Zend_Cache cache file disappears - zend-framework

I have a zend cache which stores an array from the db. The cache can be read & updated fine. But the actual cache file seems to disappear after a day or so. I thought that adding automatic_cleaning_factor = 0 would solve this, but that doesn't seem to be the case.
$frontendOptions = array(
'caching' => true,
'cache_id_prefix' => 'mysite_blah',
'lifetime' => 14400, # 4 hours
'automatic_serialization' => true,
'automatic_cleaning_factor' => 0,
);
$backendOptions = array(
'cache_dir' => "{$_SERVER['DOCUMENT_ROOT']}/../../cache/zend_cache/"
);
$cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
if(!$result = $cache->load('test_blah'))
{
// run SQL
...
$cache->save($my_array_from_db, 'test_blah');
}
else
{
$result = $cache->load('test_blah');
}
The page which uses this cache isn't very popular, not sure if that has anything to do with it..... Any ideas?

I cannot explain why your file is vanishing, I think something is missing from your sample that is probably removing the cache file. I can however have a few notes that might help you out...
I think you're misinterpreting the automatic_cleaning_factor parameter. This does not disable your cache from expiring. This only disables the cache frontend from automatically cleaning any cache that may have expired when you call the save() method.
When you load() your cache it still gets tested for validity, and if invalid, it gets ignored and your database will be queried for fresh data. You can pass true as a second parameter on the load() to ignore the validity test.
However you should probably just set your lifetime to a very long time instead of overriding cache validation, because it's there for a reason.
Also, this code can be simplified:
if(!$result = $cache->load('test_blah')) {
// run SQL
...
$cache->save($my_array_from_db, 'test_blah');
} else {
$result = $cache->load('test_blah');
}
To:
if(!$result = $cache->load('test_blah')) {
// run SQL
...
$result = $my_array_from_db;
$cache->save($result, 'test_blah');
}
The else is not needed because $result from your cache is assigned in the if() statement.

Related

Call Config::Load doesn't work in Fuelphp

I have a class in the path 'app/classes' called 'Helper.php'. And also I have a config file 'custom.php' in 'app/config'.
The problem is, when I call the config file, this return FALSE.
class Helper {
public static function actions_header ($ractive) {
return Config::load('custom');
}
}
The custom config file
return array(
'sidebar_entities' => array (
array(
'name' => 'Dashboard',
'icon' => 'icon-dashboard',
'url' => 'dashboard'
),
array(
'name' => 'Álbumes',
'icon' => 'icon-music',
'url' => 'albums'
)
)
);
You probably need something like this:
// load the config
Config::load('custom', true); // true - so you load the config to group 'custom'
// return array of items
return Config::get('custom');
I have not tested this, but something like this should work.
Tried to repeat the same code and everything works fine for me. FuelPHP 1.7.
Up until 2012-08-28, load() only returned the loaded data on the initial call. If you called load() and the file is already loaded, it returned false. Since then, it will not load the file again, but return what is already loaded.
So the question is: how old is the version of Fuel you are using? Given the date of the change, that would be < 1.3, which is very old...
I have run into this issue as well. I run the following code. (I am running Fuel 1.6)
Config::load('config_file_name') //returns config array
Config::load('config_file_name') //returns false
Then I run the following to load a sub array of the config file.
Config::get('config_file_name.attr') //returns nothing
Turns out I just didn't understand the fuel documentation. Thanks #huglester, your answer made it all make sense for some reason.
The documentation says:
// This merges the "custom" config file in with the root config.
Config::load('custom');
// This loads the "custom" config file in a group named "custom".
Config::load('custom', true);
So, when you run Config::load('config_file_name'), you can access the config sub arrays by using Config::get('attr'). This is because the 'config_file_name' is merged with the root config.
If you want to use Config::get('config_file_name.attr'), then you need to load the config file using Config::load('config_file_name', true)

Zend_Cache_Frontend_Page does not recognize output without echo

I am trying to fiddle around with Zend_Cache, so I added following code to my action (will be moved to bootstrap later, I guess):
$frontendOptions = array(
'lifetime' => 7200,
'debug_header' => true, // für das Debuggen
'default_options' => array(
'cache' => true,
'cache_with_get_variables' => true,
'cache_with_session_variables' => true,
'cache_with_cookie_variables' => true,
'cache_with_post_variables' => true,
)
);
$backendOptions = array(
'cache_dir' => '/tmp/'
);
$cache = Zend_Cache::factory('Page', 'File',
$frontendOptions, $backendOptions
);
echo "hej";
var_dump($cache->start('someid'));
Zend generates a cache file containing hejbool(false) now, but apart from that it does not cache my page. According to a German book about zend framework, false is correct when there is no cache available. true is only returned when a cache was found.
When I debugged within Zend_Cache_Frontend_Page.php directly, it went down to the bottom of the start()-method, meaning that nothing went wrong (id given) and no cache was found, so one had to be generated. This was done (I can see it in /tmp/), but without the needed content.
So why does not not cache the output from Zend_View, but only direct output via echo?
I do not call any explicit function to render the view, but this did not seem necessary anymore (my views are always rendered automatically according to controller and action). I tried it for both a standard XHTML template (index.phtml) and an RSS template (index.rss.phtml).
Any ideas? Do you need any other code fragments?
When using the Zend_Cache_Frontend_Page you have to enable the disableOutputBuffering option. The reason is that Zend_Cache_Frontend_Page uses ob_start with a callback and it has to be the first call to ob_start otherwise it leads to that strange behaviour you've encountered.
To enable it you can either set it in your Bootstrap with
Zend_Controller_Front::getInstance()->setParam('disableOutputBuffering', true);
or using the configuration file after your frontController-setup (here in the INI-style configuration):
resources.frontController.params.disableOutputBuffering = true

Zend_db caching

Is there a way to caching resultsets in Zend_db? For example, I want to run a select query using Zend_db and want this query to be cached to be able to run it faster later.
My advice is that create a initialization method in Bootstrap.php with prefix "_init". for exaple :
/**
*
* #return Zend_Cache_Manager
*/
public function _initCache()
{
$cacheManager = new Zend_Cache_Manager();
$frontendOptions = array(
'lifetime' => 7200, // cache lifetime of 2 hours
'automatic_serialization' => true
);
$backendOptions = array(
'cache_dir' => APPLICATION_PATH . '/cache/zend_cache'
);
$coreCache = Zend_Cache::factory(
'Core',
'File',
$frontendOptions,
$backendOptions
);
$cacheManager->setCache('coreCache', $coreCache);
$pageCache = Zend_Cache::factory(
'Page',
'File',
$frontendOptions,
$backendOptions
);
$cacheManager->setCache('pageCache', $pageCache);
Zend_Registry::set('cacheMan', $cacheManager);
return $cacheManager;
}
By this way, you have created and injected your cache manager with the caches which you need in your app.
Now you can use this cache object where you want to use.
For instance, in your controller or where else :
/**
*
* #return boolean |SimplePie
*/
public function getDayPosts()
{
$cacheManager = Zend_Registry::get('cacheMan');
$cache = $cacheManager->getCache('coreCache');
$cacheID = 'getDayPosts';
if (false === ($blog = $cache->load($cacheID))) {
$blog = Blog::find(array('order' => 'rand()', 'limit' => 1));
$cache->save($blog, $cacheID);
}
// do what you want to do with the daya you fetched.
}
You can use Zend_Cache when you want to save result-sets.
Zend_Db doesn't do any result-set caching itself. It's left for you to do it an application-specific way, because the framework has no way of knowing which result-sets need to be cached for performance reasons, versus those that can't be cached because you need them to be absolutely current. Those are criteria only you as the application developer know.
Just googling for "zend_db cache results" the first match is this blog showing how to use a Zend_Cache object to save a db query result: Zend Framework:: Caching the database query results

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.

Setting a fe_users session from extbase

As I have to verify the login-data in a way, normal login extensions can not handle, I have to develop a custom login-form. This login box is part of an ext. written in extbase.
But I stuck with a basic question: How can i handle fe_users sessions in extbase?
I wrote this function, maybe it helps:
/** #var $fe_user tslib_feUserAuth */
$fe_user = $GLOBALS['TSFE']->fe_user;
$fe_user->createUserSession(array('uid' => $uid));
$fe_user->user = $fe_user->getRawUserByUid($uid);
$fe_user->fetchGroupData();
$GLOBALS['TSFE']->loginUser = 1;
It's inspired by Tx_Phpunit_Framework::loginFrontEndUser($userId) :
// Instead of passing the actual user data to createUserSession, we
// pass an empty array to improve performance (e.g. no session record
// will be written to the database).
$GLOBALS['TSFE']->fe_user->createUserSession(array());
$GLOBALS['TSFE']->fe_user->user = $GLOBALS['TSFE']->fe_user->getRawUserByUid($userId);
$GLOBALS['TSFE']->fe_user->fetchGroupData();
$GLOBALS['TSFE']->loginUser = 1;
None of the answers provided seemed to work for me in TYPO3 6.2. The fix is described in a Bugreport in the Forge, https://forge.typo3.org/issues/62194 . Basically, the SessionCookie isn't placed automatically anymore, you need to do that on your own now, adding
$reflection = new \ReflectionClass($GLOBALS['TSFE']->fe_user);
$setSessionCookieMethod = $reflection->getMethod('setSessionCookie');
$setSessionCookieMethod->setAccessible(TRUE);
$setSessionCookieMethod->invoke($GLOBALS['TSFE']->fe_user);
after calling the createUserSession().
I finally made it, by combining lots of snippets. Thats how it worked out for me:
$loginData = array(
'uname' => $loginData['user'],
'uident' => $loginData['passw'],
'status' => 'login'
);
$GLOBALS['TSFE']->fe_user->checkPid = 0;
$info = $GLOBALS['TSFE']->fe_user->getAuthInfoArray();
$user = $GLOBALS['TSFE']->fe_user->fetchUserRecord( $info['db_user'], $loginData['uname'] );
if ( $GLOBALS['TSFE']->fe_user->compareUident($user,$loginData) )
{
$GLOBALS["TSFE"]->fe_user->user = $GLOBALS["TSFE"]->fe_user->fetchUserSession();
$GLOBALS['TSFE']->loginUser = 1;
$GLOBALS['TSFE']->fe_user->fetchGroupData();
$GLOBALS['TSFE']->fe_user->start();
$GLOBALS["TSFE"]->fe_user->createUserSession($user);
$GLOBALS["TSFE"]->fe_user->loginSessionStarted = TRUE;
}