在PHP mvc中缓存查询和构建页面是否可以接受?

在PHP mvc中缓存查询和构建页面是否可以接受?,php,oop,caching,model-view-controller,Php,Oop,Caching,Model View Controller,下面的代码是否显示了缓存完全构建的页面和数据库查询的可接受方法 内置页面的缓存从控制器中的\uuuu构造开始,然后通过\uuu析构函数完成,在此示例中,所有页面默认缓存15分钟到一个文件 查询缓存是使用apc完成的,它们存储在内存中的时间长度为每个查询指定的时间。在实际站点中,apc缓存将有另一个类,以便在需要时对其进行更改 我的目标是构建最简单的mvc,我失败了吗,还是走上了正确的轨道 控制器 //config //autoloader //initialiser - class cont

下面的代码是否显示了缓存完全构建的页面和数据库查询的可接受方法

内置页面的缓存从控制器中的
\uuuu构造开始,然后通过
\uuu析构函数完成,在此示例中,所有页面默认缓存15分钟到一个文件

查询缓存是使用
apc
完成的,它们存储在内存中的时间长度为每个查询指定的时间。在实际站点中,apc缓存将有另一个类,以便在需要时对其进行更改

我的目标是构建最简单的mvc,我失败了吗,还是走上了正确的轨道

控制器

//config
//autoloader
//initialiser - 

class controller {

    var $cacheUrl;

    function __construct(){

        $cacheBuiltPage = new cache();
        $this->cacheUrl = $cacheBuiltPage->startFullCache();
    }

    function __destruct(){

        $cacheBuiltPage = new cache();
        $cacheBuiltPage->endFullCache($this->cacheUrl);
    }
}

class forumcontroller extends controller{

    function buildForumThread(){

        $threadOb = new thread();
        $threadTitle = $threadOb->getTitle($data['id']);

        require 'thread.php';
    }
}
型号

class thread extends model{

    public function getTitle($threadId){

        $core = Connect::getInstance();
        $data = $core->dbh->selectQuery("SELECT title FROM table WHERE id = 1");

        return $data;
    }
}
数据库

class database {

    public $dbh;
    private static $dsn  = "mysql:host=localhost;dbname=";
    private static $user = "";
    private static $pass = '';  
    private static $instance;

    private function __construct () {
        $this->dbh = new PDO(self::$dsn, self::$user, self::$pass);
    }

    public static function getInstance(){
        if(!isset(self::$instance)){
            $object =  __CLASS__;   
            self::$instance = new $object;
        }
        return self::$instance;
    }

    public function selectQuery($sql, $time = 0) {

        $key = md5('query'.$sql);

        if(($data = apc_fetch($key)) === false) {

            $stmt = $this->dbh->query($sql);
            $data = $stmt->fetchAll();

            apc_store($key, $data, $time);
        }
        return $data;
    }
}
class cache{

    var url;

    public function startFullCache(){

        $this->url = 'cache/'.md5($_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING']);   

        if((@filesize($this->url) > 1) && (time() - filectime($this->url)) < (60 * 15)){
            readfile($this->url);
            exit;
        }

        ob_start();

        return $this->url;
    }

    public function endFullCache($cacheUrl){

        $output = ob_get_contents();
        ob_end_clean();

        $output = sanitize_output($output);

        file_put_contents($cacheUrl, $output);

        echo $output;
        flush();
    }

}
缓存

class database {

    public $dbh;
    private static $dsn  = "mysql:host=localhost;dbname=";
    private static $user = "";
    private static $pass = '';  
    private static $instance;

    private function __construct () {
        $this->dbh = new PDO(self::$dsn, self::$user, self::$pass);
    }

    public static function getInstance(){
        if(!isset(self::$instance)){
            $object =  __CLASS__;   
            self::$instance = new $object;
        }
        return self::$instance;
    }

    public function selectQuery($sql, $time = 0) {

        $key = md5('query'.$sql);

        if(($data = apc_fetch($key)) === false) {

            $stmt = $this->dbh->query($sql);
            $data = $stmt->fetchAll();

            apc_store($key, $data, $time);
        }
        return $data;
    }
}
class cache{

    var url;

    public function startFullCache(){

        $this->url = 'cache/'.md5($_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING']);   

        if((@filesize($this->url) > 1) && (time() - filectime($this->url)) < (60 * 15)){
            readfile($this->url);
            exit;
        }

        ob_start();

        return $this->url;
    }

    public function endFullCache($cacheUrl){

        $output = ob_get_contents();
        ob_end_clean();

        $output = sanitize_output($output);

        file_put_contents($cacheUrl, $output);

        echo $output;
        flush();
    }

}
类缓存{
var-url;
公共函数startFullCache(){
$this->url='cache/'.md5($\u SERVER['PHP\u SELF'].$\u SERVER['QUERY\u STRING']);
如果(@filesize($this->url)>1)和(&(time()-filectime($this->url))<(60*15)){
readfile($this->url);
出口
}
ob_start();
返回$this->url;
}
公共函数endFullCache($cacheUrl){
$output=ob_get_contents();
ob_end_clean();
$output=消毒输出($output);
文件内容($cacheUrl,$output);
echo$输出;
冲洗();
}
}
查看

<html>
<head>
<title><?=$threadTitle[0]?> Thread - Website</title>
</head>
<body>

    <h1><?=$threadTitle[0]?> Thread</h1>

</body>
</html>

线程-网站
线

这完全取决于性能问题所在。如果它们在您的DB查询中,那么缓存它们——当然,您的控制器需要为脏数据做好准备

如果您要在控制器层缓存内容,那么性能会更好,但您可能需要缓存更多的内容(您的DB数据将小于HTML)。当然,用户需要做好看到脏数据的准备

不幸的是,由于每个解决方案都有不同的需求,所以您不能真正拥有任何硬性规则。我的建议是,只有在确实需要的时候才开始缓存数据。仔细查看性能瓶颈所在,适当地进行缓存,确保可以向外扩展(更多机器),而不仅仅是向上扩展(增加机器规格)。

更新 这是在PHP mvc中缓存查询和构建页面的一种可接受的方式吗?

内置页面的缓存从控制器中的_构造开始,然后用_析构函数结束,在本例中,所有页面都会缓存到一个文件中,默认时间为15分钟

释放所有引用或脚本终止时,将调用析构函数。我假设这意味着脚本正确终止时。我想说,关键异常不能保证调用析构函数

比如说

 class A 
 {
    public function __construct()
    {
       echo "Construct\n";
    }

    public function __destruct()
    {
      echo "Destruct\n";
    }
 }
测试代码:

   $test = new A();
    die( "Dead\n");  // Will output Construct; dead; Destruct

   $test = new A();
   throw new Exception("Blah\n"); // Construct, Fatal error (no destruct)

   $test = new A();
   require_once( 'invalid_file.php'); // Construct, Fatal error (no destruct)
你最好还是去确定一下。但是要小心

可以多次调用register_shutdown_function(),每次调用的顺序与注册的顺序相同。如果在一个已注册的关闭函数中调用exit(),处理将完全停止,并且不会调用其他已注册的关闭函数。“如果其他关闭函数在您的关闭函数之前运行,则无法保证会调用您的关闭函数。”

嗯,你正在重新发明轮子,现在已经有很多框架了。你想要一个简单的小框架吗?是的

这是由创造Symfony的同一个人制作的相信我你会浪费时间的

或者为什么不尝试使用Laravel您可以只选择您想要的包,而不是所有的框架 他们已经有了一个设计良好的缓存系统,请参见

要理解如何在MVC风格的Symfony2文档中正确地进行缓存,需要

也读这个问题

根据我的经验,除非你希望有大量的用户(比如说,你的网站上同时有几十个以上的用户)另一方面,如果没有经过深思熟虑的缓存策略,像StackOverflow这样的站点将无法正常运行


正如我从你的问题中了解到的,你想缓存整个页面吗

How would you create a build function to cache the entire built page?
您可以简单地使用输出缓冲来实现这一点

例如,您有index.php代码:

<?php

 ob_start();   

 // All your mvc and application logic here

 $output = ob_get_contents();
 ob_end_clean();

我添加了CodingSane发布的内容

他是对的,这样你就可以轻松地创建自己的小缓存机制

只需将$output的内容(在CodingInsane post中)写入一个类似以下的文件:theu file.php.cache 下次在_file.php中读取_file.php.cache的内容,并将其显示给用户并退出

但是,任何缓存机制都需要一种更新(重建页面)的方法。为此,您只需跟踪内容是否已更改,或者检查内容上次更改的时间,并将其与上次修改\u file.php.cache filemtime()的时间进行比较

祝你好运!

“外包”缓存 首先,您必须了解,
GET
请求的缓存通常在整个互联网上完成,尤其是当您的用户通过某种代理进行连接时

此外,还可以设置长过期时间,以便用户的浏览器对HTML页面和/或媒体文件进行缓存

要开始了解这一点,您应该阅读文章

你的目标是什么? 在您开始尝试添加缓存之前,请确保您确实需要它。进行一些基准测试,并查看您的瓶颈是什么。为了优化而进行优化是毫无意义的,而且通常是有害的

如果您知道(并且有数据来备份它,..这不是“感觉”)您的应用程序正在进行太多的SQL查询,而不是跳跃