0 追蹤者

Trait yii\base\ArrayableTrait

實作於yii\base\DynamicModel, yii\base\Model, yii\data\ActiveDataFilter, yii\data\DataFilter, yii\db\ActiveRecord, yii\db\BaseActiveRecord
自版本2.0
原始碼 https://github.com/yiisoft/yii2/blob/master/framework/base/ArrayableTrait.php

ArrayableTrait 提供了 yii\base\Arrayable 介面的通用實作。

ArrayableTrait 實作了 toArray(),透過尊重在 fields()extraFields() 中宣告的欄位定義。

公開方法

隱藏繼承的方法

方法 描述 定義於
extraFields() 傳回可以進一步展開並由 toArray() 傳回的欄位列表。 yii\base\ArrayableTrait
fields() 傳回當未指定特定欄位時,預設應由 toArray() 傳回的欄位列表。 yii\base\ArrayableTrait
toArray() 將模型轉換為陣列。 yii\base\ArrayableTrait

受保護方法

隱藏繼承的方法

方法 描述 定義於
extractFieldsFor() 從給定根欄位的欄位集合中提取巢狀欄位。巢狀欄位以點 (.) 分隔。例如:"item.id"。先前的範例會提取 "id"。 yii\base\ArrayableTrait
extractRootFields() 從巢狀欄位中提取根欄位名稱。 yii\base\ArrayableTrait
resolveFields() 決定哪些欄位可以由 toArray() 傳回。 yii\base\ArrayableTrait

方法詳情

隱藏繼承的方法

extraFields() 公開方法

傳回可以進一步展開並由 toArray() 傳回的欄位列表。

此方法與 fields() 類似,不同之處在於此方法傳回的欄位列表預設不會由 toArray() 傳回。 只有在呼叫 toArray() 時明確指定要展開的欄位名稱時,才會匯出它們的值。

預設實作傳回一個空陣列。

您可以覆寫此方法,根據一些上下文資訊(例如,當前應用程式使用者)傳回可展開欄位的列表。

另請參閱

public array extraFields ( )
傳回 array

可展開的欄位名稱或欄位定義的列表。 請參閱 fields(),了解傳回值的格式。

                public function extraFields()
{
    return [];
}

            
extractFieldsFor() protected method (available since version 2.0.14)

從給定根欄位的欄位集合中提取巢狀欄位。巢狀欄位以點 (.) 分隔。例如:"item.id"。先前的範例會提取 "id"。

protected array extractFieldsFor ( array $fields, $rootField )
$fields array

請求提取的欄位

$rootField 字串

我們想要提取巢狀欄位的根欄位

傳回 array

為給定欄位提取的巢狀欄位

                protected function extractFieldsFor(array $fields, $rootField)
{
    $result = [];
    foreach ($fields as $field) {
        if (0 === strpos($field, "{$rootField}.")) {
            $result[] = preg_replace('/^' . preg_quote($rootField, '/') . '\./i', '', $field);
        }
    }
    return array_unique($result);
}

            
extractRootFields() protected method (available since version 2.0.14)

從巢狀欄位中提取根欄位名稱。

巢狀欄位以點號 (.) 分隔。例如:"item.id"。先前的範例會提取 "item"。

protected array extractRootFields ( array $fields )
$fields array

請求提取的欄位

傳回 array

從給定的巢狀欄位中提取的根欄位

                protected function extractRootFields(array $fields)
{
    $result = [];
    foreach ($fields as $field) {
        $result[] = current(explode('.', $field, 2));
    }
    if (in_array('*', $result, true)) {
        $result = [];
    }
    return array_unique($result);
}

            
fields() public method

傳回當未指定特定欄位時,預設應由 toArray() 傳回的欄位列表。

欄位是由 toArray() 傳回陣列中的具名元素。

此方法應傳回欄位名稱或欄位定義的陣列。若是前者,欄位名稱會被視為物件屬性名稱,其值會被用作欄位值。若是後者,陣列鍵應為欄位名稱,而陣列值應為對應的欄位定義,它可以是物件屬性名稱或傳回對應欄位值的 PHP 可呼叫函式。可呼叫函式的簽章應為

function ($model, $field) {
    // return field value
}

例如,以下程式碼宣告了四個欄位

  • email:欄位名稱與屬性名稱 email 相同;
  • firstNamelastName:欄位名稱為 firstNamelastName,其值從 first_namelast_name 屬性取得;
  • fullName:欄位名稱為 fullName。其值是透過串連 first_namelast_name 而取得。
return [
    'email',
    'firstName' => 'first_name',
    'lastName' => 'last_name',
    'fullName' => function () {
        return $this->first_name . ' ' . $this->last_name;
    },
];

在此方法中,您可能也希望根據某些上下文資訊傳回不同的欄位列表。例如,根據目前應用程式使用者的權限,您可以傳回不同的可見欄位集合或篩選掉某些欄位。

此方法的預設實作會傳回以自身索引的公開物件成員變數。

另請參閱 toArray()

public array fields ( )
傳回 array

欄位名稱或欄位定義的列表。

                public function fields()
{
    $fields = array_keys(Yii::getObjectVars($this));
    return array_combine($fields, $fields);
}

            
resolveFields() protected method

決定哪些欄位可以由 toArray() 傳回。

此方法將首先從給定的欄位中提取根欄位。然後,它會針對在 fields()extraFields() 中宣告的根欄位檢查請求的根欄位,以確定可以傳回哪些欄位。

protected array resolveFields ( array $fields, array $expand )
$fields array

請求匯出的欄位

$expand array

請求匯出的額外欄位

傳回 array

要匯出的欄位列表。陣列鍵是欄位名稱,而陣列值是對應的物件屬性名稱或傳回欄位值的 PHP 可呼叫函式。

                protected function resolveFields(array $fields, array $expand)
{
    $fields = $this->extractRootFields($fields);
    $expand = $this->extractRootFields($expand);
    $result = [];
    foreach ($this->fields() as $field => $definition) {
        if (is_int($field)) {
            $field = $definition;
        }
        if (empty($fields) || in_array($field, $fields, true)) {
            $result[$field] = $definition;
        }
    }
    if (empty($expand)) {
        return $result;
    }
    foreach ($this->extraFields() as $field => $definition) {
        if (is_int($field)) {
            $field = $definition;
        }
        if (in_array($field, $expand, true)) {
            $result[$field] = $definition;
        }
    }
    return $result;
}

            
toArray() public method

將模型轉換為陣列。

此方法將首先透過呼叫 resolveFields() 來識別要包含在結果陣列中的欄位。然後,它會將模型轉換為包含這些欄位的陣列。如果 $recursive 為 true,則任何嵌入的物件也會被轉換為陣列。當嵌入的物件是 yii\base\Arrayable 時,它們各自的巢狀欄位將被提取並傳遞給 toArray()

如果模型實作了 yii\web\Linkable 介面,則結果陣列也將具有一個 _link 元素,該元素引用介面指定的連結列表。

public array toArray ( array $fields = [], array $expand = [], $recursive true )
$fields array

請求的欄位。如果為空或包含 '*',則將傳回 fields() 指定的所有欄位。欄位可以是巢狀的,以點號 (.) 分隔。例如:item.field.sub-field。 $recursive 必須為 true 才能提取巢狀欄位。如果 $recursive 為 false,則只會提取根欄位。

$expand array

請求匯出的額外欄位。只會考慮在 extraFields() 中宣告的欄位。Expand 也可以是巢狀的,以點號 (.) 分隔。例如:item.expand1.expand2。 $recursive 必須為 true 才能提取巢狀 expand。如果 $recursive 為 false,則只會提取根 expand。

$recursive 布林值

是否以遞迴方式傳回嵌入物件的陣列表示法。

傳回 array

物件的陣列表示法

                public function toArray(array $fields = [], array $expand = [], $recursive = true)
{
    $data = [];
    foreach ($this->resolveFields($fields, $expand) as $field => $definition) {
        $attribute = is_string($definition) ? $this->$definition : $definition($this, $field);
        if ($recursive) {
            $nestedFields = $this->extractFieldsFor($fields, $field);
            $nestedExpand = $this->extractFieldsFor($expand, $field);
            if ($attribute instanceof Arrayable) {
                $attribute = $attribute->toArray($nestedFields, $nestedExpand);
            } elseif ($attribute instanceof \JsonSerializable) {
                $attribute = $attribute->jsonSerialize();
            } elseif (is_array($attribute)) {
                $attribute = array_map(
                    function ($item) use ($nestedFields, $nestedExpand) {
                        if ($item instanceof Arrayable) {
                            return $item->toArray($nestedFields, $nestedExpand);
                        } elseif ($item instanceof \JsonSerializable) {
                            return $item->jsonSerialize();
                        }
                        return $item;
                    },
                    $attribute
                );
            }
        }
        $data[$field] = $attribute;
    }
    if ($this instanceof Linkable) {
        $data['_links'] = Link::serialize($this->getLinks());
    }
    return $recursive ? ArrayHelper::toArray($data) : $data;
}