I have a site developed in cakephp. I want to cache a query. I have read the documentation and I have in my bootstrap.php this:
Cache::config('default', array('engine' => 'File'));
Cache::config('short', array(
'engine' => 'File',
'duration' => '+1 hours',
'path' => CACHE,
'prefix' => 'cake_short_'
));
// long
Cache::config('long', array(
'engine' => 'File',
'duration' => '+1 week',
'probability' => 100,
'path' => CACHE . 'long' . DS,
));
My controller to store the query is this:
public function test_view () {
$product_general = Cache::read('product_general_query', 'longterm');
if (!$product_general) {
echo("test");
$product_general = $this->Product->query('SELECT DISTINCT * FROM products');
Cache::write('product_general_query', $product_general, 'longterm');
}
$this->set('product_general', $product_general);
}
Everytime that I enter into the page it print me "test" because doesn't find the query into the cache. Where is the problem? Have I miss something?
You named your cache configuration 'long' inside your core.php but using configuration 'longterm' inside your action
Also, If you have enabled debugging (e.g. debug set to 1 or 2 in your core.conf), the cache duration may be set to 10 seconds automatically. Not sure if this will apply to your own cache definitions as well though
Related
Where is session files stored in Yii2? I need to know the the exact location. There is options to create a session database.
The default session save path is '/tmp'. link
This path is accessible via the getSavePath() method in the session class file(yii2)
#property string $savePath The current session save path, defaults to '/tmp'.
For example, in xampp software (localhost) go to the following folder(default)
myDrive:\xampp\tmp // The drive where the software is installed
It is taken by default through the session_save_path method. Which depends on the settings of the php.ini file. In session.save_path="...\tmp"
But you can also configure it through the .htaccess file
To adjust Yii2, you can do the following. In the config web file
'components' => [
'session' => [
'name' => '_Session',
'savePath' => dirname(__DIR__) .'/sessions'
],
To save in the database(yii\web\DbSession) refer to this link.
Example:
'session' => [
'class' => 'yii\web\DbSession',
'name' => 'mySession',
// 'db' => 'mydb', // the application component ID of the DB connection. Defaults to 'db'.
// 'sessionTable' => 'my_session', // session table name. Defaults to 'session'.
'timeout' => 30 * 24 * 3600,
'cookieParams' => ['httponly' => true, 'lifetime' => 3600 * 24],
'writeCallback' => function ($session) {
return [
// 'user_id' => Yii::$app->user->id,
// 'last_write' => time(),
];
},
],
writeCallback: To create more data and columns in the database table
Good luck
Yii2 by default stores session files in #app/runtime/data folder.
And if you want to use database instead then yii2 guide is great resource. check this link: https://www.yiiframework.com/doc/guide/2.0/en/runtime-sessions-cookies#custom-session-storage.
I am trying to save a string with one application to memcached. And then after an http redirect, trying to retrieve that information from a different application on the same server. I am able to save, but retrieving the information is not working.
I have made sure that both applications are not applying a prefix to the cache key. I have run 'memcached-tool localhost:11211 dump | less' on the memcache server to ensure the data exists, which it does. I can access the data from the same application that saves the data. So if I save from the Laravel app, I can retrieve from the laravel app, and vice versa for the phalcon app.
The environment variables used are the same in both apps.
Setup in Laravel (cache.php):
'memcached' => [
'driver' => 'memcached',
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 0,
],
],
],
How I am saving in Laravel:
Cache::put($sha, $viewData, 60);
return redirect("someUrl/{$sha}", 302);
Setup in Phalcon:
$di->setShared('memcached', function(){
// Cache data for one hour
$frontCache = new \Phalcon\Cache\Frontend\Data(
[
'lifetime' => 60,
'prefix' => ''
]
);
// Create the component that will cache 'Data' to a 'Memcached' backend
// Memcached connection settings
return new \Phalcon\Cache\Backend\Libmemcached(
$frontCache,
[
'prefix' => '',
'servers' => [
[
'host' => MEMCACHED_SERVER,
'port' => MEMCACHED_PORT,
'weight' => 0,
]
]
]
);
});
How I am trying to retrieve info in Phalcon:
$cache = $this->di->getShared('memcached');
$info = $cache->get($cacheKey);
Here is the output of the $cache var from xdebug:
Phalcon\Cache\Backend\Libmemcached::__set_state(array(
'_frontend' =>
Phalcon\Cache\Frontend\Data::__set_state(array(
'_frontendOptions' =>
array (
'lifetime' => 60,
'prefix' => '',
),
)),
'_options' =>
array (
'prefix' => '',
'servers' =>
array (
0 =>
array (
'host' => 'servername',
'port' => port,
'weight' => 0,
),
),
'statsKey' => '',
),
'_prefix' => '',
'_lastKey' => '38404efbc4fb72ca9cd2963d1e811e95fe76960b',
'_lastLifetime' => NULL,
'_fresh' => false,
'_started' => false,
'_memcache' =>
Memcached::__set_state(array(
)),
))
And here is the dump from memcached-tool:
Dumping memcache contents
add 38404efbc4fb72ca9cd2963d1e811e95fe76960b 4 1562346522 144
a:5:{s:3:"zip";s:0:"";s:10:"first_name";s:5:"Clint";s:9:"last_name";s:9:"Broadhead";s:5:"phone";s:0:"";s:5:"email";s:20:"blah#blah.com";}
I expected to be able to save to memcache from any application and then retrieve that cache from anywhere else that has access to the same server. But when I try to retrieve in the phalcon app I receive 'null'. Even though I can see the key/value pair on the server. Thanks in advance for your assistance.
I bypassed using Phalcons built-in backend and frontend classes and just went with using the PHP ext-memcached on the phalcon app.
$di->setShared('memcached', function(){
if( !($this->_memcache instanceof \Memcached) ){
if( !class_exists('Memcached') ){
throw new CacheException('Unable to connect to cache');
}
$this->_memcache = new \Memcached();
$this->_memcache->addServer(MEMCACHE_SERVER, MEMCACHE_PORT)
return $this->_memcache;
}
});
I started to go down the path of phalcons use of '_PHCM', but once the above solution worked I abandoned that research. Not the best, but works well for my temporary situation.
Phalcon uses prefixes for all cache keys by default. For the Libmemcached adapter
For instance the get for the Libmemcached adapter has:
let prefixedKey = this->_prefix . keyName;
let this->_lastKey = prefixedKey;
let cachedContent = memcache->get(prefixedKey);
https://github.com/phalcon/cphalcon/blob/3.4.x/phalcon/cache/backend/libmemcached.zep#L160
Just make sure that there are no prefixes by setting the prefix option in your options
$di->setShared('memcached', function(){
// Cache data for one hour
$frontCache = new \Phalcon\Cache\Frontend\Data(
[
'lifetime' => 60,
]
);
// Create the component that will cache 'Data' to a 'Memcached' backend
// Memcached connection settings
return new \Phalcon\Cache\Backend\Libmemcached(
$frontCache,
[
'prefix' => '',
'servers' => [
[
'host' => MEMCACHED_SERVER,
'port' => MEMCACHED_PORT,
'weight' => 0,
]
]
]
);
});
https://github.com/phalcon/cphalcon/blob/3.4.x/phalcon/cache/backend.zep#L59
Finally if the above does not work, install a utility that will allow you to query your Memcached instance and see what keys are stored there. Check it before you store data with Laravel and then afterwards. This way you will know whether you check the correct thing or not.
Alternatively you can use good old telnet if you are comfortable with the command line to check the keys.
I have to set up a Redis on a server to store information from Zend Framework 2.
For now, I can store information, but I can not to give them an expiration time for they naturally renew themselves after a while.
I have not found some documentations about this step and it seems to me rather obscure.
My code:
page: config/autoload/cache.global.php
return array(
'caches' => array(
'redis' => array (
'adapter' => array (
'name' => 'redis',
'lifetime' => 60, //doesn't work
'options' => array (
'server' => array (
'host' => 'x.x.x.x',
'port' => x
),
'ttl' => 10, // seems to have no effect
'namespace' => 'mycache',
),
),
)
)
);
in Controller :
..
use Zend\Cache\StorageFactory;
..
$redis = StorageFactory::factory ($this->getServiceLocator ()
->get ('config')['caches']['redis']);
if ($redis->hasItem ('test')) {
var_dump($redis->getItem ('test'));
$redis->removeItem('test');
} else {
$redis->addItem('test', 'testtest');
}
..
I tried several methods, but everytime, the result is the same, no expiration information appears in Redis :
127.0.0.1:6379> get mycache:test
"testtest"
127.0.0.1:6379> ttl mycache:test
(integer) -1
Thanks for your help!
You can also try this:
$redis = $this->getServiceLocator()->get('Cache\RedisFactory');
$redis->getOptions()->setTtl(10);
$redis->setItem('test', 'Custom Value');
So there is no need to set it globaly in factory.
This work for me :)
Take a look at my redis factory bellow:
<?php
namespace Application\Service\Factory;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\Cache\Storage\Adapter\RedisOptions;
use Zend\Cache\Storage\Adapter\Redis;
class RedisCacheFactory implements FactoryInterface
{
public function createService(ServiceLocatorInterface $serviceLocator)
{
$config = $serviceLocator->get('Config');
$config = $config['redis'];
$options = new RedisOptions();
$options->setServer(
[
'host' => $config["host"],
'port' => $config["port"],
'timeout' => $config["timeout"]
]
);
$options->setTtl(60);
/**
* This is not required, although it will allow to store anything that can be serialized by PHP in Redis
*/
$options->setLibOptions(
[
\Redis::OPT_SERIALIZER => \Redis::SERIALIZER_PHP
]
);
$redis = new Redis($options);
return $redis;
}
}
As you can see from the example, the TTL is set to 60 seconds and its working as expected.
Predis\Client has a "magic call" method command executor for setEx:
$redis->setEx($key, $expireTTL, $value);
This will set key if does not exist with passed value for a custom expiration time.
This will update existing key, resetting expiration time.
Double check as you mentioned to see that everything works as expected:
127.0.0.1:6379>dump your_key
127.0.0.1:6379>ttl your_key
Hope it helps :) !
return array(
'caches' => array(
'redis' => array (
'adapter' => array (
'name' => 'redis',
'options' => array (
'server' => array (
'host' => 'x.x.x.x',
'port' => x
),
'Ttl' => 10, // Starting with capital letter
'namespace' => 'mycache',
),
),
)
)
);
I am creating an web application in Yii . I was trying to do a sessiontimeout, if a user is idle for 30 minutes.After that he should login again.. but this is not working. I am using CHttpSession. However if i give CDbHttpSession instead of CHttpSession this is working fine.
this is my code
'user' => array(
'class' => 'WebUser',
'loginUrl' => array('site/loginaccount'),
'allowAutoLogin' => true,
),
// uncomment the following to enable URLs in path-format
'session' => array(
'class'=>'CHttpSession',
'timeout'=>$params['session_timeout'],
'autoStart'=>true,
),
Is there anything else to make this work for CHttpSession ? Due to some reasons i cannot use CDbHttpSession in my web application .
If you want that the user is sign out automatically after 30 minutes try:
'user' => array(
'class' => 'WebUser',
'loginUrl' => array('site/loginaccount'),
'allowAutoLogin' => true,
'authTimeout' => 1800
),
protected/config/main.php : (define the session timeout)
$sessionTimeout = 5; // 5 secondes
return array(
'params'=>array(
'session_timeout'=> $sessionTimeout,
);
'components'=>array(
'session' => array(
'class' => 'CDbHttpSession',
'timeout' => $sessionTimeout,
),
),
);
protected/views/layout/main.php : (define the refresh)
<html>
<head>
<?php if (!Yii::app()->user->isGuest) {?>
<meta http-equiv="refresh" content="<?php echo Yii::app()->params['session_timeout'];?>;"/>
<?php }?>
</head>
<body>
…
</body>
</html>
I've read the source code of the CHttpSession. It is a wrap of the PHP Session. So, the mechanism of CHttpSession is the same with the PHP Session.
public function setTimeout($value)
{
ini_set('session.gc_maxlifetime',$value);
}
the above is the code of timeout setter. it is just the setting of ini settings of the PHP. And according to the PHP documentation of session, after the maxlifetime, the session is just "potentially cleaned up", not for sure.
And the probability of it can be set by session.gc_probability. the default value is 1, which means 1%. So, you can set it to 100, make the garbage collection process run every time the script is run.
change your setting to
'session' => array(
'class'=>'CHttpSession',
'timeout'=>$params['session_timeout'],
'autoStart'=>true,
'gCProbability' => 100,
),
hope it helps.
return array('components'=>array(
'session'=>array(
'timeout' => 1800
),
),
);
I have a site in cakephp and I have configure cache for It.
In bootstrap.php I have write this line like the guide in the site of cakephp:
Cache::config('default', array('engine' => 'File'));
Cache::config('short', array(
'engine' => 'File',
'duration' => '+1 hours',
'path' => CACHE,
'prefix' => 'cake_short_'
));
// long
Cache::config('long', array(
'engine' => 'File',
'duration' => '+1 week',
'probability' => 100,
'path' => CACHE . 'long' . DS,
));
In my controller I want to cache some query that are call many times like this:
class User extends AppModel {
public function get($alias) {
$result = Cache::read('get_users', 'longterm');
if (!$result) {
$result = $this->find('all', array('conditions' =>array( 'alias' => $alias)));
Cache::write('get_users', $result, 'longterm');
}
return $result;
}
}
I want to know if is efficient to cache query with parameters (alias) or is better to cache only query with not parameters like this?
$result = $this->find('all', array('order' =>'id'));
Because my doubt is: is useful to cache query with parameter or not? Is a good way to make more efficient the speed of the site?