Last week, I blogged about looking for a new application framework to use and more importantly the key things that I would want in one. After reading about the Zend framework, Symfony and Laravel and finding myself hesitant to use any one, I thought to myself why not get the best of each framework? So that’s what I did.
I retained Zend for its MVC. I like Symfony for its DependencyInjection component and integration with Doctrine and thought to myself why not just integrate them in? Finally, although I loved Laravel for its File API and Rest Controller, I settled to look for existing solutions within the Zend Framework. This is especially true with the Rest Controller. Turns out with a little tweaking you could actually have a Rest Controller in Zend version < 2. Also to my surprise, Zend comes with a File Api as well that doesn’t use static methods and is fully Object Oriented.
Loading them all together: Zend_Loader_Autoloader
Autoloading was the foremost issue on my mind when I thought about doing this especially because Symfony and Doctrine use PHP namespaces already and ZF 1.11 doesn’t as of yet. Turns out, this is easily handled already by Zend_Loader_Autoloader:
|
1 2 3 |
$autoloader = Zend_Loader_Autoloader::getInstance(); $autoloader->registerNamespace('Symfony'); $autoloader->registerNamespace('Doctrine'); |
The key is to just register the namespace with the Autoloader and just as important: to make sure the libraries are in the include path and the directory structure follows PSR-0.
Getting hold of the D.I container
With that issue out of the way, the next thing concern that came to my mind was grabbing hold of the D.I container in my controllers so I can get my services. This can be done through Zend_Application’s Bootstrap like so:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Config\FileLocator; class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { public function _initContainer() { $container = new ContainerBuilder(); $loader = new XmlFileLoader( $container, new FileLocator(__DIR__) ); $loader->load('services.xml'); return $container; } } |
Then, in the action controllers, getting the container and a service was as easy as:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
class IndexController extends Zend_Controller_Action { private $em; public function init() { // get the symfony service container $container = $this->getInvokeArg('bootstrap')->getResource('container'); // get the Doctrine 2 entity manager as defined in application/services.xml $this->em = $container->get('entityManager'); } } |
Future work
I know. The current method of retrieving the container leaves much to be desired. Hopefully when the stable release of the Zend Framework 2 comes out, this can be easily resolved by creating the D.I container as a Zend framework a plugin.
Having said that, I will also work on porting this setup to ZF2 very soon.
Okay enough talk now, head on on over to Github to check it out.