12

每次有人登陆我的页面list.php?id=xxxxx时,它都会请求一些 MySQL 查询来返回:

$ids = array(..,..,..); // not big array - not longer then 50 number records
$thumbs = array(..,..,..); // not big array - not longer then 50 text records
$artdesc = "some text not very long"; // text field

因为我从中进行查询的数据库非常大,所以我想将此结果缓存 24 小时,可能是一个文件,例如:xxxxx.php在 /cache/ 目录中,这样我可以在include("xxxxx.php")它存在时使用它。(或txt文件!?,或任何其他方式)

因为有非常简单的数据,我相信只需要几行PHP就可以完成,不需要使用memcached或其他专业对象。

因为我的 PHP 非常有限,有人可以为这个任务放置 PHP 主线(或代码)吗?

我真的会非常感激!

4

3 回答 3

8

缓存 PHP 数组非常简单:

file_put_contents($path, '<?php return '.var_export($my_array,true).';?>');

然后你可以把它读回来:

if (file_exists($path)) $my_array = include($path);

您可能还想查看 ADOdb,它在内部提供缓存。

于 2013-04-01T15:24:03.577 回答
5

尝试使用序列化;

假设您在两个数组中获取数据,$array1并且$array2. 现在您要做的就是将这些数组存储在文件中。将字符串(问题中的第三个变量)存储到文件很容易,但是要存储数组,您必须首先将其转换为字符串。

$string_of_array1 = serialize( $array1 );
$string_of_array2 = serialize( $array2 );

下一个问题是缓存文件的命名,以便您可以轻松检查相关数组是否已在缓存中可用。最好的方法是创建 mysql 查询的 MD5 哈希并将其用作缓存文件名。

$cache_dir = '/path/cache/';

$query1 = 'SELECT many , fields FROM first_table INNER JOIN another_table ...';
$cache1_filename = md5( $query1 );

if( file_exists( $cache_dir . $cache1_filename ) )
{
    if( filemtime( $cache_dir . $cache1_filename ) > ( time( ) - 60 * 60 * 24 ) )
    {
        $array1 = unserialize( file_get_contents( $cache_dir . $cache1_filename ) );
    }
}

if( !isset( $array1 ) )
{
    $array1 = run_mysql_query( $query1 );
    file_put_contents( serialize( $array1 ) );
}

对应该存储在单独文件中的另一个数组重复上述操作,并将第二个查询的 MD5 用作第二个缓存文件的名称。

最后,您必须决定您的缓存应该保持有效多长时间。对于同一个查询,你的 mysql 表中可能有更改记录,这可能会使你的文件系统缓存过时。因此,您不能仅仅依靠唯一的文件名来进行唯一的查询。

重要的:

  • 必须删除旧的缓存文件。您可能必须编写一个例程来检查目录中的所有文件并删除早于 n 秒的文件。
  • 将缓存目录保留在 webroot 之外。
于 2013-04-01T17:40:15.343 回答
0

只需使用 $_GET['id'] 的名称和要缓存的内容的内容编写一个新文件,每次检查该文件是否存在,否则创建一个。像这样的东西:

$id = $_GET['id']

if (file_exists('/a/dir/' . $id)) {
  $data = file_get_contents('/a/dir/' . $id);
} else {
  //do mysql query, set data to result
  $handle = fopen('/a/dir/' . $id, 'w+');
  fwrite($handle, $data);
  fclose($handle);
}
于 2013-04-01T15:26:42.167 回答