Friday, June 17, 2011

Symfony Dependency Injection - a really cool PHP tool

Hi!

Today I want to talk a little about a great design pattern called Dependency Injection and it's implementation by SensioLabs called simply Dependency Injection Component.

Now dependency injection is basically the inversion of control in you classes. It can help you to create decoupled structures that can be configured at run time which gives you a lot of flexibility. Let's take a look at an example:

Let's presume, you need to user a tool class inside some other class:

class User {


private $tool;


public function __construct(Tool $tool){
   $this->tool = $tool;
}


public function doStuff()   
   $this->tool->doSomeStuff();
}


As you can see, I've user the strategy pattern, so every time I want the USer to ->doStuff() it uses the ->doSomeStuff() method of the Tool class object.

Now this way is pretty neat, because it avoids  hard-coding the Tool into the User allowing for polymorphism. However creating a lot of such dependencies can be a pain if you have some more complicated stuff to do. Additionally there can be some problems with instantiating the Tool class before usage.

Symfony dependency injection can solve both those problems as it decouples elements and creates them upon usage, not upon configuration and helps to easily create complicated dependencies just before usage. Let's look a the example ripped out of my ZF project:


//retrieving mailer options from configuration

$mailerOptions = $this->getOption('mailer');


//we create a builder object, that will later build our classes
$serviceContainerBuilder = new sfServiceContainerBuilder();


//regitering the mailer service
//this means, that when we call the mailer service
//the Zend_Mail class has to be instantiated with parameters
//and a function called with some additional params


$serviceContainerBuilder->register('mailer', 'Zend_Mail')
->addMethodCall('setDefaultFrom', array($mailerOptions['from'], $mailerOptions['from_name']))
->addMethodCall('setDefaultReplyTo', array($mailerOptions['replyto'], $mailerOptions['replyto_name']))
->addMethodCall('setDefaultTransport', array('%mailer.transport%'));


//everything should be pretty straight forward
//I'm creating a builder instance and configuring it
//with the object class I wan't to have created
//and it's parameters
//the setDefaultTransport param is still open, when you add
//params like %param% sfDI knows that you want to set the param
//before service class instantiation


//setting to Zend_Registry to get the serviceContainer whenever I want
Zend_Registry::set('serviceContainer', $serviceContainerBuilder);



Some of you, who have some experience with dealing with Zend_Mail, know that you need to have a mailer transport of type Zend_Mail_Transport_Abstract.

In my application I have two bootstrapping (preparing basically) files:
1) the main application bootstrap file (from which it was I took the above example)
2) the PHPUnit bootstrap

The testing reasons I want to have a different transport in the second bootstrap that in the reall one. The first mailer should normally send the email but the second one should just log it in a file. Here the dependency injection copes in really handy:

1) Main bootstrap:



$serviceContainerBuilder = Zend_Registry::get('serviceContainer');
$mailerOptions = $this->getOption('mailer');


//I want the main transport to be a posrmarkapp.com using transport
$serviceContainerBuilder->register('mail.transport', 'FT_Mail_Transport_Postmark')
->addArgument($mailerOptions['transport']['api_key'])
->setShared(false);


//the setShared(false) simply tells the container that the mail.transport object isn't unique


//here is the interesting part
//I tell the Container to inject the newly configured container, as the 
//"mailer.transport" argument to the mail.transport container


$serviceContainerBuilder->setParameter('mailer.transport', new sfServiceReference('mail.transport'));



2) The second bootstrap (PHPUnit):



$serviceContainerBuilder = Zend_Registry::get('serviceContainer');
$serviceContainerBuilder->register('mail.transport', 'Zend_Mail_Transport_File')
->addArgument(array('path' => APPLICATION_PATH . '/..tests/log'))
->setShared(false);



This example shows just how you can create another transport for another purpose, just as easily.
Now we want to see it all in action:


//in some form processing command, we retrieve the container and create the service

$mailerService = \Zend_Registry::get('serviceContainer')->getService('mailer');


$tpl = //obviously we need some template


$mailerService->setBodyHtml($tpl->render());
$mailerService->addTo($emailTo);
$mailerService->send();



It's that simple, we can additionally set some parameters before getting the service, adding different behavior to the container.
Some of you might say that you can preconfigure the Zend_Mail class instance and set if directly into the registry. True, but remember that not all pages result in the usage of the mailer, so you would probably waste a lot of resources holding a lot if instantiated objects in the registry.

Hope you enjoyed the examples and start building your complicated class relations with the Symfony Dependency Injection Component. For more information go to http://components.symfony-project.org/dependency-injection/

cheers,
Peter

Thursday, May 19, 2011

SilverStripe CMS for PHP programmers, not for dummies

Hi there!

Recently I've came across a pretty standard problem:

1. I had a simple php website with little php really, some routing, contact form handling, teamplating, nothing fancy
2. I hate doing boring stuff like CRUD's and CMS's
3. I make a lot of changes to the website
4. The website comes in 2 languages

If you think "just user some cms" - well I had the same idea. I started from the best known to me - Wordpress. It's pretty robust, but not being written as a CMS, but as a blog, it didn't really fit in. Of course I could force WP to do what I wish, but anyone who developed something in WP knows it's not really for programmers (or by programmers IMO).

The second choice was on pretty standard CMS's like Joomla or  Drupal, still programming was really problematic, extending stuff hard, since I wanted pretty much nothing form Drupal, and had to leave all that was on the old page.

Finally a friend of mine introduced SilverStripe, a New Zeland made CMS/Framework.
I'm a sceptic by nature but this I loved at first sight.



1. You program first what you want (pretty much no prerequisites), and let the framework build the rest. It's really for programmers, you can't just click away compromising modularity or re-usability. Everything is a class, that you can create and use over and over.

2. Every one of my custom objects (like for example ProjectRealisations) are encapsulated in a single class, that was pretty easy to set up and extend.

3. Multilingual setup for the CMS (options to get any additional language) - 5 minutes.

So what I've done is set up a completely custom website with a CMS for multilingual content (with ACL cf course) in a few days, while learning the CMS/Framework (ssbits.com - a big help).

I strongly recommend the framework for small websites, for lazy programmers (like myself;) )

See you next time,
Peter

Wednesday, March 9, 2011

Flash sites beware - UseItBetter is finally out!

Hi Everyone,

just a quick note that the (super) cool tool for flash sites usability testing, recording and playing visits, making sophisticated site analysis is out!

Almost two years of hard work and the collective work of great minds made it all possible.

Check out more at www.UseItBetter.com

Thanks,
Peter

Friday, March 4, 2011

Importance of versioning software

Why is versioning important? What's the difference of naming 1.0 or 0.1 or whatever. In my experience product versioning is a crucial aspect not only providing law and order but also invoking the paradigm of modern programming techniques. You can compare a good versioning strategy to the Code of Law of a community, however big or small. A good CoL will make your community prosper and evolve even when bad stuff happens (it allways does), however a bad CoL will make your community vulnerable to internal problems, it's productivity and prosperity will suffer in each mishalf.
In IT product development versioning calls to a certain paradigm that is often underestimated by programmers on even team leaders (seen it) - the power of predictability.
Remember, there is always someone waiting for your code. Associating versions with time (like in SCRUM sprints) gives the programmer and the client a common way to express the readiness of a particular piece of logic and not that a simple date wouldn't be enough, but there is a bit more to it.
There are some basic versioning perks that you might want to take advantage of.  For instance combining a time period with a version eg.: each 0.1 is a 3 week sprint gives us has:

PROS:


  • gives a common time factor variable associated with development (from the clients pov) - so everyone knows when something is/should be/should have been ready
  • when there are more smaller tasks in a given sprint, you are free to prioritize them as you find fit for the best result - no one tells you if something should be 
  • you always know how much time there is left for doing something - given that you know how long it is going to take
  • you can easily plan ahead, knowing how much time you need for a particular task, just look at your project road map
  • less deployment cycles give less space for error while updating production files/data
  • less deployment cycles also creates a natural catching net for bugs - most probable that detected bugs are from the last sprint


CONS:


  • the main problems are with getting clients to acknowledge some simple truths like "NOT EVERYTHING HAS TO BE DONE ON YESTERDAY"
  • there is a real risk of thinking that we are lazy or just thinking of some "stupid academic stuff or suitable for real business" - just have to be as eloquent as possible, explaining that its the best (cheapest) solution possible and will save money (that's the keyword here)
  • big risk of hot fixing - everything is starting to be a high priority hot fix for the client
  • in some development cycles, where the clients are responsible for quality, you will need to take them into account in the versioning strategy


With the right set of people and a little time, versioning is a great tool for making development and maintenance of software much easier and more reliable.

more on this : wiki page

Hope it's been another inspiring piece of text for all humanity ;)
See you next time.

Monday, February 7, 2011

Why self-made frameworks are too expensive?

As I progress in my PHP programming endeavours I tend to argue a lot about the same topics with different developers. Sometimes there is some reason in madness I hear, but very often there is much overheard information that somehow doesn't make any sense and causes real confusion with some people. As in my opinion many web developers/programmers are very narcissistic, and even if they wont admit it, they think their code is the best for whatever reason, and no Open Source PHP Framework (they're all only open source since it's php, but I like to call it like it is) can match them in the understanding on the domain they are working on and the project will surely die without a custom made framework.
This confusion can sometimes lead to very high development and maintenance cost and I'll try to clear the situation a little bit, so You don't have to make the same mistakes.



The problem:

We have to build an Internet service of some kind, something we haven't exactly been much familiar with because it can be described as innovative.



The typical "solutions" (stuff I hear very often)

1) "Frameworks like Zend Framework or Symfony are slow and heavy, we will need a lot more hardware"
2) We need a lot more features than Open Source frameworks can provide
3) Frameworks are just another dude's point of view and implement things strangely



The crushing(for some) reality:

Let us mark out all the fields that we need to compare home-made-gizmo frameworks with PHP OSF (Open Source Frameworks):

  • learning curve
  • reliability
  • maintainability
  • extendability
  • performance
  • development time
  • overall system cost



So lets maybe start with learning curve.

Unless You made a real effort to document everything in detail, add examples, tutorials and so on, event if you make some presentations and in-house training courses... you can't come even close to the POWER OF COMMUNITY.
Open Source PHP frameworks like ZF (my favorite as You might have noticed) have a great community, testing, learning and developing a lot of code with You and for You. You can hire professionals (like I ;-) ) that already know a lot about a system that you are about to design, build or maintain and spare a lot of head aches on paying someone for a month or two just to get around your system.

That's a clear 1-0 for PHP OSF !



Next we have a reliability comparison

So in my opinion there is only one answer here but let's just see what will be.
IMHO self made framework have a overall lower quality of code, thus offering much lower reliability for three simple reasons.

One - the developers working on in house development (and php programmers anyway) often don't know more (that a sad truth to realize) than two design patterns. the first is Singleton, the second is MVC or a mutant, unusable form of it anyway. I don't have any idea why developers confuse MVC's Model with the data layer, and not the business logic layer but what the hell, let's just go with it. the design becomes unclear, the classes all become dependant on each other and there is no way in hell that someone is writing decent unit tests for that monster.

The second reason is that most of the time there is no time to THINK BEFORE YOU CODE and the obvious pressure is on functionality not on the back end. Many people think that they can just code away and if the service is a bulls eye in the market, they.ll just change the framework "with all the money we will get" :) but in reality this seldom happens. they end up with much higher development costs.

The third reason is again COMMUNITY. It is very simple really. While one developer can write one thing, a hundred developers write a hundred things, find a hundred bugs, and since it's Open Source, entirely free. Unit testing everything just to get their piece of code accepted in a frameworks source makes people very proud and you don't have to pay a cent for the reliability these frameworks offer.

So that's 2-0 for PHP OSF ! Great!



Now let's take a look at maintainability and extendability

How are your projects being maintained ? Another "if" maybe? Well let's just say, you're one hell of a programmer and you create object oriented code that uses design patterns in a reasonable manner and is really great to maintain. You have a great FW that is easy to maintain, but almost certainly just for you, with no real documentation no one will even look at it (unless you have some fanatic followers of course ;) ) and it takes a lot of effort to upgrade some part of the application. OSF's again have the power of COMMUNITY that creates updates, bug fixes, and the code is just from start designed to please the most of users, not just one.

Extendability is tightly coupled (ironic isn't it?:) ) with maintainability, so I wont;t get in to deep. The punchline here is, if you create code that can easily change from eg. JSON output to Array output, without changing any conditional statements you almost certainly create code that can be extended to output XML or something else.

A clear 3-0 for OSF...



Now comes the fun part, performance.

Many developers believe that they truly do good for the project by repeating some overheard information with no real scientific background. NO! If you want to be sure, that you create faster code -> test it. Nothing is just faster or just slower.

In my time I've created a version of Zend_Acl that was made entirely with arrays. Since the code almost entirely run in some simple foreaches, it was 10-20x faster than the original. If you take into account only the speed of working, not the speed of development - you are sure to create code that is used only one and rewritten every time. Speed is not a scalar value, its a function of functionality, so most probably, making really good OOP into procedural programming, will make it works faster, and less memory bound, but also will make you work longer to get to the same place.

In my opinion, OOP is not always the best approach, for high traffic websites, most often used load balancer is something like $readServer = $readServerSet[ rand(1,10) ]; It gets the Job done.

Custom made frameworks are in most cases faster that the OOP approach of for instance ZF. It's a question of power really, the simpler the framework, the faster it runs. OSF's are made for many people, not just for your project, so the creators had to compromise function and form.

I will give one for custom frameworks here, but it's not really a win, as I'll try to explain later. So 3-1...

The real kicker and the whole idea of OSF's is to decrease development time because that's what it's all about. the purpose of most applications is to get the creator money :) I know it's pretty harsh but it's the simple truth. So what does it give us, that we have a team skilled in one framework, like ZF, with a lot of extensions developed, with no time spent creating, testing, maintaining their own custom FW?


More Money!


That's what its all about, the time spent developing is one half or even less that in custom frameworks (not enterprise level frameworks of course) and that results in a lot more projects being created, and more money earned.

Needless to say +2 for OSF's ! That's 5-1 !!!



The conclusion:

So for all you rich bastards, that can afford developing shitty frameworks, by unskilled developers who still think, they can do better than Zend, Symfony, Doctrine or whatever...

... think with your wallet :)

best,
Peter