October 29, 2014

9:28 am
In this article, we are going to discuss about How to use the Dependency Injection component as a standalone component without using the whole Symfony 2 framework. I will also use ClassLoader from Symfony and just for the sake of the demo I will integrate it with Zend Framework. The code requires PHP 5.3 (mostly for namespaces support).

Create a directory for your project. Inside create "lib" directory. Inside lib, create directory structure: Symfony/Component. Put ClassLoader code inside Component – the easiest thing to do is to clone if from Symfony github:

cd lib/Symfony/Component
git clone https://github.com/symfony/ClassLoader.git

The same goes for DependencyInjection component:

cd lib/Symfony/Component
git clone https://github.com/symfony/DependencyInjection.git

Finally download Zend Framework and put the contents of Zend directory into lib/Zend (so for instance Log.php file will be available in lib/Zend/Log.php).

The actual source code will go into "src" directory, which is a sibling directory of "lib".

Configuring the ClassLoader

DependencyInjection uses namespaces for managing classes, so it needs to be registered with registerNamespace method. Zend Framework follows PEAR naming convention for classes – registerPrefix will do the work for us. Finally, I will register our own code that will be stored in src directory. I will use namespaces as well. Create a new file (let's call it main.php) in the top-level directory:

require_once('lib/Symfony/Component/ClassLoader/UniversalClassLoader.php');

$loader = new Symfony\Component\ClassLoader\UniversalClassLoader();
$loader->registerNamespace('PHPCmsframework',__DIR__.'/src');
$loader->registerNamespace('Symfony',__DIR__.'/lib');
$loader->registerPrefix('Zend',__DIR__.'/lib');
$loader->register();

set_include_path(get_include_path().PATH_SEPARATOR.__DIR__.'/lib');

ClassLoader should now work just fine but we still need set_include_path so require functions inside Zend code will work correctly.

Dependency Injection container

Create a sample class that we'll use for testing. I will call it Test and put it into PHPCmsframework\Techblog, which means it should be located at src/PHPCmsframework/Techblog/Test.php:

namespace PHPCmsframework\Techblog;

class Test
{
    private $logger;

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

    public function run() {
     $this->logger->info("Running...");
    }
}

$logger should be injected using container – here is where we will use Zend_Log class. This one in turn requires a Writer, so we will create it as well. The rest of main.php will look like this:

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

$sc = new ContainerBuilder();

$sc->register('log.writer','Zend_Log_Writer_Stream')
    ->addArgument('php://output');
$sc->register('logger', 'Zend_Log')
    ->addArgument(new Reference('log.writer'));
$sc->register('test','PHPCmsframework\Techblog\Test')
    ->addArgument(new Reference('logger'));

$sc->get('test')->run();

Running the code should give an output like below:

% php main.php 
2011-06-09T15:17:22+01:00 INFO (6): Running...

0 comments:

Post a Comment