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 通过遵守在 fields()extraFields() 中声明的字段定义来实现 toArray()

公共方法

隐藏继承的方法

方法 描述 定义于
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() 受保护的方法 (自版本 2.0.14 起可用)

从给定根字段的字段集合中提取嵌套字段。嵌套字段用点 (.) 分隔。例如:"item.id" 上述示例将提取 "id"。

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

请求提取的字段

$rootField string

我们要为其提取嵌套字段的根字段

返回值 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() 受保护的方法 (自版本 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() 公共方法

返回当没有指定特定字段时,默认情况下应由 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() 受保护方法

确定哪些字段可以由 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() 公共方法

将模型转换为数组。

此方法将首先通过调用 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 才能提取嵌套扩展。如果 $recursive 为 false,则仅提取根扩展。

$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;
}