跳转到内容

PHP 编程/缓存

来自维基教科书,开放的书籍,开放的世界

缓存是重复数据的集合,其中原始数据相对于缓存来说,获取或计算的成本很高(通常是访问时间)。在 PHP 中,缓存用于最大限度地减少页面生成时间。

PHP 提供了多种缓存系统[1]

名称 存储的数据 刷新
实例缓存 PHP 对象。例如
if (null === $x) {
    $x = 1;
}
重启脚本(例如:刷新网页)。
会话缓存 PHP 对象[2] 清空浏览器 cookie。
OPcache 操作码[3] opcache_reset();
APCu RAM 用户变量[4] apc_clear_cache();
浏览器缓存 渲染 CTRL + F5
ESI 网页部分 取决于所使用的CDN代理服务器
框架缓存 配置、翻译 例如Symfonyphp bin/console cache:clear清空临时 var/cache 文件。
代理 整个网页 例如,参见:VarnishHAProxy
NoSQL 数据库 键值对 例如,参见:MemcachedRedis
ORM 缓存 注解、SQL 请求或其结果 例如使用Doctrine
php bin/console doctrine:cache:clear-metadata 
php bin/console doctrine:cache:clear-query  
php bin/console doctrine:cache:clear-result

bin/console cache:pool:clear doctrine.query_cache_pool doctrine.result_cache_pool doctrine.system_cache_pool
链式缓存 所有内容 使用每个包含的缓存刷新。

PHP 基本上有两种主要的缓存类型:“输出缓存”和“解析器缓存”。PHP “输出缓存”将一块数据保存到某个地方,以便另一个脚本以后可以比生成它更快地读取它。“解析器缓存”是特定功能。PHP 是一种脚本语言,代码不会被编译或优化到特定的计算机。每个 PHP 文件都必须被解析,这需要时间。这种时间最小化类型是“解析器缓存”。

解析器缓存

[编辑 | 编辑源代码]

包含缓存

[编辑 | 编辑源代码]

示例

文件:class.test.php

<?php
class test
{
    function hello()
    {
        echo "Hello world!\n";
    }
}
echo "Class loaded\n";

文件:program.php

<?php
require_once("class.test.php");
$obj1 = new test;
$obj1->hello();
require_once("class.test.php");
$obj2 = new test;
$obj2->hello();

输出

Class loaded
Hello world!
Hello world!

数组缓存

[编辑 | 编辑源代码]

示例

文件:program.php

<?php
global $sum_cache; 
$sum_cache=array();
function sum($nr)
{
    global $sum_cache;
    
    if (isset($sum_cache[$nr])) {
       echo "sum(".$nr.")=" . $sum_cache[$nr] . " from cache\n";
       return $sum_cache[$nr];
    }

    if ($nr <= 0) {
       $sum_cache[$nr] = 0;
    } else {
       $sum_cache[$nr] = sum($nr - 1) + $nr;
    }

    echo "sum(".$nr.")=" . $sum_cache[$nr] . " computed\n";
    return $sum_cache[$nr];
}
sum(3);
sum(4);

输出

sum(0)=0 computed
sum(1)=1 computed
sum(2)=3 computed
sum(3)=6 computed
sum(3)=6 from cache
sum(4)=10 computed

会话缓存

[编辑 | 编辑源代码]

示例

文件:program.php

<?php
session_start();
function find_my_name()
{
    //perhaps some time-consuming database queries
    return "Bill"; 
}
if (isset($_SESSION["hello"])) {
    echo "cached\n";
    session_destroy();
} else {
    echo "computed\n";
    $_SESSION["hello"] = "My Name is " . find_my_name() . ".\n";
}
echo $_SESSION["hello"];

输出

computed
My Name is Bill.

刷新后的输出

cached
My Name is Bill.

共享变量

[编辑 | 编辑源代码]

示例

文件:program.php

<?php
class test
{
    var $list = array();

    function load_list()
    {
        // some less time consuming database queries
        $this->list[0]["info"] = "small info nr 1";
        $this->list[1]["info"] = "small info nr 2";
        $this->list[2]["info"] = "small info nr 3";
    }

    function load_element_detail(&$data)
    {
        // some very time consuming database queries
        $data["big"] = "added big info, maybe structure of objects";
    }

    function get_element($nr)
    {
        return $this->list[$nr];
    }

    function print_element($nr)
    {
        echo "this->list[${nr}]['info'] = '" . $this->list[$nr]['info'] . "'\n";
        echo "this->list[${nr}]['big']  = '" . $this->list[$nr]['big'] . "'\n";
    }
}

$obj = new test;

$obj->load_list();
$obj->print_element(0);

$element = &$obj->get_element(0);

$obj->load_element_detail($element);
$obj->print_element(0);

输出

$this->list[0]["info"]="small info nr 1"
$this->list[0]["big"]=""
$this->list[0]["info"]="small info nr 1"
$this->list[0]["big"]="added big info, maybe structure of objects"

输出缓存

[编辑 | 编辑源代码]

服务器缓存策略包含在HTTP 头部中,可以通过cURL(使用选项“I”查看头部)查看。

curl -I http://example.org

示例

curl -I https://wikibooks.cn/
HTTP/2 301 
date: Sun, 02 Jan 2022 11:50:58 GMT
server: mw1429.eqiad.wmnet
x-content-type-options: nosniff
p3p: CP="See https://wikibooks.cn/wiki/Special:CentralAutoLogin/P3P for more info."
vary: Accept-Encoding,X-Forwarded-Proto,Cookie,Authorization
cache-control: s-maxage=1200, must-revalidate, max-age=0
last-modified: Sun, 02 Jan 2022 11:50:58 GMT
location: https://wikibooks.cn/wiki/Main_Page
content-length: 0
content-type: text/html; charset=utf-8
age: 1139
x-cache: cp3062 miss, cp3060 hit/4
x-cache-status: hit-front
server-timing: cache;desc="hit-front", host;desc="cp3060"
strict-transport-security: max-age=106384710; includeSubDomains; preload
report-to: { "group": "wm_nel", "max_age": 86400, "endpoints": [{ "url": "https://intake-logging.wikimedia.org/v1/events?stream=w3c.reportingapi.network_error&schema_uri=/w3c/reportingapi/network_error/1.0.0" }] }
nel: { "report_to": "wm_nel", "max_age": 86400, "failure_fraction": 0.05, "success_fraction": 0.0}
permissions-policy: interest-cohort=()
set-cookie: WMF-Last-Access=02-Jan-2022;Path=/;HttpOnly;secure;Expires=Thu, 03 Feb 2022 12:00:00 GMT
set-cookie: WMF-Last-Access-Global=02-Jan-2022;Path=/;Domain=.wikibooks.org;HttpOnly;secure;Expires=Thu, 03 Feb 2022 12:00:00 GMT

参考资料

[编辑 | 编辑源代码]


华夏公益教科书