Zend Framework 2 : using ‘caches’ configuration to setting up cache services
Zend Framework 2.2 has Zend\Cache\Service\StorageCacheAbstractServiceFactory that allow us to configure cache services via array configuration. We just need to register the abstract factory and create a config array that represent cache options. I will give you an example if we want to create memcached service.
- register to service manager
//config/autoload/global.php 'service_manager' => array( 'abstract_factories' => array( 'Zend\Cache\Service\StorageCacheAbstractServiceFactory', ) ),
- configure array cache options, for example, I write at config/autoload/cache.local.php
//config/autoload/cache.local.php <?php return array( 'caches' => array( 'memcached' => array( //can be called directly via SM in the name of 'memcached' 'adapter' => array( 'name' =>'memcached', 'options' => array( 'ttl' => 7200, 'servers' => array( array( '127.0.0.1',11211 ) ), 'namespace' => 'MYMEMCACHEDNAMESPACE', 'liboptions' => array ( 'COMPRESSION' => true, 'binary_protocol' => true, 'no_block' => true, 'connect_timeout' => 100 ) ) ), 'plugins' => array( 'exception_handler' => array( 'throw_exceptions' => false ), ), ), ), );
Done, and we can call
$this->getServiceLocator()->get('memcached');
from service that implements ServiceLocatorAwareInterface ( controllers or other service(s)).
Want to check ? Check this at your controller :
//filling cache value public function indexAction() { $this->getServiceLocator()->get('memcached')->setItem('foo', 'bar'); } //retrieve cache value public function retrieveAction() { echo $this->getServiceLocator()->get('memcached')->getItem('foo'); }
If you want to set multi-cache config, just configure, and call them :).
Hi
thanks you very match .
I want to use caches to optimize Zend/Mvc/Application::init because it take > 0,5 s
is it possible ?
i am using skeleton app.
thankx.
i have no idea, sorry
but maybe you can cache your configs : https://samsonasik.wordpress.com/2013/03/13/zend-framework-2-cache-module-config-module-classmap-caching/
thanks
i tested it and it gives better response time ~ 0.6 s.
is it (time) normal ? is there another way to get it better?
thank you very match.
i think normal or not it depend on your server spec, traffic, and configuration
I using xampp 1.8.1 as server.
I am the only one who send request.
and i am using
zfc-user module with bjy-authorize
+ MyModule
that strange, maybe you load huge resource/data. I have no idea for it.
thank you.
I’ll check it.
Having the same behavior without any big data sets as well on really simple pages without any db connects. I’m going to debug what is causing this.
Strangest thing until now: languages with po files, cache on file system is slower as no caching, cache on memcache is slower as file system and without cache. Tested in a productive environment on two servers, 250 measurements each, with two content locations. Any ideas?
The test case (default language) to verification the test had in all 3 versions, like expected the same result/timing.
i’ve just found out about this case.. anyone who feels the same thing.. please check your memcached in you phpinfo() and make sure it does exist.. i felt this after installing memcached i only restart nginx but you need to restart php5-fpm too for php.ini changes.
I’m sorry, but what is “11211” next to ip address? Thanks.
port. read phpmanual!
Hi zack,
hello, this is the port (TCP/UDP) where memcache listens.
br,
Pedro J.
Hello Samsonasik,
good information for Memcache, but if I use just as you describe I get the following error message:
this call: $this->getServiceLocator()->get(‘memcached’);
Additional information:
Zend\ServiceManager\Exception\ServiceNotFoundException
File:
/var/www/app.com/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php:495
Message:
Zend\ServiceManager\ServiceManager::get was unable to fetch or create an instance for memcached
So the error message but I have understood what I forgot?
sorry for English
Pedro J.
what zf version you’re using ? if it using ZF 2.2 , it should be worked.
Please enable the memcached service in your system, then check might it helps you.
Hi,
my version is “zendframework/zendframework”: “2.2.*”
br
Pedro J.
it must be your config not accessible, or you forgot register the abstract_factories.
Hi samsonasik,
the abstract class I have registered as they have written in tutorial.
br,
Pedro
what actually your config/autolad/global.php configure ?
Hi,
tis my config: config/autolad/global.php
return array(
‘db’ => array(
‘driver’ => ‘Pdo_Mysql’, //’Pdo’,
‘username’ => ‘cronJobs’,
‘password’ => ‘XSDSvQR4x0LFQMfpFh-%3’,
‘dsn’ => ‘mysql:dbname=global_cms;host=localhost’,
‘driver_options’ => array(
PDO::MYSQL_ATTR_INIT_COMMAND => ‘SET NAMES \’UTF8\”
),
),
‘service_manager’ => array(
‘abstract_factories’ => array(
‘Zend\Cache\Service\StorageCacheAbstractServiceFactory’,
),
‘factories’ => array(
‘Zend\Db\Adapter\Adapter’ => ‘Zend\Db\Adapter\AdapterServiceFactory’,
‘Zend\Cache\Storage\Filesystem’ => function($sm){
$cache = Zend\Cache\StorageFactory::factory(array(
‘adapter’ => ‘filesystem’,
‘plugins’ => array(
‘exception_handler’ => array(‘throw_exceptions’ => false),
‘serializer’
)
));
$cache->setOptions(array(
‘cache_dir’ => ‘./data/cache’
));
return $cache;
},
),
),
‘doctrine’ => array(
‘connection’ => array(
‘orm_default’ => array(
‘driverClass’ => ‘Doctrine\DBAL\Driver\PDOMySql\Driver’,
‘params’ => array(
‘host’ => ‘localhost’,
‘port’ => ‘3306’,
‘user’ => ‘cronJobs’,
‘password’ => ‘XSDSvQR4x0LFQMfpFh-%3’,
‘dbname’ => ‘global_cms’,
)
)
)
),
);
check if there is a file named Zend\Cache\Service\StorageCacheAbstractServiceFactory.php at your zf2 library.
Hi,
yes, I have.
that’s strange. please do :
and find if ‘memcached’ is under ‘caches’ array.
Hi,
Yes I have, but why is not loaded? do you have any idea what is problem?
[“caches”] => array(1) {
[“memcached”] => array(2) {
[“adapter”] => array(3) {
[“name”] => string(9) “memcached”
[“lifetime”] => int(7200)
[“options”] => array(3) {
[“servers”] => array(1) {
[0] => array(2) {
[0] => string(9) “127.0.0.1”
[1] => int(11211)
}
}
[“namespace”] => string(20) “MYMEMCACHEDNAMESPACE”
[“liboptions”] => array(4) {
[“COMPRESSION”] => bool(true)
[“binary_protocol”] => bool(true)
[“no_block”] => bool(true)
[“connect_timeout”] => int(100)
}
}
}
[“plugins”] => array(1) {
[“exception_handler”] => array(1) {
[“throw_exceptions”] => bool(false)
}
}
}
}
memcached is installed and running with php exted.
BR,
Pedro
I have no idea. Sorry. Maybe you need to create your own abstract_factories 🙂
Ok thank you for your help.
greetings from germany.
BR
Pedro
Call to undefined method Closure::__set_state() in C:\wamp\www\SMBERP\data\cache\modulecache\module-config-cache.2245023265ae4cf87d02c8b6ba991139.php on line 1196
[…] https://samsonasik.wordpress.com/2013/10/06/zend-framework-2-using-caches-configuration-to-setting-up… […]
Im really struggling to get ZF2 running with memcache. My testscripts run without any problems and can write/read btw access to the memcache.
I followed the instructions until this point:
———————————————-
$this->getServiceLocator()->get(‘memcached’);
Memcached version:
———————————————-
Memcache Server version: 1.4.13
Getting the exception:
———————————————-
Message:
Unknown libmemcached option ‘COMPRESSION’ (Memcached::OPT_COMPRESSION)
Stack trace:
#0 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Cache/Storage/Adapter/MemcachedResourceManager.php(311): Zend\Cache\Storage\Adapter\MemcachedResourceManager->normalizeLibOptionKey(‘COMPRESSION’)
#1 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Cache/Storage/Adapter/MemcachedResourceManager.php(211): Zend\Cache\Storage\Adapter\MemcachedResourceManager->normalizeLibOptions(Array)
#2 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Cache/Storage/Adapter/MemcachedOptions.php(265): Zend\Cache\Storage\Adapter\MemcachedResourceManager->setLibOptions(‘default’, Array)
#3 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Stdlib/AbstractOptions.php(104): Zend\Cache\Storage\Adapter\MemcachedOptions->setLibOptions(Array)
#4 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Stdlib/AbstractOptions.php(57): Zend\Stdlib\AbstractOptions->__set(‘liboptions’, Array)
#5 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Stdlib/AbstractOptions.php(32): Zend\Stdlib\AbstractOptions->setFromArray(Array)
#6 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Cache/Storage/Adapter/Memcached.php(128): Zend\Stdlib\AbstractOptions->__construct(Array)
#7 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Cache/StorageFactory.php(137): Zend\Cache\Storage\Adapter\Memcached->setOptions(Array)
#8 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Cache/StorageFactory.php(70): Zend\Cache\StorageFactory::adapterFactory(‘memcached’, Array)
#9 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Cache/Service/StorageCacheAbstractServiceFactory.php(59): Zend\Cache\StorageFactory::factory(Array)
#10 [internal function]: Zend\Cache\Service\StorageCacheAbstractServiceFactory->createServiceWithName(Object(Zend\ServiceManager\ServiceManager), ‘memcached’, ‘memcached’)
#11 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php(905): call_user_func(Array, Object(Zend\ServiceManager\ServiceManager), ‘memcached’, ‘memcached’)
#12 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php(1076): Zend\ServiceManager\ServiceManager->createServiceViaCallback(Array, ‘memcached’, ‘memcached’)
#13 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php(617): Zend\ServiceManager\ServiceManager->createFromAbstractFactory(‘memcached’, ‘memcached’)
#14 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php(569): Zend\ServiceManager\ServiceManager->doCreate(‘memcached’, ‘memcached’)
#15 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php(503): Zend\ServiceManager\ServiceManager->create(Array)
#16 /var/[__somefolder__]/module/Application/src/Application/Controller/ContactController.php(22): Zend\ServiceManager\ServiceManager->get(‘memcached’)
#17 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractActionController.php(83): Application\Controller\ContactController->indexAction()
#18 [internal function]: Zend\Mvc\Controller\AbstractActionController->onDispatch(Object(Zend\Mvc\MvcEvent))
#19 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#20 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners(‘dispatch’, Object(Zend\Mvc\MvcEvent), Object(Closure))
#21 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/AbstractController.php(117): Zend\EventManager\EventManager->trigger(‘dispatch’, Object(Zend\Mvc\MvcEvent), Object(Closure))
#22 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Mvc/DispatchListener.php(114): Zend\Mvc\Controller\AbstractController->dispatch(Object(Zend\Http\PhpEnvironment\Request), Object(Zend\Http\PhpEnvironment\Response))
#23 [internal function]: Zend\Mvc\DispatchListener->onDispatch(Object(Zend\Mvc\MvcEvent))
#24 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(468): call_user_func(Array, Object(Zend\Mvc\MvcEvent))
#25 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/EventManager/EventManager.php(207): Zend\EventManager\EventManager->triggerListeners(‘dispatch’, Object(Zend\Mvc\MvcEvent), Object(Closure))
#26 /var/[__somefolder__]/vendor/zendframework/zendframework/library/Zend/Mvc/Application.php(309): Zend\EventManager\EventManager->trigger(‘dispatch’, Object(Zend\Mvc\MvcEvent), Object(Closure))
#27 /var/[__somefolder__]/public/index.php(14): Zend\Mvc\Application->run()
For all having trouble – there are 2 different php librarys called “memcache” and “memcached” doing nearly the same job. Seems to be a bit unlucky in the naming… If you having trouble check with phpinfo() if “memcached” is installed otherwise apt-get install php5-memcached
Fatal error: Uncaught exception ‘Zend\View\Exception\RuntimeException’ with message ‘Zend\View\Renderer\PhpRenderer::render: Unable to render template “error”; resolver could not resolve to a file’ in D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\View\Renderer\PhpRenderer.php:498 Stack trace: #0 D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\View\View.php(205): Zend\View\Renderer\PhpRenderer->render(Object(Zend\View\Model\ViewModel)) #1 D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\View\View.php(233): Zend\View\View->render(Object(Zend\View\Model\ViewModel)) #2 D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\View\View.php(198): Zend\View\View->renderChildren(Object(Zend\View\Model\ViewModel)) #3 D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\Mvc\View\Http\DefaultRenderingStrategy.php(102): Zend\View\View->render(Object(Zend\View\Model\ViewModel)) #4 [internal function]: Zend\Mvc\View\Http\DefaultRenderingStrategy->render(Object(Zend\Mvc\ in D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\View\Renderer\PhpRenderer.php on line 498
can you help me?…
phprenderer.php -> line 495 -> 503
while ($this->__template = array_pop($this->__templates)) {
$this->__file = $this->resolver($this->__template);
if (!$this->__file) { // errorr here 😥
throw new Exception\RuntimeException(sprintf(
‘%s: Unable to render template “%s”; resolver could not resolve to a file’,
__METHOD__,
$this->__template
));
}
controller only script
public function indexAction() {
$this->getServiceLocator()->get(‘memcached’)->setItem(‘foo’, ‘bar’);
}
-> error 😥
do you send reply to skype: reach_phan ?
or reply it’s here…
Thanks you!
you need to work with ZendSkeletonApplication, you can start learn from the docs : http://framework.zend.com/manual/2.3/en/user-guide/overview.html
my application did worked, i want use memcache to speeding application when query database, but it didn’t worked with “$ this-> getServiceLocator () -> get (‘memcached’) -> SetItem (‘foo’, ‘bar’); “
based on your error, you don’t have “error” template, that’s not related with its cache part, that related with your skeleton, please do effor to find solution by looking the error.
I’ve tried this way but still get an error as above …
link: http://www.php.net/manual/en/memcached.construct.php
and I have absolutely no idea how to solve it …
if possible, please help me solve it …
I ask for your email address, I will send the project for you, please help me!!!
tudientable code:
$GLOBALS[‘memcached-sets’] = array (
‘_’ => array (
array(‘localhost’, 11211)
)
);
define(‘DEFAULT_MEMCACHED_SET’, ‘_’);
class TudienTable{
protected $tableGateway;
public function __construct(TableGateway $tableGateway){
$this->tableGateway = $tableGateway;
}
function mcache( $persistent_id=DEFAULT_MEMCACHED_SET ) {
// one instantiation per-connection per-request
static $memcached_instances = array();
if( array_key_exists($persistent_id, $memcached_instances)) {
$instance = $memcached_instances[$persistent_id];
}else{
$instance = new Memcached($persistent_id);
$instance->setOption(Memcached::OPT_PREFIX_KEY, $persistent_id);
$instance->setOption(Memcached::OPT_LIBKETAMA_COMPATIBLE, true); // advisable option
// Add servers if no connections listed. Get server set by $persistent_id or use default set.
// In a production environment with multiple server sets you may wish to prevent typos from silently adding data
// to the default pool, in which case return an error on no match instead of defaulting
if( !count($instance->getServerList()) ) {
$servers = array_key_exists($persistent_id, $GLOBALS[‘memcached-sets’])
? $GLOBALS[‘memcached-sets’][$persistent_id]
: $GLOBALS[‘memcached-sets’][DEFAULT_MEMCACHED_SET];
$instance->addServers($servers);
}
$memcached_instances[$persistent_id] = $instance;
}
return $instance;
}
public function fetchAll($paginated = false,$search,$mac_add,$arr)
{
if ($paginated) {
if(!$this->mcache()->getItem(‘key’)){
$select = $this->get($search,$mac_add,$arr);
$paginatorAdapter = new DbSelect(
$select,
$this->tableGateway->getAdapter(),
$this->tableGateway->getResultSetPrototype()
);
$this->mcache()->setItem(‘key’, $paginatorAdapter);
}
$paginatorAdapter = $this->mcache()->getItem(‘key’);
$paginator = new Paginator($paginatorAdapter);
return $paginator;
}
return $this->tableGateway->select();
}
…..
}
indexcontroller code:
class IndexController extends AbstractActionController
{
public function indexAction() {
$page=1;
$count=25;
$search=”;
return $this->getTuVung($page,$count,$search);
}
public function getTuVung($page,$count,$search){
$mac_add = $this->getMacAddressAction();
$arr = $this->getServiceLocator()->get(‘Kiemtra\Model\UserTable’)->getIDWithMacAddress($mac_add);
//$list=”;
$i = 0;
foreach ($arr as $v){
foreach ($v as $k){
if($k>0){
$list[$i]=$k;
$i++;
}
}
}
$paginator = $this->getServiceLocator()->get(‘Kiemtra\Model\TudienTable’)->fetchAll(true,$search,$mac_add, $list);
$total = $paginator->getTotalItemCount();
$paginator->setCurrentPageNumber((int) $this->params()->fromQuery(‘page’, $page));
$paginator->setItemCountPerPage($count);
return new ViewModel(array(‘test’ => $paginator));
}
}
index.phtml code:
<?php
echo '
‘;
?>
–>
Fatal error: Uncaught exception ‘Zend\View\Exception\RuntimeException’ with message ‘Zend\View\Renderer\PhpRenderer::render: Unable to render template “error”; resolver could not resolve to a file’ in D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\View\Renderer\PhpRenderer.php:498 Stack trace: #0 D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\View\View.php(205): Zend\View\Renderer\PhpRenderer->render(Object(Zend\View\Model\ViewModel)) #1 D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\View\View.php(233): Zend\View\View->render(Object(Zend\View\Model\ViewModel)) #2 D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\View\View.php(198): Zend\View\View->renderChildren(Object(Zend\View\Model\ViewModel)) #3 D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\Mvc\View\Http\DefaultRenderingStrategy.php(102): Zend\View\View->render(Object(Zend\View\Model\ViewModel)) #4 [internal function]: Zend\Mvc\View\Http\DefaultRenderingStrategy->render(Object(Zend\Mvc\ in D:\Source Code\PHP\xampp\htdocs\English\vendor\ZF2\library\Zend\View\Renderer\PhpRenderer.php on line 498
What type of object will return
$this->getServiceLocator()->get(‘memcached’)
?
\Memcached or some Zend implementation?
Zend\Cache\Storage\Adapter\Memcach will returns
I’m like factory way more, for example
class CacheFactory() {
$cache = new \Zend\Cache\Storage\Adapter\Filesystem();
$cache->getOptions()
->setWritable(TRUE)
->setReadable(TRUE)
->setTtl(3600)
->setCacheDir(‘./data/cache/filesystem’)
->setDirPermission(“777”)->setFilePermission(‘666’);
$plugin = new \Zend\Cache\Storage\Plugin\ExceptionHandler();
$plugin->getOptions()->setThrowExceptions(false);
$cache->addPlugin($plugin);
$pluginSerializer = new \Zend\Cache\Storage\Plugin\Serializer();
$cache->addPlugin($pluginSerializer);
return $cache
}
and use it in config
you can var_dump it…
I have error :
An abstract factory could not create an instance of memcached(alias: memcached).
Please help me fix it
please take a look the full stack trace, it should be because you doens’t have memcached installed. please google for it.
when i use code below :
connect(‘localhost’,11211);
echo $memcache->getVersion();
}
else{
die(‘Can not connect to Memcache Server’);
}
?>
Result is 1.2.6
but when I use in zf2, I have an error as above,
I do not know how to fix it, please help
Please add an article to configure Redis also..!!