類別 yii\filters\ContentNegotiator
ContentNegotiator 支援回應格式協商與應用程式語言協商。
當指定了支援的格式屬性時,ContentNegotiator 將根據 GET 參數 $formatParam 和 Accept
HTTP 標頭的值來支援回應格式協商。如果找到匹配項,yii\web\Response::$format 屬性將設定為選定的格式。yii\web\Response::$acceptMimeType 以及 yii\web\Response::$acceptParams 也將相應地更新。
當指定了支援的語言時,ContentNegotiator 將根據 GET 參數 $languageParam 和 Accept-Language
HTTP 標頭的值來支援應用程式語言協商。如果找到匹配項,yii\base\Application::$language 屬性將設定為選定的語言。
您可以將 ContentNegotiator 作為引導元件以及動作過濾器使用。
以下程式碼示範如何將 ContentNegotiator 作為引導元件使用。請注意,在這種情況下,內容協商適用於整個應用程式。
// in application configuration
use yii\web\Response;
return [
'bootstrap' => [
[
'class' => 'yii\filters\ContentNegotiator',
'formats' => [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
],
'languages' => [
'en',
'de',
],
],
],
];
以下程式碼示範如何將 ContentNegotiator 作為動作過濾器在控制器或模組中使用。在這種情況下,內容協商結果僅適用於相應的控制器或模組,甚至如果您設定過濾器的 only
或 except
屬性,則僅適用於特定動作。
use yii\web\Response;
public function behaviors()
{
return [
[
'class' => 'yii\filters\ContentNegotiator',
'only' => ['view', 'index'], // in a controller
// if in a module, use the following IDs for user actions
// 'only' => ['user/view', 'user/index']
'formats' => [
'application/json' => Response::FORMAT_JSON,
],
'languages' => [
'en',
'de',
],
],
];
}
公開屬性
屬性 | 類型 | 描述 | 定義於 |
---|---|---|---|
$except | array | 此過濾器不應套用的動作 ID 列表。 | yii\base\ActionFilter |
$formatParam | string | 指定回應格式的 GET 參數名稱。 | yii\filters\ContentNegotiator |
$formats | array|null | 支援的回應格式列表。 | yii\filters\ContentNegotiator |
$languageParam | string | 指定應用程式語言的 GET 參數名稱。 | yii\filters\ContentNegotiator |
$languages | array|null | 支援的語言列表。 | yii\filters\ContentNegotiator |
$only | array | 此篩選器應套用的動作 ID 列表。 | yii\base\ActionFilter |
$owner | yii\base\Component|null | 此行為的擁有者 | yii\base\Behavior |
$request | yii\web\Request | 目前的請求。 | yii\filters\ContentNegotiator |
$response | yii\web\Response|null | 要發送的回應。 | yii\filters\ContentNegotiator |
公共方法
受保護的方法
方法 | 描述 | 定義於 |
---|---|---|
getActionId() | 透過將 yii\base\Action::$uniqueId 轉換為相對於模組的 ID,傳回動作 ID。 | yii\base\ActionFilter |
isActive() | 傳回指示篩選器是否對給定動作處於活動狀態的值。 | yii\base\ActionFilter |
isLanguageSupported() | 傳回指示請求的語言是否與支援的語言相符的值。 | yii\filters\ContentNegotiator |
negotiateContentType() | 協商回應格式。 | yii\filters\ContentNegotiator |
negotiateLanguage() | 協商應用程式語言。 | yii\filters\ContentNegotiator |
屬性詳細資訊
指定回應格式的 GET 參數名稱。請注意,如果指定的格式在 $formats 中不存在,將會拋出 yii\web\NotAcceptableHttpException 例外。如果參數值為空,或者此屬性為 null,則回應格式將僅根據 Accept
HTTP 標頭確定。
另請參閱 $formats。
支援的回應格式列表。鍵是 MIME 類型(例如 application/json
),而值是相應的格式(例如 html
、json
),這些格式必須如 yii\web\Response::$formatters 中宣告般受到支援。
如果此屬性為空或未設定,則將跳過回應格式協商。
指定應用程式語言的 GET 參數名稱。請注意,如果指定的語言與 $languages 中的任何語言都不符,則將使用 $languages 中的第一種語言。如果參數值為空,或者此屬性為 null,則應用程式語言將僅根據 Accept-Language
HTTP 標頭確定。
另請參閱 $languages。
支援的語言列表。陣列鍵是支援的語言變體(例如 en-GB
、en-US
),而陣列值是應用程式可辨識的相應語言代碼(例如 en
、de
)。
陣列鍵並非總是必需的。當陣列值沒有鍵時,請求語言的匹配將基於語言回退機制。例如,值為 en
將匹配 en
、en_US
、en-US
、en-GB
等。
如果此屬性為空或未設定,則將跳過語言協商。
要發送的回應。如果未設定,將使用 response
應用程式元件。
方法詳細資訊
public mixed __call ( $name, $params ) | ||
$name | string |
方法名稱 |
$params | array |
方法參數 |
return | mixed |
方法傳回值 |
---|---|---|
throws | yii\base\UnknownMethodException |
當呼叫未知方法時 |
public function __call($name, $params)
{
throw new UnknownMethodException('Calling unknown method: ' . get_class($this) . "::$name()");
}
定義於: 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();
}
定義於: yii\base\BaseObject::__get()
傳回物件屬性的值。
請勿直接呼叫此方法,因為當執行 $value = $object->property;
時,它是一個將被隱式呼叫的 PHP 魔術方法。
另請參閱 __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);
}
定義於: yii\base\BaseObject::__isset()
檢查屬性是否已設定,即已定義且非 null。
請勿直接呼叫此方法,因為當執行 isset($object->property)
時,它是一個將被隱式呼叫的 PHP 魔術方法。
請注意,如果屬性未定義,將傳回 false。
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;
}
定義於: yii\base\BaseObject::__set()
設定物件屬性的值。
請勿直接呼叫此方法,因為當執行 $object->property = $value;
時,它是一個將被隱式呼叫的 PHP 魔術方法。
另請參閱 __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);
}
}
定義於: yii\base\BaseObject::__unset()
將物件屬性設定為 null。
請勿直接呼叫此方法,因為當執行 unset($object->property)
時,它是一個將被隱式呼叫的 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);
}
}
public mixed afterAction ( $action, $result ) | ||
$action | yii\base\Action |
剛執行的動作。 |
$result | mixed |
動作執行結果 |
return | mixed |
已處理的動作結果。 |
---|
public function afterAction($action, $result)
{
return $result;
}
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']);
}
定義於: 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']);
}
此方法在動作即將執行之前(在所有可能的篩選器之後)調用。您可以覆寫此方法以進行動作的最後準備。
public boolean beforeAction ( $action ) | ||
$action | yii\base\Action |
要執行的動作。 |
return | boolean |
動作是否應繼續執行。 |
---|
public function beforeAction($action)
{
$this->negotiate();
return true;
}
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;
}
}
在應用程式啟動階段要調用的 Bootstrap 方法。
public void bootstrap ( $app ) | ||
$app | yii\base\Application |
目前正在執行的應用程式 |
public function bootstrap($app)
{
$this->negotiate();
}
定義於: 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);
}
定義於: 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);
}
::class
。
定義於: yii\base\BaseObject::className()
傳回此類別的完整限定名稱。
public static string className ( ) | ||
return | string |
此類別的完整限定名稱。 |
---|
public static function className()
{
return get_called_class();
}
定義於: 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;
}
}
定義於: yii\base\Behavior::events()
為 $owner 的事件宣告事件處理常式。
子類別可以覆寫此方法,以宣告應將哪些 PHP 回呼附加到 $owner 元件的事件。
當行為附加到擁有者時,回呼將附加到 $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 [];
}
定義於: 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;
}
定義於: 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);
}
Defined in: 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);
}
public void init ( ) |
public function init()
{
}
Defined in: yii\base\ActionFilter::isActive()
傳回指示篩選器是否對給定動作處於活動狀態的值。
protected boolean isActive ( $action ) | ||
$action | yii\base\Action |
正在被過濾的動作 |
return | boolean |
過濾器是否對給定的動作啟用。 |
---|
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;
}
傳回指示請求的語言是否與支援的語言相符的值。
protected boolean isLanguageSupported ( $requested, $supported ) | ||
$requested | string |
請求的語言代碼 |
$supported | string |
支援的語言代碼 |
return | boolean |
請求的語言是否被支援 |
---|
protected function isLanguageSupported($requested, $supported)
{
$supported = str_replace('_', '-', strtolower($supported));
$requested = str_replace('_', '-', strtolower($requested));
return strpos($requested . '-', $supported . '-') === 0;
}
協商回應格式和應用程式語言。
public void negotiate ( ) |
public function negotiate()
{
$request = $this->request ?: Yii::$app->getRequest();
$response = $this->response ?: Yii::$app->getResponse();
if (!empty($this->formats)) {
if (\count($this->formats) > 1) {
$response->getHeaders()->add('Vary', 'Accept');
}
$this->negotiateContentType($request, $response);
}
if (!empty($this->languages)) {
if (\count($this->languages) > 1) {
$response->getHeaders()->add('Vary', 'Accept-Language');
}
Yii::$app->language = $this->negotiateLanguage($request);
}
}
協商回應格式。
protected void negotiateContentType ( $request, $response ) | ||
$request | yii\web\Request | |
$response | yii\web\Response | |
throws | yii\web\BadRequestHttpException |
如果收到 GET 參數 $formatParam 的陣列。 |
---|---|---|
throws | yii\web\NotAcceptableHttpException |
如果請求的內容類型皆不被接受。 |
protected function negotiateContentType($request, $response)
{
if (!empty($this->formatParam) && ($format = $request->get($this->formatParam)) !== null) {
if (is_array($format)) {
throw new BadRequestHttpException("Invalid data received for GET parameter '{$this->formatParam}'.");
}
if (in_array($format, $this->formats)) {
$response->format = $format;
$response->acceptMimeType = null;
$response->acceptParams = [];
return;
}
throw new NotAcceptableHttpException('The requested response format is not supported: ' . $format);
}
$types = $request->getAcceptableContentTypes();
if (empty($types)) {
$types['*/*'] = [];
}
foreach ($types as $type => $params) {
if (isset($this->formats[$type])) {
$response->format = $this->formats[$type];
$response->acceptMimeType = $type;
$response->acceptParams = $params;
return;
}
}
foreach ($this->formats as $type => $format) {
$response->format = $format;
$response->acceptMimeType = $type;
$response->acceptParams = [];
break;
}
if (isset($types['*/*'])) {
return;
}
throw new NotAcceptableHttpException('None of your requested content types is supported.');
}
協商應用程式語言。
protected string negotiateLanguage ( $request ) | ||
$request | yii\web\Request | |
return | string |
選擇的語言 |
---|
protected function negotiateLanguage($request)
{
if (!empty($this->languageParam) && ($language = $request->get($this->languageParam)) !== null) {
if (is_array($language)) {
// If an array received, then skip it and use the first of supported languages
return reset($this->languages);
}
if (isset($this->languages[$language])) {
return $this->languages[$language];
}
foreach ($this->languages as $key => $supported) {
if (is_int($key) && $this->isLanguageSupported($language, $supported)) {
return $supported;
}
}
return reset($this->languages);
}
foreach ($request->getAcceptableLanguages() as $language) {
if (isset($this->languages[$language])) {
return $this->languages[$language];
}
foreach ($this->languages as $key => $supported) {
if (is_int($key) && $this->isLanguageSupported($language, $supported)) {
return $supported;
}
}
}
return reset($this->languages);
}
註冊 或 登入 以進行評論。