0 追蹤者

類別 yii\filters\HttpCache

繼承關係yii\filters\HttpCache » yii\base\ActionFilter » yii\base\Behavior » yii\base\BaseObject
實作yii\base\Configurable
自版本起可用2.0
原始碼 https://github.com/yiisoft/yii2/blob/master/framework/filters/HttpCache.php

HttpCache 透過使用 Last-ModifiedETag HTTP 標頭實作用戶端快取。

它是一個動作篩選器,可以添加到控制器並處理 beforeAction 事件。

要使用 HttpCache,請在控制器類別的 behaviors() 方法中宣告它。在以下範例中,篩選器將應用於 index 動作,而 Last-Modified 標頭將包含資料庫中使用者表格上次更新的日期。

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\HttpCache',
            'only' => ['index'],
            'lastModified' => function ($action, $params) {
                $q = new \yii\db\Query();
                return $q->from('user')->max('updated_at');
            },
//            'etagSeed' => function ($action, $params) {
//                return // generate ETag seed here
//            }
        ],
    ];
}

公開屬性

隱藏繼承的屬性

屬性 類型 描述 定義於
$cacheControlHeader string|null Cache-Control HTTP 標頭的值。 yii\filters\HttpCache
$enabled boolean 指示是否應啟用此篩選器的值。 yii\filters\HttpCache
$etagSeed callable 產生 ETag 種子字串的 PHP 回呼。 yii\filters\HttpCache
$except array 此篩選器不應應用於的動作 ID 清單。 yii\base\ActionFilter
$lastModified callable 傳回上次修改時間的 UNIX 時間戳記的 PHP 回呼。 yii\filters\HttpCache
$only array 此篩選器應應用於的動作 ID 清單。 yii\base\ActionFilter
$owner yii\base\Component|null 此行為的所有者 yii\base\Behavior
$params mixed 應傳遞給 $lastModified$etagSeed 回呼的額外參數。 yii\filters\HttpCache
$sessionCacheLimiter string|null 呼叫 session_cache_limiter() 時要設定的快取限制器的名稱。 yii\filters\HttpCache
$weakEtag boolean 是否產生弱 ETag。 yii\filters\HttpCache

公開方法

隱藏繼承的方法

方法 描述 定義於
__call() 呼叫非類別方法的具名方法。 yii\base\BaseObject
__construct() 建構子。 yii\base\BaseObject
__get() 傳回物件屬性的值。 yii\base\BaseObject
__isset() 檢查屬性是否已設定,即已定義且非 null。 yii\base\BaseObject
__set() 設定物件屬性的值。 yii\base\BaseObject
__unset() 將物件屬性設定為 null。 yii\base\BaseObject
afterAction() 此方法在動作執行後立即調用。 yii\base\ActionFilter
afterFilter() yii\base\ActionFilter
attach() 將行為物件附加到組件。 yii\base\ActionFilter
beforeAction() 此方法會在動作即將執行前(在所有可能的篩選器之後)被調用。您可以覆寫此方法,以便為動作執行最後一刻的準備。 yii\filters\HttpCache
beforeFilter() yii\base\ActionFilter
canGetProperty() 傳回一個值,指示是否可以讀取屬性。 yii\base\BaseObject
canSetProperty() 傳回一個值,指示是否可以設定屬性。 yii\base\BaseObject
className() 傳回此類別的完整限定名稱。 yii\base\BaseObject
detach() 從元件分離行為物件。 yii\base\ActionFilter
events() 宣告 $owner 事件的事件處理器。 yii\base\Behavior
hasMethod() 傳回一個值,指示是否已定義方法。 yii\base\BaseObject
hasProperty() 傳回一個值,指示是否已定義屬性。 yii\base\BaseObject
init() 初始化物件。 yii\base\BaseObject

Protected Methods

隱藏繼承的方法

方法 描述 定義於
generateEtag() 從給定的種子字串產生 ETag。 yii\filters\HttpCache
getActionId() 透過將 yii\base\Action::$uniqueId 轉換為相對於模組的 ID,傳回動作 ID。 yii\base\ActionFilter
isActive() 傳回一個值,指示篩選器是否對給定的動作處於啟用狀態。 yii\base\ActionFilter
sendCacheControlHeader() 將快取控制標頭傳送至用戶端。 yii\filters\HttpCache
validateCache() 驗證 HTTP 快取是否包含有效內容。 yii\filters\HttpCache

Property Details

隱藏繼承的屬性

$cacheControlHeader public property

Cache-Control HTTP 標頭的值。如果為 null,則不會傳送標頭。

另請參閱 https://datatracker.ietf.org/doc/html/rfc2616#section-14.9

public string|null $cacheControlHeader 'public, max-age=3600'
$enabled public property

指示是否應啟用此篩選器的值。

public boolean $enabled true
$etagSeed public property

一個 PHP 回呼函數,用於產生 ETag 種子字串。回呼函數的簽名應為

function ($action, $params)

其中 $action 是此篩選器目前正在處理的 yii\base\Action 物件;$params 採用 $params 的值。回呼函數應傳回一個字串,作為產生 ETag 的種子。

public callable $etagSeed null
$lastModified public property

一個 PHP 回呼函數,用於傳回上次修改時間的 UNIX 時間戳記。回呼函數的簽名應為

function ($action, $params)

其中 $action 是此篩選器目前正在處理的 yii\base\Action 物件;$params 採用 $params 的值。回呼函數應傳回一個 UNIX 時間戳記。

另請參閱 https://datatracker.ietf.org/doc/html/rfc7232#section-2.2

public callable $lastModified null
$params public property

應傳遞給 $lastModified$etagSeed 回呼的額外參數。

public mixed $params null
$sessionCacheLimiter public property

當呼叫 session_cache_limiter() 時,要設定的快取限制器名稱。預設值為空字串,表示完全關閉自動傳送快取標頭。您可以將此屬性設定為 publicprivateprivate_no_expirenocache。請參閱 session_cache_limiter() 以取得這些值的詳細說明。

如果此屬性為 null,則不會呼叫 session_cache_limiter()。因此,PHP 將根據 session.cache_limiter PHP ini 設定傳送標頭。

$weakEtag public property (自版本 2.0.8 起可用)

是否產生弱 ETag。

如果內容在語義上應被視為等效,但在位元組上不相等,則應使用弱 ETag。

另請參閱 https://datatracker.ietf.org/doc/html/rfc7232#section-2.3

public boolean $weakEtag false

Method Details

隱藏繼承的方法

__call() public method

定義於: yii\base\BaseObject::__call()

呼叫非類別方法的具名方法。

請勿直接呼叫此方法,因為它是一個 PHP 魔術方法,當調用未知方法時,它會被隱式呼叫。

public mixed __call ( $name, $params )
$name string

方法名稱

$params array

Method parameters

return mixed

方法傳回值

throws yii\base\UnknownMethodException

當呼叫未知方法時

                public function __call($name, $params)
{
    throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}

            
__construct() public method

定義於: yii\base\BaseObject::__construct()

建構子。

預設實作會執行兩件事

  • 使用給定的配置 $config 初始化物件。
  • 呼叫 init()

如果在子類別中覆寫此方法,建議

  • 建構子的最後一個參數是一個配置陣列,例如此處的 $config
  • 在建構子的結尾呼叫父類別實作。
public void __construct ( $config = [] )
$config array

將用於初始化物件屬性的名稱-值對

                public function __construct($config = [])
{
    if (!empty($config)) {
        Yii::configure($this, $config);
    }
    $this->init();
}

            
__get() public method

定義於: yii\base\BaseObject::__get()

傳回物件屬性的值。

請勿直接呼叫此方法,因為它是一個 PHP 魔術方法,當執行 $value = $object->property; 時,它會被隱式呼叫。

另請參閱 __set()

public mixed __get ( $name )
$name string

屬性名稱

return mixed

屬性值

throws yii\base\UnknownPropertyException

如果未定義屬性

throws yii\base\InvalidCallException

如果屬性為唯寫

                public function __get($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter();
    } elseif (method_exists($this, 'set' . $name)) {
        throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
    }
    throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}

            
__isset() public method

定義於: yii\base\BaseObject::__isset()

檢查屬性是否已設定,即已定義且非 null。

請勿直接呼叫此方法,因為它是一個 PHP 魔術方法,當執行 isset($object->property) 時,它會被隱式呼叫。

請注意,如果未定義屬性,將傳回 false。

另請參閱 https://php.dev.org.tw/manual/en/function.isset.php

public boolean __isset ( $name )
$name string

屬性名稱或事件名稱

return boolean

具名屬性是否已設定(非 null)。

                public function __isset($name)
{
    $getter = 'get' . $name;
    if (method_exists($this, $getter)) {
        return $this->$getter() !== null;
    }
    return false;
}

            
__set() public method

定義於: yii\base\BaseObject::__set()

設定物件屬性的值。

請勿直接呼叫此方法,因為它是一個 PHP 魔術方法,當執行 $object->property = $value; 時,它會被隱式呼叫。

另請參閱 __get()

public void __set ( $name, $value )
$name string

屬性名稱或事件名稱

$value mixed

屬性值

throws yii\base\UnknownPropertyException

如果未定義屬性

throws yii\base\InvalidCallException

如果屬性為唯讀

                public function __set($name, $value)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter($value);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name);
    } else {
        throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name);
    }
}

            
__unset() public method

定義於: yii\base\BaseObject::__unset()

將物件屬性設定為 null。

請勿直接呼叫此方法,因為它是一個 PHP 魔術方法,當執行 unset($object->property) 時,它會被隱式呼叫。

請注意,如果未定義屬性,此方法將不執行任何操作。如果屬性為唯讀,它將拋出例外。

另請參閱 https://php.dev.org.tw/manual/en/function.unset.php

public void __unset ( $name )
$name string

屬性名稱

throws yii\base\InvalidCallException

如果屬性為唯讀。

                public function __unset($name)
{
    $setter = 'set' . $name;
    if (method_exists($this, $setter)) {
        $this->$setter(null);
    } elseif (method_exists($this, 'get' . $name)) {
        throw new InvalidCallException('Unsetting read-only property: ' . get_class($this) . '::' . $name);
    }
}

            
afterAction() public method

定義於: yii\base\ActionFilter::afterAction()

此方法在動作執行後立即調用。

您可以覆寫此方法,以便為動作執行一些後續處理。

public mixed afterAction ( $action, $result )
$action yii\base\Action

剛執行的動作。

$result mixed

動作執行結果

return mixed

已處理的動作結果。

                public function afterAction($action, $result)
{
    return $result;
}

            
afterFilter() public method
public void afterFilter ( $event )
$event yii\base\ActionEvent

                public function afterFilter($event)
{
    $event->result = $this->afterAction($event->action, $event->result);
    $this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']);
}

            
attach() public method

定義於: yii\base\ActionFilter::attach()

將行為物件附加到組件。

預設實作將設定 $owner 屬性,並附加在 events() 中宣告的事件處理器。如果您覆寫此方法,請確保呼叫父類別實作。

public void attach ( $owner )
$owner yii\base\Component

此行為要附加到的元件。

                public function attach($owner)
{
    $this->owner = $owner;
    $owner->on(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']);
}

            
beforeAction() public method

此方法會在動作即將執行前(在所有可能的篩選器之後)被調用。您可以覆寫此方法,以便為動作執行最後一刻的準備。

public boolean beforeAction ( $action )
$action yii\base\Action

要執行的動作。

return boolean

是否應繼續執行動作。

                public function beforeAction($action)
{
    if (!$this->enabled) {
        return true;
    }
    $verb = Yii::$app->getRequest()->getMethod();
    if ($verb !== 'GET' && $verb !== 'HEAD' || $this->lastModified === null && $this->etagSeed === null) {
        return true;
    }
    $lastModified = $etag = null;
    if ($this->lastModified !== null) {
        $lastModified = call_user_func($this->lastModified, $action, $this->params);
    }
    if ($this->etagSeed !== null) {
        $seed = call_user_func($this->etagSeed, $action, $this->params);
        if ($seed !== null) {
            $etag = $this->generateEtag($seed);
        }
    }
    $this->sendCacheControlHeader();
    $response = Yii::$app->getResponse();
    if ($etag !== null) {
        $response->getHeaders()->set('Etag', $etag);
    }
    $cacheValid = $this->validateCache($lastModified, $etag);
    // https://tools.ietf.org/html/rfc7232#section-4.1
    if ($lastModified !== null && (!$cacheValid || ($cacheValid && $etag === null))) {
        $response->getHeaders()->set('Last-Modified', gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
    }
    if ($cacheValid) {
        $response->setStatusCode(304);
        return false;
    }
    return true;
}

            
beforeFilter() public method
public void beforeFilter ( $event )
$event yii\base\ActionEvent

                public function beforeFilter($event)
{
    if (!$this->isActive($event->action)) {
        return;
    }
    $event->isValid = $this->beforeAction($event->action);
    if ($event->isValid) {
        // call afterFilter only if beforeFilter succeeds
        // beforeFilter and afterFilter should be properly nested
        $this->owner->on(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter'], null, false);
    } else {
        $event->handled = true;
    }
}

            
canGetProperty() public method

定義於: yii\base\BaseObject::canGetProperty()

傳回一個值,指示是否可以讀取屬性。

如果屬性可讀取,條件如下:

  • 類別具有與指定名稱關聯的 getter 方法(在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數(當 $checkVars 為 true 時);

另請參閱 canSetProperty()

public boolean canGetProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否可以讀取

                public function canGetProperty($name, $checkVars = true)
{
    return method_exists($this, 'get' . $name) || $checkVars && property_exists($this, $name);
}

            
canSetProperty() public method

定義於: yii\base\BaseObject::canSetProperty()

傳回一個值,指示是否可以設定屬性。

如果屬性可寫入,條件如下:

  • 類別具有與指定名稱關聯的 setter 方法(在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數(當 $checkVars 為 true 時);

另請參閱 canGetProperty()

public boolean canSetProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否可以寫入

                public function canSetProperty($name, $checkVars = true)
{
    return method_exists($this, 'set' . $name) || $checkVars && property_exists($this, $name);
}

            
className() public static method
自 2.0.14 版本起已棄用。在 PHP >=5.5 上,請改用 ::class

定義於: yii\base\BaseObject::className()

傳回此類別的完整限定名稱。

public static string className ( )
return string

此類別的完整限定名稱。

                public static function className()
{
    return get_called_class();
}

            
detach() public method

定義於: yii\base\ActionFilter::detach()

從元件分離行為物件。

預設實作將取消設定 $owner 屬性,並分離在 events() 中宣告的事件處理器。如果您覆寫此方法,請確保呼叫父類別實作。

public void detach ( )

                public function detach()
{
    if ($this->owner) {
        $this->owner->off(Controller::EVENT_BEFORE_ACTION, [$this, 'beforeFilter']);
        $this->owner->off(Controller::EVENT_AFTER_ACTION, [$this, 'afterFilter']);
        $this->owner = null;
    }
}

            
events() public method

定義於: yii\base\Behavior::events()

宣告 $owner 事件的事件處理器。

子類別可以覆寫此方法,以宣告應附加到 $owner 元件事件的 PHP 回呼函數。

當行為附加到擁有者時,回呼函數將附加到 $owner 的事件;當行為從元件分離時,它們將從事件中分離。

回呼函數可以是下列任何一種

  • 此行為中的方法:'handleClick',等效於 [$this, 'handleClick']
  • 物件方法:[$object, 'handleClick']
  • 靜態方法:['Page', 'handleClick']
  • 匿名函數:function ($event) { ... }

以下是一個範例

[
    Model::EVENT_BEFORE_VALIDATE => 'myBeforeValidate',
    Model::EVENT_AFTER_VALIDATE => 'myAfterValidate',
]
public array events ( )
return array

事件(陣列鍵)和對應的事件處理器方法(陣列值)。

                public function events()
{
    return [];
}

            
generateEtag() protected method

從給定的種子字串產生 ETag。

protected string generateEtag ( $seed )
$seed string

ETag 的種子

return string

產生的 ETag

                protected function generateEtag($seed)
{
    $etag = '"' . rtrim(base64_encode(sha1($seed, true)), '=') . '"';
    return $this->weakEtag ? 'W/' . $etag : $etag;
}

            
getActionId() protected method (自版本 2.0.7 起可用)

定義於: yii\base\ActionFilter::getActionId()

透過將 yii\base\Action::$uniqueId 轉換為相對於模組的 ID,傳回動作 ID。

protected string getActionId ( $action )
$action yii\base\Action

                protected function getActionId($action)
{
    if ($this->owner instanceof Module) {
        $mid = $this->owner->getUniqueId();
        $id = $action->getUniqueId();
        if ($mid !== '' && strpos($id, $mid) === 0) {
            $id = substr($id, strlen($mid) + 1);
        }
    } else {
        $id = $action->id;
    }
    return $id;
}

            
hasMethod() public method

定義於: yii\base\BaseObject::hasMethod()

傳回一個值,指示是否已定義方法。

預設實作是對 php 函數 method_exists() 的呼叫。當您實作 php 魔術方法 __call() 時,可以覆寫此方法。

public boolean hasMethod ( $name )
$name string

方法名稱

return boolean

方法是否已定義

                public function hasMethod($name)
{
    return method_exists($this, $name);
}

            
hasProperty() public method

定義於: yii\base\BaseObject::hasProperty()

傳回一個值,指示是否已定義屬性。

屬性已定義如果

  • 類別具有與指定名稱相關聯的 getter 或 setter 方法(在這種情況下,屬性名稱不區分大小寫);
  • 類別具有具有指定名稱的成員變數(當 $checkVars 為 true 時);

參見

public boolean hasProperty ( $name, $checkVars true )
$name string

屬性名稱

$checkVars boolean

是否將成員變數視為屬性

return boolean

屬性是否已定義

                public function hasProperty($name, $checkVars = true)
{
    return $this->canGetProperty($name, $checkVars) || $this->canSetProperty($name, false);
}

            
init() public method

定義於: yii\base\BaseObject::init()

初始化物件。

此方法在建構子結束時調用,在物件使用給定的配置初始化之後。

public void init ( )

                public function init()
{
}

            
isActive() protected method

定義於: yii\base\ActionFilter::isActive()

傳回一個值,指示篩選器是否對給定的動作處於啟用狀態。

protected boolean isActive ( $action )
$action yii\base\Action

正在被過濾的 action

return boolean

篩選器是否對於給定的 action 為啟用狀態。

                protected function isActive($action)
{
    $id = $this->getActionId($action);
    if (empty($this->only)) {
        $onlyMatch = true;
    } else {
        $onlyMatch = false;
        foreach ($this->only as $pattern) {
            if (StringHelper::matchWildcard($pattern, $id)) {
                $onlyMatch = true;
                break;
            }
        }
    }
    $exceptMatch = false;
    foreach ($this->except as $pattern) {
        if (StringHelper::matchWildcard($pattern, $id)) {
            $exceptMatch = true;
            break;
        }
    }
    return !$exceptMatch && $onlyMatch;
}

            
sendCacheControlHeader() protected method

將快取控制標頭傳送至用戶端。

參見 $cacheControlHeader

protected void sendCacheControlHeader ( )

                protected function sendCacheControlHeader()
{
    if ($this->sessionCacheLimiter !== null) {
        if ($this->sessionCacheLimiter === '' && !headers_sent() && Yii::$app->getSession()->getIsActive()) {
            header_remove('Expires');
            header_remove('Cache-Control');
            header_remove('Last-Modified');
            header_remove('Pragma');
        }
        Yii::$app->getSession()->setCacheLimiter($this->sessionCacheLimiter);
    }
    $headers = Yii::$app->getResponse()->getHeaders();
    if ($this->cacheControlHeader !== null) {
        $headers->set('Cache-Control', $this->cacheControlHeader);
    }
}

            
validateCache() protected method

驗證 HTTP 快取是否包含有效內容。

如果 Last-Modified 和 ETag 皆為 null,則返回 false。

protected boolean validateCache ( $lastModified, $etag )
$lastModified integer|null

計算出的 Last-Modified 值,以 UNIX 時間戳記表示。如果為 null,則不會驗證 Last-Modified header。

$etag string|null

計算出的 ETag 值。如果為 null,則不會驗證 ETag header。

return boolean

HTTP 快取是否仍然有效。

                protected function validateCache($lastModified, $etag)
{
    if (Yii::$app->request->headers->has('If-None-Match')) {
        // HTTP_IF_NONE_MATCH takes precedence over HTTP_IF_MODIFIED_SINCE
        // https://datatracker.ietf.org/doc/html/rfc7232#section-3.3
        return $etag !== null && in_array($etag, Yii::$app->request->getETags(), true);
    } elseif (Yii::$app->request->headers->has('If-Modified-Since')) {
        return $lastModified !== null && @strtotime(Yii::$app->request->headers->get('If-Modified-Since')) >= $lastModified;
    }
    return false;
}