跳至內容

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://wikibook.tw/
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://wikibook.tw/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://wikibook.tw/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

參考文獻

[編輯 | 編輯原始碼]


華夏公益教科書