0

我正在寻找一些关于缓存 php 的信息。我发现的所有信息都是在特定时间间隔(每隔几个小时)缓存一个 php 文件。有没有办法为每 50 个页面视图缓存?每浏览 50 次页面后,缓存文件就会过期。

有人对此有任何想法吗?

先感谢您!

4

2 回答 2

1

这是一个我刚刚放在一起的解决方案,而不是使用基于文件的缓存使用数据库,PDO sqlite(这种方式很容易删除缓存文件数据库以清除所有缓存)。

往底部看,你可以看到它是如何工作的,它会在 50 次点击后删除该行并重定向,这样它就可以生成一个新副本。希望能帮助到你

sqlite.cache.class.php

<?php 
/**
* PDO sqlite cache class
* You can include('sqlite.cache.class.php'); this class
*/
class sqlite_cache{
    private $db;

    function __construct($dsn){
        $this->dsn = $dsn;
        $this->chkSetup();
    }

    /*Singleton Connect*/
    private function connect(){
        if (!$this->db instanceof PDO){
            $this->db = new PDO($this->dsn);
            $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
    }

    /*Raw Select*/
    public function rawSelect($sql){
        $this->connect();
        return $this->db->query($sql)->fetchAll(PDO::FETCH_ASSOC);
    }

    public function get($fieldname=null, $id=null){
        $this->connect();
        $sql = "SELECT * FROM cache WHERE $fieldname = :id";
        $statement = $this->db->prepare($sql);
        $statement->bindParam(':id', $id, PDO::PARAM_STR);
        $statement->execute();
        return $statement->fetchAll(PDO::FETCH_ASSOC);
    }

    /*Insert*/
    public function put($values){
        $this->connect();
        $fieldnames = array_keys($values[0]);
        $sql = "INSERT INTO cache ";
        $fields = '('.implode(' ,', $fieldnames).')';
        $bound = '(:'.implode(', :', $fieldnames).')';
        $sql .= $fields.' VALUES '.$bound;

        $statement = $this->db->prepare($sql);
        foreach($values as $vals){
            $statement->execute($vals);
        }
    }

    /*Update*/
    public function update($fieldname, $value, $pk, $id){
        $this->connect();
        $sql = "UPDATE cache SET $fieldname = :value WHERE $pk = :id";
        $statement = $this->db->prepare($sql);
        $statement->bindParam(':id', $id, PDO::PARAM_STR);
        $statement->bindParam(':value', $value, PDO::PARAM_STR);
        $statement->execute();
    }

    /*Update Hits*/
    public function add_hit($id){
        $this->connect();
        $sql = "UPDATE cache SET hits = hits + 1 WHERE url = :id";
        $statement = $this->db->prepare($sql);
        $statement->bindParam(':id', $id, PDO::PARAM_STR);
        $statement->execute();
    }

    /*Delete*/
    public function delete($id){
        $this->connect();
        $sql = "DELETE FROM cache WHERE url = :id";
        $statement = $this->db->prepare($sql);
        $statement->bindParam(':id', $id, PDO::PARAM_STR);
        $statement->execute();
    }


    /*Database Setup*/
    private function chkSetup(){
        $dso = explode(':',$this->dsn);

        if(file_exists($dso[1])){
            return;
        }else{
            $this->connect();
            //Create Table
            $sql ="CREATE TABLE cache (id INTEGER PRIMARY KEY,
                                            title TEXT,
                                            url TEXT,
                                            hits INTEGER,
                                            date INTEGER,
                                            contents TEXT)";
            $this->db->query($sql);
            header("refresh:0;url=./");
            die;
        }
    }
}
?>

索引.php

<?php
include('sqlite.cache.class.php');
$cache = new sqlite_cache('sqlite:./cache.db');

//Check if cache exists
$cache_result = $cache->get('url',$_SERVER['REQUEST_URI']);
//Exists
if(!empty($cache_result)){
    //Add Hit
    $cache->add_hit($_SERVER['REQUEST_URI']);

    //Delete If over 50 hits
    if($cache_result[0]['hits']>=50){
        $cache->delete($_SERVER['REQUEST_URI']);
        header('Location: '.$_SERVER['REQUEST_URI']);
        die;
    }

    echo $cache_result[0]['contents'];
}else{
    //Generate your page contents ect
    ob_start();

    ///////////////////////////////
    //Your script code goes here
    ///////////////////////////////

    echo 'Your content';

    //End your script code/////////
    ///////////////////////////////
    $return = ob_get_contents();
    ob_end_clean();

    //Before output build values to put in cache
    $cache_contents = array(array('id'=>NULL,
                                  'title'=>'Page Title',
                                  'url'=>$_SERVER['REQUEST_URI'],
                                  'hits'=>'0',
                                  'date'=>time(),
                                  'contents'=>$return));

    //Store cache
    $cache->put($cache_contents);
    echo $return;
}

?>
于 2012-05-26T12:07:28.893 回答
0

您可以采用非常低的技术来解决此问题。

对于您的 URL 的每次点击,您都可以创建一个临时文件作为计数器。使用这样的东西 -

// recursively remove a directory
function rrmdir($dir) {
    foreach(glob($dir . '/*') as $file) {
        if ($file != "." && $file != "..") {
          if(is_dir($file))
            rrmdir($file);
          else
            unlink($file);
        }
    }
    rmdir($dir);
} 



$fileCount = count(glob($tempfile_directory."/*"));
if ($fileCount >= $someLimit){
  rrmdir($tempfile_directory); // clear the counter
  mkdir($tempfile_directory);
  // clear the cached server data and refresh. 
}
touch($tempfile_directory . '/' . time()); // create a new dummy counter file

从 - http://www.php.net/manual/en/function.rmdir.php#108113借来的递归删除函数

当文件数$tempfile_directory大于等于 时$someLimit,文件夹将被清空并刷新缓存数据。

于 2012-05-26T11:48:59.450 回答