CakePHP: Cache can write file but not read it (always false) - cakephp

I am trying to cache something. In my core.php config file, I have this:
//short
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 have this:
$xmlpublist = Cache::read('xmlpublist');
var_dump($xmlpublist);
//if cache is still set, return cache
if($xmlpublist !== false) {
die('cache A');
return $xmlpublist;
}
Cache::write('xmlpublist', "test", 'short');
die('cache C');
return $xml;
I can see that the file is generated - /path/to/cache/cake_short_xmlpublist
But when I Cache::read('xmlpublist'), I always get bool(false). I made sure that I have both read and write access to the cache directory.
Expectation:
Get values from the cache.
Result:
I get bool(false)
Where could have I gone wrong?
Any reply appreciated ;)
Thanks,
W

When calling Cache::read() you need to include the cache configuration to read from, so in your case 'short'. Without that additional parameter you'll be reading from the 'default' config which probably doesn't have the key you're looking for.

Related

How to decrease session time in cakephp

i have write this code in app/Config/core.php file of cakephp to timeout in 1 minute
Configure::write('Session', array(
'defaults' => 'php',
'timeout' => 1,
'autoRegenerate' => true
));
but this code not work
When you use the 'php' defaults, the time out is actually taken from the session.cookie_lifetime directive in php.ini. Either change the value in the php.ini configuration for your php or change the configuration like this:
Configure::write('Session', array(
'defaults' => 'php',
'autoRegenerate' => true,
'ini' => array('session.cookie_lifetime' => $timeInSeconds)
));

cakephp redis storage besides sessions

I am trying to use redis as my caching engine and I have so far was able to add the add redis in cakephp and it writes my sessions to my redis just fine. This is what I did in the core
$engine = 'Redis';
$prefix = 'myapp_';
Cache::config('session', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_session_',
'duration' => $duration
));
Configure::write('Session', array(
'defaults' => 'cache',
'timeout' => 100,
'start' => true,
'checkAgent' => false,
'handler' => array(
'config' => 'session'
)
));
Now I want to be able to write to redis from my controller some cached queries but I am not able to save that in redis. Instead it saves it to some default (I have no idea where) cache.
This is what I did in my controller
public function index()
{
Cache::write("TestKey","myquery","default");
var_dump(Cache::read("TestKey")); die;
}
The above gives me the value myquery on the browser but when I go to my redis-cli and look for keys * I do not see that key there. So obviously its saving somewhere else. I am not sure how to make it to write to redis. I have tried this Cache::write("TestKey","myquery","Redis"); but that also did not work.
Thanks for help in advance
**EDIT 1 **
I just did some debugging and it looks like its trying to add to file
object(FileEngine)[3]
protected '_File' => null
public 'settings' =>
array (size=10)
'engine' => string 'File' (length=4)
'path' => string '/Library/WebServer/Documents/phoneapp_backend/app/tmp/cache/' (length=60)
'prefix' => string 'cake_' (length=5)
'lock' => boolean true
'serialize' => boolean true
'isWindows' => boolean false
'mask' => int 436
'duration' => int 3600
'probability' => int 100
'groups' =>
array (size=0)
empty
protected '_init' => boolean true
protected '_groupPrefix' => null
How do I change it to write to redis?
Thanks
You need to configure the default cache configuration to use Redis insteado of File. In app/Config/bootstrap.php Change
Cache::config('default', array('engine' => 'File'));
So it reads:
Cache::config('default', array('engine' => 'Redis'));
You may need to add more options to the configuration for specifying the server and port where Redis is running.

Custom Log Method

I am attempting to implement a log system in cakePHP. I have a issue now were the methods contents in "write" are called twice. This causes an issue because it places 2 log entries of the same type in my system.
Databaselogger.php in the Lib/Engine/ directory:
App::uses('CakeLogInterface', 'Log');
class DatabaseLogger implements CakeLogInterface {
private $types = array();
public function __construct($options = array()) {
// Allowed method calls
$this->types = $options['types'];
}
public function write($type = NULL, $message = NULL) {
// Only store to cache types that are permitted, other errors from cake are not reported
if(!empty($this->types) && in_array($type, $this->types))
{
//make database entry here
}
}
}
In my bootstrap.php :
App::uses('CakeLog', 'Log');
CakeLog::config('debug', array(
'engine' => 'FileLog',
'types' => array('notice', 'info', 'debug'),
'file' => 'debug',
));
CakeLog::config('error', array(
'engine' => 'FileLog',
'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
'file' => 'error',
));
// Custom configuration
CakeLog::config('mytest', array(
'engine' => 'DatabaseLogger',
'types' => array('mytest'),
'scope' => array(),
'file' => '',
));
This is how I call the method:
CakeLog::write('mytest', 'this message!');
Can anyone give some hints as to why this might be happening? Thanks!
As the namespace of the core files is
/Log/Engine/
I would assume that it should be
/Lib/Log/Engine/DatabaseLog.php (or Logger if you want to straggle from the core naming).
accordingly.
Proof you will get from the LogEngineCollection class, which contains:
App::uses($loggerName, $plugin . 'Log/Engine');
to include the engine of yours (hence the importance of the correct namespace).
Please take the time to look into the core code. Its open source after all :)

CakePHP Cache Config always reverts to File (from Memcache or APC)

Firstly both Memcache and APC are installed successfully using PECL (and are verified as working) on my Macbook Pro dev server running PHP 5.3.15
I've just baked a test Cake 2.2.2 app. In Config/core.php I have the following:
/**
* Pick the caching engine to use. If APC is enabled use it.
* If running via cli - apc is disabled by default. ensure it's available and enabled in this case
*
*/
$engine = 'File';
if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) {
$engine = 'Apc';
}
if (extension_loaded('memcache') && php_sapi_name() !== 'cli') {
$engine = 'Memcache';
}
// In development mode, caches should expire quickly.
$duration = '+999 days';
if (Configure::read('debug') >= 1) {
$duration = '+10 seconds';
}
// Prefix each application on the same server with a different string, to avoid Memcache and APC conflicts.
$prefix = 'mcmyapp_';
/**
* Configure the cache used for general framework caching. Path information,
* object listings, and translation cache files are stored with this configuration.
*/
Cache::config('_cake_core_', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_core_',
'path' => CACHE . 'persistent' . DS,
'serialize' => ($engine === 'File'),
'duration' => $duration
));
/**
* Configure the cache for model and datasource caches. This cache configuration
* is used to store schema descriptions, and table listings in connections.
*/
Cache::config('_cake_model_', array(
'engine' => $engine,
'prefix' => $prefix . 'cake_model_',
'path' => CACHE . 'models' . DS,
'serialize' => ($engine === 'File'),
'duration' => $duration
));
Cache::config('default', array(
'engine' => $engine,
'serialize' => ($engine === 'File'),
'duration'=>$duration,
'prefix'=>$prefix,
));
debug(Cache::settings());
The output of the above final debug() is:
array(
'prefix' => '*****',
'engine' => 'Memcache',
'serialize' => false,
'duration' => (int) 10,
'servers' => array(
(int) 0 => '127.0.0.1'
),
'compress' => false,
'persistent' => true,
'probability' => (int) 100,
'groups' => array()
)
So in core.php it appears that Cake wants to use Memcache for its caching engine.
However, when I visit localhost/myapp/pages/home in my browser, CakePHP's default, freshly-baked welcome page greets me, informing me that The FileEngine is being used for core caching
Anywhere else in my app (other than in core.php) if I debug(Cache::settings()), I get the following:
array(
'prefix' => '*****',
'engine' => 'File',
'serialize' => false,
'duration' => (int) 10,
'servers' => array(
(int) 0 => '127.0.0.1'
),
'compress' => false,
'persistent' => true,
'probability' => (int) 100,
'groups' => array()
)
Basically, CakePHP appears to revert to File for caching, ignoring my configuration in core.php to use Memcache... unless I've done something wrong here??!
I've tried this with Configure::write('debug', 0) and Configure::write('debug', 1).
I should mention that with the above, both APC and Memcache extensions are enabled in php.ini.
Any help would be gratefully received, thanks in advance.
Memcached should be on some port, default one is 11211 (check)... So your config tries to connect to Memcached, fails and reverts back to default (File) cache...
Try:
Cache::config('default', array(
'engine' => 'Memcache',
'duration'=> 3600,
'probability'=> 100,
'servers' => array('127.0.0.1:11211') <<<<==
));

Browsers do not cache response sent by MediaView

This is my controller code:
$this->viewClass = 'Media';
$params = array(
'id' => $filename '.gif',
'name' => $filename ,
'download' => false,
'extension' => 'gif',
'path' => $folderpath,
'cache' => '+30 days',
'modified' => '#' . filemtime($pathtofile),
);
$this->set($params);
and the response:
Debug is disabled in core.php. However, the browser (Firefox, Chrome) never caches the file and always download the whole thing. Is this because of the 200 OK response? How can I fix it?
EDIT
I probably should have added a sample of the actual request URL
http://localhost/mycontroller/mymediaaction/2345
I resolved the issue by setting the name attribute to the action parameter instead of the actual file name. I still appreciate an answer with some explanation of this behavior.
The following code snippet for a controller action would either serve a 304 response or the file. I think that the checkNotModified functionality should be done by the MediaView::render function internally, similar to the AssetDispatcher. But for the time being this snippet may be of help.
$modified = #filemtime(ROOT . $dir . $filename);
$this->response->modified($modified);
if ($this->response->checkNotModified($this->request))
{
$this->autoRender = false;
$this->response->send();
}
else
{
$this->viewClass = 'Media';
$params = array('id' => $filename,
'cache' => '+1 day',
'modified' => '#' . $modified, // Must be a string to work. See MediaView->render()
'path' => ROOT . $dir);
$this->set($params);
}
return;

Resources