Set ttl and namespace using Memcached in Zend Framework 2 - memcached

As far as I can figure this seems to be the way to set up Memcached and set the TTL and Namespace but they have no effect in the cache. The key is not prefixed with a namespace and the expire is infinite.
$MemcachedOptions = new \Zend\Cache\Storage\Adapter\MemcachedOptions();
$MemcachedResourceManager = new \Zend\Cache\Storage\Adapter\MemcachedResourceManager(1, new \Zend\Cache\Storage\Adapter\Memcached());
$MemcachedResourceManager->addServer(1, array('localhost', 11211));
$MemcachedOptions->setResourceManager($MemcachedResourceManager);
$MemcachedOptions->setNamespace('FooBar_');
$MemcachedOptions->setTtl(10);
$cache = $MemcachedOptions->getResourceManager()->getResource(1);
$cache->set('foobar_key','I am in cache');
Does anyone have any tips, clues? Any help would be much appreciated.

The MemcachedResourceManager works different as you trying to use it.
You should initialize it like the following:
// init a memcached resource manager with one native memcached resource
// using resource id "1"
$MemcachedResourceManager = new \Zend\Cache\Storage\Adapter\MemcachedResourceManager();
$MemcachedResourceManager->addServer('1', array('localhost', 11211));
// init a memcached storage adapter
// using the native memcached resource of id "1"
// configure it with a ttl and a namespace
$cache = \Zend\Cache\StorageFactory::adapterFactory('memcached', array(
'resource_manager' => $MemcachedResourceManager,
'resource_id' => '1',
'namespace' => 'FooBar_',
'ttl' => 10,
));
// or
$memcachedAdapterOptions = new \Zend\Cache\Storage\Adapter\MemcachedOptions(array(
'resource_manager' => $MemcachedResourceManager,
'resource_id' => '1',
'namespace' => 'FooBar_',
'ttl' => 10,
));
$cache = new \Zend\Cache\Storage\Adapter\Memcached($memcachedAdapterOptions);
How does the classes work together:
The most important class is Zend\Cache\Storage\Adapter\Memcached it is a wrapper for a native instance of Memcached used in a context of Zend\Cache\StorageInterface.
This storage adapter has a number of options defined as Zend\Cache\Storage\Adapter\MemcachedOptions.
Because cache storage adapters in ZF2 are designed to handle one type of items to store you need different instances of Zend\Cache\Storage\Adapter\Memcached for different type of items. But you don't wont to use different connections to a memcached (different instance of the native Memcached class) server - this is were Zend\Cache\Storage\Adapter\MemcachedResourceManager comes to play.
The Zend\Cache\Storage\Adapter\MemcachedResourceManager handles native instances of Memcached which will be used by Zend\Cache\Storage\Adapter\Memcached.

Related

multiple instances of view helper plugin?

How do I instantiate multiple instances of a view helper plugin in Zend 2?
I want to return a new instance every time I call $this->pluginName(); from the view.
How do I return a new instance of the view plugin?
Add the service name to the getViewHelperConfig() shared configuration key in Module.php and set this value to false
Module.php
function getViewHelperConfig()
{
return array(
'shared' => array(
'MyViewHelper' => false,
),
'factories' => array(
'MyViewHelper' => 'App\View\Helper\MyViewHelperFactory',
)
);
}
By adding 'MyViewHelper' => false, the service manager (or View Helper plugin manager) will create a new instance of that service each time it is used.
The documentation states
shared An array of service name/boolean pairs, indicating whether or not a service should be shared. By default, the ServiceManager assumes all services are shared, but you may specify a boolean false value here to indicate a new instance should be returned.

Flush default cache

I am using a couchbase memcached bucket for my cakephp default cache. I would like to be able to flush the cache when I change the schema within my cakephp app. There is a method to clear the cache however it is asking for arguments.
How do I use this method to clear / flush the cache?
Edit: my bootstrap contains the setup for the cache config
Cache::config('default', array(
'engine' => 'Memcache',
'prefix' => Inflector::slug(APP_DIR) . '_',
'servers' => array(
'127.0.0.1:11211' // localhost, default port 11211
), //[optional]
'duration' => 7200,
'serialize' => false,
'persistent' => true, // [optional] set this to false for non-persistent connections
'compress' => false,
'probability' => 100
)
);
Cache::clear(false, 'default'); // Default configuration, shortcut Cache::clear()
Cache::clear(false, '_cake_core_'); // General framework caching
Cache::clear(false, '_cake_model_'); // Cache for model and datasource caches

how to use Zend_Loader_PluginLoader?

I am trying to optimize zend for performance.
I used as much cache as possible and got to the code of this page
where do i have to write it ? i tried putting it in bootstrap __initAutoload() but the profiler shows no change whatsover
$classFileIncCache = APPLICATION_PATH . '/../data/pluginLoaderCache.php';
if (file_exists($classFileIncCache)) {
include_once $classFileIncCache;
}
Zend_Loader_PluginLoader::setIncludeFileCache($classFileIncCache);
Can someone explain how to use it pluginloader and if it has a performance increase?
here is part of my bootstrap
protected function _initSessionAfterDb()
{
//http://stackoverflow.com/questions/1100562/zend-error-via-my-ini-file
$this->bootstrap('db');
$this->bootstrap('session');
}
protected function _initSession()
{
$this->bootstrap('cache');//http://stackoverflow.com/questions/5271018/zend-how-to-enable-cachemetadata-on-session-table
//NOTE: this config is also passed to Zend_Db_Table so anything specific
//to the table can be put in the config as well
$config = array(
'name' => 'session', //table name as per Zend_Db_Table
'primary' => array(
'session_id', //the sessionID given by PHP
'save_path', //session.save_path
'name', //session name
//'cols' => array('session_id', 'save_path', 'name', 'modified', 'lifetime', 'session_data')
),
'primaryAssignment' => array(
//you must tell the save handler which columns you
//are using as the primary key. ORDER IS IMPORTANT
'sessionId', //first column of the primary key is of the sessionID
'sessionSavePath', //second column of the primary key is the save path
'sessionName', //third column of the primary key is the session name
),
'modifiedColumn' => 'modified', //time the session should expire
'dataColumn' => 'session_data', //serialized data
'lifetimeColumn' => 'lifetime', //end of life for a specific record
'user_id' => 'user_id'
);
//Tell Zend_Session to use your Save Handler
$savehandler = new Zend_Session_SaveHandler_DbTable($config);
//http://framework.zend.com/wiki/display/ZFPROP/Zend_Session_SaveHandler_DbTable
//cookie persist for 30 min
$config = Zend_Registry::get('config');
$seconds = $config->session->seconds_life;
//make the session persist for 30 min
$savehandler->setLifetime($seconds)
->setOverrideLifetime(true);
Zend_Session::setSaveHandler($savehandler);
Zend_Session::start();
}
I think you are not starting on the good foot, early optimization is the root of all evil. First I think you should investigate which part of your application is the slowest and try to fix it, xdebug should be able to help to get some performance data.
The plugin loader cache would increase the performance but not by a great deal, the framework search in the filesystem the plugins you are using. Enabling the cache would skip the searching process but I doubt it would make your application 50% faster all suddendly.
Also to answer where you should write it, like you mentioned the bootstrap is probably the best place.

Hostname and Custom routing in Zend Framework don't work together for me

I am building an application that uses hostname routing to detect subdomains like
user1.example.com
user2.example.com
and also have custom routes like user1.example.com/login
This works well so far, however when I add custom routes they do not work. I have searched and read a lot but seems there is something I am missing. Here is what I have so far:
//my routes in routes.ini
[development]
routes.login.type = "Zend_Controller_Router_Route"
routes.login.route = "/login"
routes.login.defaults.controller = "user"
routes.login.defaults.action = "login"
//This part in Bootstrap file
$this->bootstrap('frontController');
$router = $this->frontController->getRouter();
$routerConfig = new Zend_Config_Ini(
APPLICATION_PATH . '/configs/routes.ini',
'production'
);
//I create a default route
$routeDefault = new Zend_Controller_Router_Route_Module(
array(),
$this->frontController->getDispatcher(),
$this->frontController->getRequest()
);
$router->addConfig($routerConfig, 'routes');
// hostname route
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
':username.mysite.com',
array(
'module' => 'default',
'controller' => 'index',
'action' => 'index',
)
);
//I add the default route.
$router->addRoute('default', $routeDefault);
//I chain the routes so that all routes have subdomain routing too
foreach ($router->getRoutes() as $key => $theroute) {
$router->addRoute($key, $hostnameRoute->chain($theroute));
}
When I go to a custom route like http://user1.example.com/login I get the error: 'Invalid controller specified (login)' which means my custom route is not being recognized. I am also not sure if the way I am adding the default route is correct and necessary. If I remove that code then it doesn't work. So my problem really is that I would like my hostname matching, custom routes and default routes to all work. If you can spot where I'm going wrong please help, I have read previous related posts all over on routes, chaining, default routes etc (including this very related one: How do I write Routing Chains for a Subdomain in Zend Framework in a routing INI file?) but haven't found the solution so far.
You should be able to setup your routing using a custom param in the route:
routes.testdynamicsubdomain.type = "Zend_Controller_Router_Route_Hostname"
routes.testdynamicsubdomain.route = ":subdomain.domain.dev"
routes.testdynamicsubdomain.defaults.module = public
routes.testdynamicsubdomain.defaults.controller = index
routes.testdynamicsubdomain.defaults.action = index
If your apache/hostfile etc are configured correctly going to test.domain.dev should load the index action in your indexController where you could get the :subdomain param:
echo $this->getRequest()->getParam('subdomain');
Also, as you discovered, the order of the routes is very important. See also Zend Router precedence for more info about this.

How to route multi subdomain with zend router hostname

I need to create routing in Zend to simply copy the current live site url structure which is sadly inconsistent
What i want to do is to route subdomain as follow:
www.site.com -> static router
a.site.com & b.site.com -> category controller
c.site.com & d.site.com -> location controller
the rest sub domain -> user controller
could anyone guide me how to solve this, thanks.
UPDATE:
First thanks Fge, vote your answer, it works but i need some more advice:
Since i have many subdomains for each rules is there a better way than add the rules in looping
foreach($subdomains as $a){
$tr = new Zend_Controller_Router_Route_Hostname(
"$a.site.com",
array(
'module' => 'mod',
'controller' => 'ctrl',
'param_1' => $a
));
$router->addRoute($a,$tr);
}
How to combine it with other routing type to parse the parameters (chained?), something like http://a.site.com/:b/:c, i want t parse it to param_1 (a), param_2 (b), param_2 (c)
Note: Reverse Matching
Routes are
matched in reverse order so make sure
your most generic routes are defined
first.
(Zend_Controller_Router)
Thus you have to define the route for all other subdomains first, then the specific ones:
$user = new Zend_Controller_Router_Route_Hostname(
':subdomain.site.com',
array(
'controller' => 'user'
)
);
$location1 = new Zend_Controller_Router_Route_Hostname(
'c.site.com',
array(
'controller' => 'location'
)
);
$location1 = new Zend_Controller_Router_Route_Hostname(
'd.site.com',
array(
'controller' => 'location'
)
);
// other definitions with known subdomain
$router->addRoute($user); // most general one added first
$router->addRoute($location1);
$router->addRoute($location2);
// add all other subdomains
Update for the updated question:
1) This really depends on how different the parameters are you want to route a subdomain to. In your example you routed them all to the same model and controller and added the actual subdomain as a parameter. This can be done easily with the user-route i posted above. There the subdomain is set as parameter subdomain ($request->getParam("subdomain")). If you want the subdomains to be the action of a known controller/model you could replace :subdomain with :action. But as soon as you have other controllers/models for each subdomain, I'm affraid you have to loop over them (or use a config file). For the example you provided in the question, the route simply could look like this:
$user = new Zend_Controller_Router_Route_Hostname(
':param1.site.com',
array(
'controller' => 'user'
)
);
// routes "subdomain".site.com to defaultModul/userController/indexAction with additional parameter param1 => subdomain.
As long as you don't have any schema in your subdomains it's very difficult to route them in a general way.
2) That's an example where router chains come into play. The outer route would be the hostname route which handles the subdomain and the inner route would handle the :a/:b part. This could look like this for example:
$user->chain(new Zend_Controller_Router_Route(':a/:b'));