用于实现文件伪缓存系统的PHP方法

3
这个问题更多关于方法论而非实际代码。我想知道如何在PHP中实现一个“伪缓存”(因为没有更好的名称)来缓存文件。我尝试读了一些文章,但是它们大部分都涉及PHP的内部缓存系统,而不是我需要的文件缓存。
我有几种情况需要应用这样的系统:
场景1:访问帖子并单击链接时,收集所有帖子附件,并将它们添加到zip文件中进行下载。
场景2:访问帖子时,脚本将扫描所有内容,提取所有链接,为每个链接下载某些匹配的图像(或动态准备一个),然后将其提供给浏览器。 (但要检查过期时间吗?)
(这些示例使用“post”和“attachment”,因为我使用的是WordPress,这是WordPress的术语,两者目前对我来说都很好,除了它们一遍又一遍地生成文件。)
我的疑问是关于这两种情况(特别是第二种) - 如何防止脚本每次访问页面时都执行操作?(换句话说,如果文件存在,请直接调用它,而无需再次循环整个创建操作)
我第一个想法是以一些独特(但不唯一)的名称调用文件,然后检查它是否已经存在于服务器上,但这会出现几个问题(例如,它可能已经以该名称存在,但是属于其他帖子...),而且 - 对于一个有20,000张图片的服务器来说,这应该是非常资源密集型的。
第二件事我想到了如何为这些文件关联一个元数据,但是我怎么实现它?如何知道哪个链接对应什么图像?
还有,在检查文件在服务器上是否存在的情况下,如何知道文件是否应更改(因此需要重新创建)?
由于我正在引用WordPress,因此我考虑使用transient API将这些图像从二进制直接存储为Base64存储到数据库中-但感觉很笨拙。
总结一下问题。如何生成文件,并且知道它是否存在并在需要时直接调用它?我的唯一选择是将文件名存储在数据库中,并与帖子相关联吗?那似乎效率不高。
编辑I:我决定包含一些示例代码,因为它可以帮助人们理解我的困境。
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;
} 

这是一个不错的问题 :) 你是否决定要手写解决方案?还是你愿意使用现有的解决方案/库? - asifrc
@asifrc - 我更倾向于不使用现成的解决方案,因为我想理解这个方法,以便在类似情况下能够使用它。就像我在原帖中写的一样,这与代码本身并不那么相关,而是关于方法和方法论。 - Obmerk Kronen
你应该自己编写文件缓存。可以使用filemtime()检查缓存文件是否已经存在且未过期。将其命名为包含描述其唯一内容的所有信息的MD5哈希值。然后,如果存在缓存,则加载缓存,否则生成缓存。定期删除所有过期的缓存。顺便说一句,文件方法比任何数据库访问都要快得多 ;) - ToBe
1个回答

0

对于场景1:

WordPress将所有的文章附件存储为文章在posts表中。当访问一篇文章时,在创建的插件或您的主题functions.php中运行一个函数。使用pre_get_posts钩子检查是否已经使用每个zip归档文件的唯一名称或帖子ID或永久链接创建了zip文件。虽然您需要确保没有用户特定的内容。您可以使用filemtime()来检查文件创建的时间以及它是否仍然相关。如果zip文件不存在,则创建它,pre_get_posts将传递查询对象,其中包含帖子ID,只需使用get_posts获取所有帖子附件,并将父ID设置为传递给查询对象的ID。GUID字段包含每个附件的URL,然后只需使用ZipArchive()生成zip归档文件,按照此tutorial进行操作。

对于方案2: 如果您的WordPress模板已设置为使用WordPress函数,则替换附件函数以返回其URL,并将其映射到您缓存内容的新URL。例如,the_post_thumbnail() 将转到 wp_get_attachment_thumb_url(),将文件复制到缓存中并使用缓存URL作为输出。如果您还想缓存页面的DOM,请使用ob_start()。现在只需在模板开头运行一个检查,使用file_exists和filetime(),如果两者都有效,则读取缓存的DOM而不是加载页面。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接