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...
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