How to Variable Cache in PHP - php

I am looking at trying to cache variables in PHP from a JSON file. Is there anyone that knows of a good tutorial or can provide an example?

Save variable to file cache:
file_put_contents('cache.txt', json_encode($variable));
Read cache into variable:
$variable = json_decode(file_get_contents('cache.txt'));

Memcached is your best bet. It will save any serializable data in a very fast cache. You can find a tutorial at:
http://php.net/manual/en/memcache.examples-overview.php
It is lightning quick and has many other features that makes it better than just saving a txt file to the server.
$memcache->set('key', $jsonstring, false, 10)
and
$get_result = $memcache->get('key');

A simple approach is:
function getMyJson()
{
$data = apc_fetch('my_json', $wasCached);
if ($wasCached) {
return $data;
}
$data = json_decode(file_get_contents('/path/to/data.json'));
apc_store('my_json', $data);
return $data;
}
This uses APC's cache but you could work similarly with memcached, redis etc.

Related

Does file_get_contents use a cache?

I have a function that generates a table with contents from the DB. Some cells have custom HTML which I'm reading in with file_get_contents through a templating system.
The small content is the same but this action is performed maybe 15 times (I have a limit of 15 table rows per page). So does file_get_contents cache if it sees that the content is the same?
file_get_contents() does not have caching mechanism. However, you can use write your own caching mechanism.
Here is a draft :
$cache_file = 'content.cache';
if(file_exists($cache_file)) {
if(time() - filemtime($cache_file) > 86400) {
// too old , re-fetch
$cache = file_get_contents('YOUR FILE SOURCE');
file_put_contents($cache_file, $cache);
} else {
// cache is still fresh
}
} else {
// no cache, create one
$cache = file_get_contents('YOUR FILE SOURCE');
file_put_contents($cache_file, $cache);
}
UPDATE the previous if case is incorrect, now rectified by comparing to current time. Thanks #Arrakeen.
Like #deceze says, generally the answer is no. However operating system level caches may cache recently used files to make for quicker access, but I wouldn't count on those being available. If you'd like to cache a file that is being read multiple times per request, consider using a static variable to act as a cache inside a wrapper function.
function my_file_read($filename) {
static $file_contents = array();
if (!isset($file_contents[$filename])) {
$file_contents[$filename] = file_get_contents($filename);
}
return $file_contents[$filename];
}
Calling my_file_read($filename) multiple times will only read the file from disk a single time, subsequent calls will read the value from the static variable within the function. Note that you shouldn't count on this approach for large files or ones used only once per page, since the memory used by the static variable will persist until the end of the request. Keeping the contents of files unnecessarily in static variables is a good way to make your script a memory hog.
The correct answer is yes. All the PHP file system functions do their own caching, and you can use the "realpath_cache_size = 0" directive in PHP.ini to disable the caching if you like. The default caching timeout is 120 seconds. This is separate from the caching typically done by browsers for all GET requests (the majority of Web accesses) unless the HTTP headers override it. Caching is not a good idea during development work, since your code may read in old data from a file whose contents you have changed.

How to save Php variable every 5 minutes without database

On my website there is a php function func1(), which gets some info from other resources. It is very costly to run this function.
I want that when Visitor1 comes to my website then this func1() is executed and the value is stored in $variable1=func1(); in a text file (or something, but not a database).
Then a time interval of 5 min starts and when during this interval Visitor2 visits my website then he gets the value from the text file without calling the function func1().
When Visitor3 comes in 20 min, the function should be used again and store the new value for 5 minutes.
How to make it? A small working example would be nice.
Store it in a file, and check the file's timestamp with filemtime(). If it's too old, refresh it.
$maxage = 1200; // 20 minutes...
// If the file already exists and is older than the max age
// or doesn't exist yet...
if (!file_exists("file.txt") || (file_exists("file.txt") && filemtime("file.txt") < (time() - $maxage))) {
// Write a new value with file_put_contents()
$value = func1();
file_put_contents("file.txt", $value);
}
else {
// Otherwise read the value from the file...
$value = file_get_contents("file.txt");
}
Note: There are dedicated caching systems out there already, but if you only have this one value to worry about, this is a simple caching method.
What you are trying to accomplish is called caching. Some of the other answers you see here describe caching at it's simplest: to a file. There are many other options for caching depending on the size of the data, needs of the application, etc.
Here are some caching storage options:
File
Database/SQLite (yes, you can cache to a database)
MemCached
APC
XCache
There are also many things you can cache. Here are a few:
Plain Text/HTML
Serialized data such as PHP objects
Function Call output
Complete Pages
For a simple, yet very configurable way to cache, you can use the Zend_Cache component from the Zend Framework. This can be used on it's own without using the whole framework as described in this tutorial.
I saw somebody say use Sessions. This is not what you want as sessions are only available to the current user.
Here is an example using Zend_Cache:
include ‘library/Zend/Cache.php’;
// Unique cache tag
$cache_tag = "myFunction_Output";
// Lifetime set to 300 seconds = 5 minutes
$frontendOptions = array(
‘lifetime’ => 300,
‘automatic_serialization’ => true
);
$backendOptions = array(
‘cache_dir’ => ‘tmp/’
);
// Create cache object
$cache = Zend_Cache::factory(‘Core’, ‘File’, $frontendOptions, $backendOptions);
// Try to get data from cache
if(!($data = $cache->load($cache_tag)))
{
// Not found in cache, call function and save it
$data = myExpensiveFunction();
$cache->save($data, $cache_tag);
}
else
{
// Found data in cache, check it out
var_dump($data);
}
In a text file. Oldest way of saving stuff (almost). Or do a cronjob to run the script with the function each 5 minutes independently on the visits.
Use caching, such as APC!
If the resource is really big, this may not be the best option and a file may then indeed be better.
Look at:
apc_store
apc_fetch
Good luck!

How to do caching in php

I used the following code, but it is taking time. i want to cache without storing in a text file.
$file = 'cache_toppers.txt';
if (file_exists($file) &&
filemtime($file) > (time() - $expire)) {
$records = unserialize(file_get_contents($file));
} else {
include("kalvidbconnect.php");
$query = "SELECT * FROM vpfmsttoppers";
$result = mysql_query($query)
or die (mysql_error());
while ($record = mysql_fetch_array($result) ) {
$records[] = $record;
}
$OUTPUT = serialize($records);
$fp = fopen($file,"w");
fputs($fp, $OUTPUT);
fclose($fp);
}
Thanks,
Kamatchi.D
There are some ready to use PHP extensions providing cache functionality. Some of them:
memcache http://pecl.php.net/package/memcache
APC http://php.net/manual/en/book.apc.php
eAccelerator
XCache
these are the ones I know of, but surely there are many more.
Just a thought, not sure, but how about using CouchDB!?
Here is a good tutorial on IBM http://www.ibm.com/developerworks/opensource/library/os-php-couchdb/index.html?ca=drs-
If you don't want to use file-based caching, then one option is to build a wrapper and store it in shared memory,
http://se.php.net/manual/en/ref.sem.php
Maybe APC utilizes the same technique, I don't know, but if you don't want to install PECL-extensions then building your own cache-handling might be an option.
I would however consider caching rendered content to file, since that would put the least amount of load on the server.
Depending on a very long list of factors, I'd typically expect trying to unserialize the file to take longer than loading it fresh from the database.
Well, use cache then, for example APC - apc_store()/ apc_fetch()

php cache zend framework

server side is PHP + zend framework.
problem:
i have huge of data appox 5000 records and no of columns are 5 in input.txt file.
i like to read all data into memory only once and send some data to the every browser request.
but if i update that input.txt file then updated data must be auto synchronized to that
memory location.
so i need to solve that problem by using memory caching technique.but caching technique
has expire time.but if input.txt is updated before cache expire then i need to auto synchronize to that memory location.
now i am using zend framework 1.10.is it possible in zend framework.
can anybody give me some line of code of zendfrmawork
i have no option to use memchached server(distributed).
Only zend framwork.
It is possible to cache something like that using zend framework.
Check Zend documentation online - its not complete but can give you a head start:
http://framework.zend.com/manual/en/zend.cache.introduction.html
Use lazy loading like this (1h cache is usually OK).
function getData() {
$cache = ...; //get your memory cache here
$cacheId = 'MyCacheId'; //cache id for your data
$loadTimeCacheId = 'dataLoadCacheId'; //cache id for data load timestamp
$cacheLength = 3600; //seconds
$data = $cache->load($cacheId);
$loadTime = (int) $cache->load($loadTimeCacheId);
if (!$data || filemtime('/path/to/your/file') > $loadTime) {
$data = ...; //real loading here
$cache->save($data, $cacheId, array(/*no tags*/), $cacheLength); //save data to cache
$cache->save(time(), $loadTimeCacheId, array(/*no tags*/), $cacheLength); //save load timestamp
}
return $data;
}
Best option is to use Zend_Cache_Frontend_File pointed to your file and Zend_Cache_Backend_Memcached. There is virtually no other option how to store anything in memory than Memcache or APC. It cannot be done without external extension IMO.

MySQL Query Logging in CakePHP

I wanted to know if there is way to log the mysql queries in CakePHP being executed when we use the find method on the models, I know that rails database queries, so does Cake do the same, if so how can I enable it or use it?
Shiv
This page has instructions on how to get Cake to log queries the same way as rails.
A Very simple method to log all the queries being executed:
in your cake\libs\model\datasources\dbo\dbo_mysql.php
find the _execute function:
function _execute($sql) {
return mysql_query($sql, $this->connection);
}
add the line "$this->log($sql);" before "return mysql_query($sql, $this->connection);"
function _execute($sql) {
$this->log($sql);
return mysql_query($sql, $this->connection);
}
That's it!!!!! All your SQL Queries gets logged. Make sure the log file is configured properly and have sufficient permission. Enjoy
Assuming you are on a nix os, the best approach would actually to tail the mysql log itself.
You might learn some interesting things out of it.
log in Ubuntu when installing from repository
tail -f /var/log/mysql/mysql.log
As mentioned below, this is a huge performance killer (well, all logs have some performance impact). So, make sure you use it only on your dev/QA machines and only for short periods on your production machine.
CakePHP 1.3 uses the sql_dump element for that.
You can use the element directly when Configure::read('debug') is set to 2:
echo $this->element('sql_dump');
Or take it's code directly if you need to do something else with it (like echo it from a ShellTask)
$sources = ConnectionManager::sourceList();
$logs = array();
foreach ($sources as $source):
$db =& ConnectionManager::getDataSource($source);
if (!$db->isInterfaceSupported('getLog')):
continue;
endif;
$logs[$source] = $db->getLog();
endforeach;
Echo with e.g.:
print_r($logs)
This is what I use (put it in element folder then include in your layout)
<?php
ob_start();
echo $this->element('sql_dump');
$out = ob_get_contents();
ob_end_clean();
CakeLog::write('mysql' , $out);
?>
then you will find the mysql.log file in TMP.logs.DS.mysql.log

Categories