Skip to content

Instantly share code, notes, and snippets.

@wdalmut
Created July 26, 2012 16:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wdalmut/3183148 to your computer and use it in GitHub Desktop.
Save wdalmut/3183148 to your computer and use it in GitHub Desktop.
ZF2 DiC - Zend Cache Object
composer.phar
vendor
{
"minimum-stability": "dev",
"repositories": [
{
"type": "composer",
"url": "http://packages.zendframework.com/"
}
],
"require": {
"zendframework/zend-di": "2.0.*",
"zendframework/zend-cache": "2.0.*",
"zendframework/zend-servicemanager": "2.0.*",
"zendframework/zend-eventmanager": "2.0.*",
"zendframework/zend-config": "2.0.*"
}
}
{
"hash": "572a2b8fb2a55f4499722e4c1382081a",
"packages": [
{
"package": "zendframework/zend-cache",
"version": "2.0.0-rc1"
},
{
"package": "zendframework/zend-code",
"version": "2.0.0-rc1"
},
{
"package": "zendframework/zend-config",
"version": "2.0.0-rc1"
},
{
"package": "zendframework/zend-di",
"version": "2.0.0-rc1"
},
{
"package": "zendframework/zend-eventmanager",
"version": "2.0.0-rc1"
},
{
"package": "zendframework/zend-servicemanager",
"version": "2.0.0-rc1"
},
{
"package": "zendframework/zend-stdlib",
"version": "2.0.0-rc1"
}
],
"packages-dev": null,
"aliases": [
],
"minimum-stability": "dev",
"stability-flags": [
]
}
definition.class.Zend\Cache\Pattern\PatternOptions.setObject.object.type = "A"
definition.class.Zend\Cache\Pattern\PatternOptions.setObject.object.required = true
definition.class.Zend\Cache\Pattern\PatternOptions.setStorage.storage.type = "Zend\Cache\Storage\Adapter\AbstractAdapter"
definition.class.Zend\Cache\Pattern\PatternOptions.setStorage.storage.required = true
definition.class.Zend\Cache\Pattern\ObjectCache.setOptions.options.type = "Zend\Cache\Pattern\PatternOptions"
definition.class.Zend\Cache\Pattern\ObjectCache.setOptions.options.required = true
instance.alias.cache = Zend\Cache\Pattern\ObjectCache
instance.Zend\Cache\Pattern\PatternOptions.injections.setStorage.storage = 'Zend\Cache\Storage\Adapter\Memory'
instance.Zend\Cache\Pattern\PatternOptions.injections.setObject.object = 'A'
instance.cache.injections.setOptions.shared = 'Zend\Cache\Pattern\PatternOptions'
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Zend\Cache\PatternFactory;
class A {
/**
* @var B The B var
*/
private $_b;
public function __construct(\B $b) {
$this->_b = $b;
}
public function intensiveTask($param1, $param2) {
return $param1 . " " . $this->_b->intensiveB() . " " . $param2;
}
}
class B {
private $_c;
public function __construct(\C $c) {
$this->_c = $c;
}
public function intensiveB() {
return $this->_c->compute();
}
}
class C {
private $_c;
public function __construct() {
$this->_c = "Created C";
}
public function compute() {
return $this->_c;
}
}
$c = new \C();
$b = new \B($c);
$a = new \A($b);
$objectProxy = PatternFactory::factory('object',
array('object' => $a, 'storage' => 'memory'));
$computed = $objectProxy->intensiveTask("example", "complete");
echo $computed . PHP_EOL;
// USING DI [SIMPLE 1]
$di = new \Zend\Di\Di();
$c = $di->get("A");
echo $c->intensiveTask("di", "ok") . PHP_EOL;
// Create this configuration
$c = new \C();
$b = new \B($c);
$a = new \A($b);
$options = new \Zend\Cache\Pattern\PatternOptions();
$options->setObject($a);
$storage = new \Zend\Cache\Storage\Adapter\Memory();
$options->setStorage($storage);
$proxy = new \Zend\Cache\Pattern\ObjectCache();
$proxy->setOptions($options);
echo $proxy->intensiveTask("A", "B") . PHP_EOL;
// Using Di
$di = new \Zend\Di\Di();
$conf = new \Zend\Di\Config(
array(
'definition' => array(
'class' => array(
'Zend\Cache\Pattern\PatternOptions' => array(
'setObject' => array(
'object' => array(
'type' => 'A',
'required' => true
)
),
'setStorage' => array(
'storage' => array(
'type' => 'Zend\Cache\Storage\Adapter\AbstractAdapter',
'required' => true
)
)
),
'Zend\Cache\Pattern\ObjectCache' => array(
'setOptions' => array(
'options' => array(
'type' => 'Zend\Cache\Pattern\PatternOptions',
'required' => true
)
)
)
)
),
'instance' => array(
'alias' => array(
'cache' => 'Zend\Cache\Pattern\ObjectCache'
),
'Zend\Cache\Pattern\PatternOptions' => array(
'injections' => array(
'setStorage' => array("storage" => 'Zend\Cache\Storage\Adapter\Memory'),
'setObject' => array("object" => 'A')
)
),
'cache' => array(
'injections' => array(
'setOptions' => array('shared' => 'Zend\Cache\Pattern\PatternOptions')
)
)
)
)
);
$di->configure($conf);
$inj = $di->get("cache");
echo $inj->intensiveTask("Di", "OKKKK") . PHP_EOL;
// DiC using ini files
$di = new \Zend\Di\Di();
$ini = new \Zend\Config\Reader\Ini();
$di->configure(new \Zend\Di\Config($ini->fromFile(__DIR__ . '/example.ini')));
$proxy = $di->get("cache");
echo $proxy->intensiveTask("Ini", "ok") . PHP_EOL;
@wdalmut
Copy link
Author

wdalmut commented Jul 26, 2012

Install using composer

$ curl -s http://getcomposer.org/installer | php
$ php composer.phar install

@beberlei
Copy link

So DIC turns 6 perfectly fine lines into 40 lines of PHP code or 10 lines of ugly ini files?

@beberlei
Copy link

To clarify the previous rant, is there a DSL, builder or something to make this more easy to write?

@wdalmut
Copy link
Author

wdalmut commented Jul 29, 2012

Hi, I see you into big projects as Doctrine and Symfony and I'm happy to talk on DiC with you.

First of all there is my first steps with Zend\Di and I don't know if exists something that simplify the configuration and generation and it's possible that I overkilled the configuration with instance and definition sections.

I try to explain what I want to try. Tipically I see into projects, during my work time, section like this (that is an example but the concept should be clear)

<?php
class Model
{
    //...
    public function intensiveTask()
    {
        if (($data = $this->_cache->load("an-in")) === false) {
            // compute

            $this->_cache->save("id", $data);
        }
    }
}

The cache "pollute" the model source code and obviously we can move into a ModelProxy to do it better. Create by hand models proxy is quite booring and I think that ObjectCache working well and realize a proxy strategy (I can attach a list of method that it can cache).

I just working on ideas and I want to try out DiC. Can you do a similar thing (with a better example if you prefer) with Symfony DiC? With Pimple should be like this https://gist.github.com/3196566 (I've started another gist)

Bye
Walter

@beberlei
Copy link

I find the idea very good, just the how to program this is way to complicated in my opinion. DIC always adds overhead for the configuration, but i don't think it should be that much overhead. Additionally array configurations of so many levels are very hard to understand, and i suppose there is little validation going on as well. For new users its very hard to understand whats going on.

In Symfony DIC this looks like this. Its roughly 20 lines of code, but it has semantic meaning. You can read and understand it without needing to know the internals very much.

<?php
/*
$c = new \C();
$b = new \B($c);
$a = new \A($b);
$options = new \Zend\Cache\Pattern\PatternOptions();
$options->setObject($a);
$storage = new \Zend\Cache\Storage\Adapter\Memory();
$options->setStorage($storage);
$proxy = new \Zend\Cache\Pattern\ObjectCache();
$proxy->setOptions($options);
*/

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

$container = new ContainerBuilder();
$container->set('c', new Definition('C'));
$container->set('b', new Definition('B', array(new Reference('c')));
$container->set('a', new Definition('A', array(new Reference('b')));
$container->set('storage', new Definition('Zend\Cache\Storage\Adapter\Memory'));

$options = new Definition('Zend\Cache\Pattern\PatternOptions');
$options->addMethodCall('setObject', array(new Reference('a')));
$options->addMethodCall('setStorage', array(new Reference('storage')));
$container->set('options', $options);

$proxy = new Definition('Zend\Cache\Pattern\ObjectCache');
$proxy->addMethodCall('setOptions', array(new Reference('options')));
$container->set('proxy', $proxy);

$proxy = $container->get('proxy');

With XML the definition is the following. XML is very helpful for such configuration, because it can add semantic meaning and grouping. This is rather bad in INI:

<container>
    <service id="c" class="C" />
    <service id="b" class="B"><argument type="service" id="c" /></service>
    <service id="a" class="A"><argument type="service" id="b" /></service>

    <service id="storage" class="Zend\Cache\Storage\Adapter\Memory" />

    <service id="options" class="Zend\Cache\Pattern\PatternOptions">
        <call method="setObject"><argument type="service" id="a" /></call>
        <call method="setStorage"><argument type="service" id="storage" /></call>
    </service>

    <service id="proxy" class="Zend\Cache\Pattern\ObjectCache">
        <call method="setOptions"><argument type="service" id="options" /></call>
    </service>
</container>

@wdalmut
Copy link
Author

wdalmut commented Jul 29, 2012

Thanks,

I agree with you that in Symfony it has more semantic mean at first sight. I try it out with symfony components to have a complete panorama.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment