Search code examples
phpzend-framework2zend-framework-modules

Zend Framework 2 - Cache-conform service factories


The zend file application.config.php offers some way to cache the config, which I find very nice for a production system:

return array(
        'modules' => array(
                'Application',
        ),
        'module_listener_options' => array(
                'module_paths' => array(
                        './module',
                        './vendor'
                ),
                'config_glob_paths' => array('config/autoload/{,*.}{global,local}.php'),
                'config_cache_enabled' => true,
                'config_cache_key' => md5('config'),
                'module_map_cache_enabled' => true,
                'module_map_cache_key' => md5('module_map'),
                'cache_dir' => './data/cache',
        ),
);

However, activating that leads immediately to errors like

Fatal error: Call to undefined method Closure::__set_state()

This has to do with factories written as closures, like these:

'service_manager' => array(
    'factories' => array(
        'auth.service' => function($sm) {
            /* hic sunt ponies */
        },
    ),
),

Unfortunately, the issues only tell me why this error happens, but not how to resolve it.

How can I rework this and similar factories so the cache will work with them?


Solution

  • Rework your factory closures to factory classes.

    Config

    'service_manager' => array(
        'factories' => array(
            'auth.service' => \Fully\Qualified\NS\AuthFactory::class,
        ),
    ),
    

    Factory

    namespace Fully\Qualified\NS;
    
    use Zend\ServiceManager\FactoryInterface;
    use Zend\ServiceManager\ServiceLocatorInterface;
    
    class AuthFactory implements FactoryInterface
    {
        public function createService(ServiceLocatorInterface $serviceLocator) {
            // create your object and set dependencies
            return $object
        }
    }
    

    Besides this approach making caching possible, another advantage is that PHP will parse your config faster since it doesn't have to create a Closure class on each request for each anonymous function.