I want to set up a simple cache feature with php. I want the script to get data from somewhere, but not to do it on every page view, but only every hour.
I know i can have a cron job that runs a php script every hour.
But I was wondering if this can be achieved without cron, just inside the php script that created the page based on the data fetched (or cached). I'm really looking the simplest solution possible. It doesn't have to be accurate
I would use APC as well, but in either case you still need some logic. Basic file cache in PHP:
if (file_exists($cache_file) and time() - filemtime($cache_file) < 3600)
{
$content = unserialize(file_get_contents($cache_file));
}
else
{
$content = your_get_content_function_here();
file_put_contents($cache_file, serialize($content));
}
You only need to serialize/unserialize if $content is not a string (e.g. an array or object).
Why just don't use APC ?
you can do
apc_store('yourkey','yourvalue',3600);
And then you can retrive the content with:
apc_fetch();
Related
So, I'm working on a time-sensitive website in PHP on my CentOS server. I have a random time selected in the future, within 24 hours of the present. At that point, I need a PHP file to execute, and a new date to be selected and the same file to be opened. How is this possible to accomplish? I looked briefly at cronjobs, but I couldn't find a way to make them open at a specific, random, time.
You can use at command, run your PHP file and in the end, register make another call to at for the next time. Something like this
<?php
// your PHP code in here, and then find out when is the next call time
$time = date('H:i', intval($time)); // or another good way to make sure time value is safe to use as a shell argument, like using escapeshellarg()
$run_me = "/usr/bin/env php " . __FILE__;
exec("echo '$run_me' | at '$time'");
One possible workaround is to run a script from a cron job, say, every 10 minutes. On the top of the script, check a specific file which is supposed to contain a timestamp. If the current time is greater than the value from the file, do the job, and write the new timestamp value into this file.
$time_to_run = intval(file_get_contents('my.timestamp'));
if(time() >= $time_to_run) {
do stuff
file_put_contents(time() + random value, 'my.timestamp');
}
If you need more granularity, a better option would be to run it as a daemon (see advices here) and just loop forever (probably with some sleep() inside) until the time comes.
I have a php file that returns html based on certain parameters, but it also saves this output in a separate directory (basically a custom made caching process).
Now I want to build a separate php file that automatically updates the cache based on array of known possible parameters.
So I want to "load" or "run" rather than "include" the file several times with the different parameters so that it will save the results in the cache folder.
Is there a php function that will allow me to simply load this other file and perhaps tell me when it is done? If not, do I need to use ajax for something like this or maybe PHP's curl library??
At the present I was thinking about something along the following lines:
<?php
$parameters = array("option1", "option2", "option3");
//loop through parameters and save to cache folder
foreach ($parameters as $parameter){
//get start time to calculate process time
$time_start = microtime(true);
sleep(1);
//I wish there was some function called run or load similar to jquery's 'load'
run("displayindexsearch.php?p=$parameter");
//return total time that it took to run the script and save to cache
$time_end = microtime(true);
$time = $time_end - $time_start;
echo "Process Time: {$time} seconds";
}
?>
why don't you include the file, but create functions for the things you want to do inside the file. That way, at the time when you want to run, you simply call the function. This seems to be the correct way to do what you are trying to do if I understand it correctly.
The best solution I found is to use:
file_get_contents($url)
So where the questions looks for a replacement for run, I substitute file_get_contents($url).
Note that I was getting errors when I used a relative path here. I only had success when I used http://localhost/displayindexsearch.php?p=parameter etc.
Please take a look at this question.
Launch php file from php as background process without exec()
It might be helping for you.
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!
here is my code
echo ("<br/>");
if ($APIkbpersec < 30) {
global $SpeedTest;
echo ("Slow speed");
$SpeedTest--;
}
if ($APIkbpersec > 30) {
global $SpeedTest;
echo ("High speed");
$SpeedTest++;
}
echo $SpeedTest;
the page this code is in gets reloaded every second with AJAX and the $APIkbpersec changes between 40 and 0.
I basically want to have a variable ($SpeedTest) increase or decrese depending on what $APIkbpersec is.
if $APIkbpersec is less than 30, I want $SpeedTest to decrease by 1 every refresh to a minimum of 0.
if $APIkbpersec is greaterthan 30, I want $SpeedTest to increase from by 1 every refresh to a maximum of 10.
the problem is I dont know what the porblem is....Im currently trying to write $SpeedTest to a txt file so I can read it in every refresh to do the maths on it every refresh without it being reset in PHP
any help would be appreciated
It's being reset because the HTTP request is stateless. Each AJAX call is an isolated event to a PHP script. To make the variable persist, it has to be stored in $_SESSION.
You have not shown the code you're using to write it to a text file, but unless you need it to persist beyond a user session, that's the wrong approach. You're better served using $_SESSION. If you do need long-term persistence, you should use a database instead.
session_start();
// Initialize the variable if it doesn't exist yet
if (!isset($_SESSION['SpeedTest'])) {
$_SESSION['SpeedTest'] = 0;
}
echo ("<br/>");
if ($APIkbpersec < 30) {
echo ("Slow speed");
$_SESSION['SpeedTest']--;
}
if ($APIkbpersec > 30) {
echo ("High speed");
$_SESSION['SpeedTest']++;
}
echo $_SESSION['SpeedTest'];
You should use $_SESSION for that purpose.
See HERE for an explanation, but basically you would need to do the following:
session_start();
$SpeedTest = isset($_SESSION['speedTest']) ? $_SESSION['speedTest'] : 0;
if ($APIkbpersec < 30)
{
echo ("Slow speed");
$SpeedTest--;
}
if ($APIkbpersec > 30)
{
echo ("High speed");
$SpeedTest++;
}
$_SESSION['speedTest'] = $SpeedTest;
echo $SpeedTest;
Either:
Return $SpeedTest in the response and pass it back and forth.
Use some kind of persistent storage such as a cookie or PHP sessions.
Both are pretty easy to implement. If you want with persistent storage, I'd suggest a cookie as both JS and PHP could share it. Session, although the obvious candidate, are a bit overkill in this case - IMO.
If this is all of your code, the problem is simple. Each time the script is run, the values of all the variables are initialized. For your case, this means that the value of $SpeedTest does not persist - it's reset to zero each time the script is called. You can use a session as #Michael suggests (probably my recommendation), read the value out from a text file or database and then write a new value out, or you could return the value of $SpeedTest to your AJAX script and pass it back into the php script as a parameter. Each of these have various advantages and disadvantages, but using the $_SESSION superglobal is easy to do and takes little modification to your code.
If you want to do it with files you can use a single file to store a single global value for your variable:
Read data from file (docs here):
$data= file_get_contents('file.txt');
Put data into file (docs here)
$bytesWritten = file_put_contents( $data );
Else you can use sessions or database as other suggested.
Without cookies or sessions you cannot have a real "per user" solution so if you need that stick with other answers or use an hybrid solution with sessions/files
If you use the request solution (that kind of ping-pong with POST or GET variables) always pay attention because those variables can be altered by users.
Other things to remember:
Files and database records last until you delete them (so maybe you have to manage undeleted files or records).
Session duration is configured within your server (so they can last too short if you need long term persistency).
Usually database are better than files (the do more tasks and provide your application more scalability) but in some cases files solution is faster (tested) specially if your database resides in another host and is not on the same host as your webserver.
I have php scripts that call perl scripts to do various things and sometimes I get it where it just goes on and on without getting a response back, this is based on the variable that is being passed to the perl script and I am doing a lot of different ones in succession so I can't get really debug it directly since I don't have a response from perl...
I would really like to just be able to set a php function or block of code to timeout after a certain number of seconds.. I have been searching on this but haven't found anything yet on how to do this,
I was thinking something like this could work but I don't think it would dynamically update the $time variable, but maybe there is a way to get this to work? Any advice is appreciated
$time = time();
$timeout = $time + 5; //just as an example
do {
// do stuff
} while ($time < $timeout)
Your best bet would be to use proc_open, sleep for your timeout amount and then call proc_terminate if the process still hasn't completed.
See http://us3.php.net/manual/en/book.exec.php for details on the proc_* family.
Well, I'm not so sure this question would have an answer based on how I asked it, so what I am going to do is do the perl call where php doesn't wait for a response and have perl write the output to a text file, then have php read this after specified number of seconds, I think this is the simplest way to do this, its just for a small app i am running on a local server