This question is more about methodology than actual code – lines
I would like to know how to implement a pseudo caching
(for lack of a better name) for FILES in php . I have tried to read some articles, but most of them refer to the internal caching system of PHP , and not to what I need which is a FILE cache.
I have several scenarios where I needed such a system applied :
Scenario 1 :
While accessing a post and clicking a link, all the post attachments are collected and added to a zip file for download.
Scenario 2 :
Accessing a post , the script will scan all the content , extract all links, download some matching images for each link (or dynamically prepare one) and then serve those to browser . (but not after checing expiration period ?? )
( Those example uses "post"
and "attachment"
because i use wordpress and it is wordpress terminology, both currently work for me fine, except they generate the file over and over again. )
My doubts regarding the two scenarios (especially No.2) – How do I prevent the script to do the operation EVERY time the page is accessed ? (in other words , if the file exists , just serve it without looping the whole creating operation again)
My first instinct was call the file with some distinctive (but not load – unique like uniqueid()
) name and then check if it is already on the server , but that presents several problems (like it can already exists as naming , but of another post ..) and also – that should be very resource intensive for a server with 20,000 images .
The second thing I thought was to somehow associate a meta data for those files, but then again, How to implement it ? How to knwo which link is of what image ??
Also, in a case where I check for the file existence on the server , how can I know if the file SHOULD be changed (and therefor recreated ) ?
Since I am refering to wordpress, I thought about storing those images as base64 from binary directly to the DB with the transien_API
– but it feels quite clumsy.
To sum up the question . How to generate a file, but also know if it exists and call it directly when needed ?? does my only option is store the file-name in DB and associate it somehow with the post ?? that seems so non efficient ..
EDIT I
I decided to include some example code , as it can help people to understand my dilemma .
function o99_wbss_prepare_with_callback($content,$width='250'){
$content = preg_replace_callback( '/(http[s]?:[^s]*)/i', 'o99_wbss_prepare_cb', $content );
return $content;
}
function o99_wbss_prepare_cb($match){
$url = $match[1];
$url = esc_url_raw( $url );//someone said not need ??
$url_name = parse_url($url);
$url_name = $url_name['host'];// get rid of http://..
$param = '660';
$url = 'http://somescript/' . urlencode($url) . '?w=' . $param ;
$uploads = wp_upload_dir();
//$uniqid = uniqid();
$img = $uploads['basedir'] . '/tmp/' . $url_name .'.jpg' ; // was with $uniqid...
if(! @ file_get_contents($url)){
$url = 'path ' .$url. ' doesn"t exist or unreachable';
return $url;
} else {
$file = file_get_contents( $url );
}
// here I will need to make some chck if the file already was generated , and
// if so - just serve it ..
if ( $file) {
file_put_contents( $img, $file );
// Do some other operations on the file and prepare a new one ...
// this produces a NEW file in the wp-uploads folder with the same name...
unlink($img);
}
return $url;
}
For Scenario 1:
WordPress stored all post attachments as posts in the posts table. When a post is accessed run a function either in a created plugin or your themes functions.php. Use the pre_get_posts hook check if you have already created the zip file with function file_exists() using a unique name for each zip archive you create, post ID or permalink would be a good idea. Although you would need to make sure there was no user specific content. You can use filemtime() to check the time the file was created and if it is still relevant. If zip file does not exist create it, pre_get_posts will pass the query object which has the the post ID, just grab all the post attachments using get_posts and the parent ID being set to the ID passed in the query object. The GUID field contains the URL for each attachment then just generate a zip archive using ZipArchive() following this tutorial at.
For Scenario 2:
If your wordpress templates are set up to use the wordpress functions then replace the attachment functions to return their url and map that to the new url you have the cached content. For example the_post_thumbnail() would go to wp_get_attachment_thumb_url() copy the file to your cache and use the cache url as output. If you wanted to cache the DOM for the page as well use ob_start(). Now just run a check at the start of the template using file_exists and filetime(), if both are valid read in the cached DOM instead of loading the page.