0

I designed my database and cache layer after Zend Framework 1, like this:

class Cache
{
    public static function create($adapter, array $params)
    {
        $class_name = 'Cache_Adapter_' . $adapter;

        return new $class_name($params);   
    }
}

abstract class Cache_Adapter
{
    public function __construct(array $params)
    {

    }
}

class Cache_Adapter_File extends Cache_Adapter
{
    // ...
}

Usage example:

// config.php
return array(
    'cache' => array(
        'adapter' => 'file',
        'params' => array(
            'path' => '/path',
        ),
    ),
);

// bootstrap.php
$dic->cache = Cache::create($config['cache']['adapter'], $config['cache']['params']);

This approach is great, because each cache adapter can have different parameters, for example, file cache need path to directory where to store cache files.

Then I wanted to create cache adapter for storing data in database and realized that instead of scalar parameter array, database abstraction class dependency is needed.

Currently database connections are registered in dependency injection container:

// config.php
return array(
    'db1' => array(
        'adapter' => 'mysql',
        'params' => array(
            'user' => 'root',
            'connect_timeout' => 5,
        ),
    ),
    'db2' => array(
        'adapter' => 'sqlsrv',
        'params' => array(
            'db' => 'foo',
        ),
    ),
);

// bootstrap.php
$dic->db1 = Site:Db::create($config['db1']['adapter'], $config['db1']['params']);
$dic->db2 = Site:Db::create($config['db2']['adapter'], $config['db2']['params']);

So I wanted to ask how in addition to scalar configuration parameter array, zero or more specific dependencies can be passed to cache adapters and this can be done in config.php.

class Cache_Adapter_Db extends Cache_Adapter
{
    // Instead of abstract Cache_Adapter::__construct(array $params)
    // something like this is needed:
    // public function __construct(array $params, Db_Adapter $db)
    public function __construct(array $params)
    {

    }
}
Hemaulo
  • 979
  • 2
  • 9
  • 16

1 Answers1

0

There are 2 steps involved: first your cache adapter should call its parent class in the correct way:

class Cache_Adapter_Db extends Cache_Adapter
{
    public function __construct(array $params, Db_Adapter $db)
    {
       parent::__construct($params);
    }
}

Second: your factory class Cache should accept more parameters:

class Cache
{
    public static function create($adapter, array $params, $optparams = null )
    {
        $class_name = 'Cache_Adapter_' . $adapter;

        return new $class_name($params, $optparams);   
    }
}

The config php would look like this:

// config.php
return array(
    'db1' => array(
        'adapter' => 'mysql',
        'params' => array(
            'user' => 'root',
            'connect_timeout' => 5,
        ),
    ),
    'db2' => array(
        'adapter' => 'sqlsrv',
        'params' => array(
            'db' => 'foo',
        ),
        'options' => 'extraoption'
    ),
);

and in bootstrap.php:

$dic->db2 = Site:Db::create(
   $config['db2']['adapter'], 
   $config['db2']['params'],
   $config['db2']['options']
);
JvdBerg
  • 21,777
  • 8
  • 38
  • 55
  • Okay, but how configuration array will look like in this case? – Hemaulo Sep 28 '12 at 12:15
  • Do you mean for DB based cache adapter: 'options' => new Db_Adapter_Mysql(...)? This is not correct. I need somehow specify in configuration which dependency to use, like 'options' => 'db1', but this is also not so good because single dependency is hardcoded. What if some adapter needs more than one? – Hemaulo Sep 28 '12 at 12:38