php serializer,Serializer.php

namespace deepziyu\yii\rest;

use Yii;

use yii\base\Arrayable;

use yii\base\Component;

use yii\base\Model;

use yii\data\DataProviderInterface;

use yii\data\Pagination;

use yii\helpers\ArrayHelper;

use yii\web\Link;

use yii\web\Request;

use yii\web\Response;

/**

* Serializer converts resource objects and collections into array representation.

*

* Serializer is mainly used by REST controllers to convert different objects into array representation

* so that they can be further turned into different formats, such as JSON, XML, by response formatters.

*

* The default implementation handles resources as [[Model]] objects and collections as objects

* implementing [[DataProviderInterface]]. You may override [[serialize()]] to handle more types.

*

* @author Qiang Xue

* @since 2.0

*/

class Serializer extends Component

{

/**

* @var string the name of the query parameter containing the information about which fields should be returned

* for a [[Model]] object. If the parameter is not provided or empty, the default set of fields as defined

* by [[Model::fields()]] will be returned.

*/

public $fieldsParam = 'fields';

/**

* @var string the name of the query parameter containing the information about which fields should be returned

* in addition to those listed in [[fieldsParam]] for a resource object.

*/

public $expandParam = 'expand';

/**

* @var string the name of the HTTP header containing the information about total number of data items.

* This is used when serving a resource collection with pagination.

*/

public $totalCountHeader = 'X-Pagination-Total-Count';

/**

* @var string the name of the HTTP header containing the information about total number of pages of data.

* This is used when serving a resource collection with pagination.

*/

public $pageCountHeader = 'X-Pagination-Page-Count';

/**

* @var string the name of the HTTP header containing the information about the current page number (1-based).

* This is used when serving a resource collection with pagination.

*/

public $currentPageHeader = 'X-Pagination-Current-Page';

/**

* @var string the name of the HTTP header containing the information about the number of data items in each page.

* This is used when serving a resource collection with pagination.

*/

public $perPageHeader = 'X-Pagination-Per-Page';

/**

* @var string the name of the envelope (e.g. `items`) for returning the resource objects in a collection.

* This is used when serving a resource collection. When this is set and pagination is enabled, the serializer

* will return a collection in the following format:

*

* ```php

* [

* 'items' => [...], // assuming collectionEnvelope is "items"

* '_links' => { // pagination links as returned by Pagination::getLinks()

* 'self' => '...',

* 'next' => '...',

* 'last' => '...',

* },

* '_meta' => { // meta information as returned by Pagination::toArray()

* 'totalCount' => 100,

* 'pageCount' => 5,

* 'currentPage' => 1,

* 'perPage' => 20,

* },

* ]

* ```

*

* If this property is not set, the resource arrays will be directly returned without using envelope.

* The pagination information as shown in `_links` and `_meta` can be accessed from the response HTTP headers.

*/

public $collectionEnvelope;

/**

* @var string the name of the envelope (e.g. `_links`) for returning the links objects.

* It takes effect only, if `collectionEnvelope` is set.

* @since 2.0.4

*/

public $linksEnvelope = '_links';

/**

* @var string the name of the envelope (e.g. `_meta`) for returning the pagination object.

* It takes effect only, if `collectionEnvelope` is set.

* @since 2.0.4

*/

public $metaEnvelope = '_meta';

/**

* @var Request the current request. If not set, the `request` application component will be used.

*/

public $request;

/**

* @var Response the response to be sent. If not set, the `response` application component will be used.

*/

public $response;

/**

* @var bool whether to preserve array keys when serializing collection data.

* Set this to `true` to allow serialization of a collection as a JSON object where array keys are

* used to index the model objects. The default is to serialize all collections as array, regardless

* of how the array is indexed.

* @see serializeDataProvider()

* @since 2.0.10

*/

public $preserveKeys = false;

/**

* @inheritdoc

*/

public function init()

{

if ($this->request === null) {

$this->request = Yii::$app->getRequest();

}

if ($this->response === null) {

$this->response = Yii::$app->getResponse();

}

}

/**

* Serializes the given data into a format that can be easily turned into other formats.

* This method mainly converts the objects of recognized types into array representation.

* It will not do conversion for unknown object types or non-object data.

* The default implementation will handle [[Model]] and [[DataProviderInterface]].

* You may override this method to support more object types.

* @param mixed $data the data to be serialized.

* @return mixed the converted data.

*/

public function serialize($data)

{

if ($data instanceof Model && $data->hasErrors()) {

return $this->serializeModelErrors($data);

} elseif ($data instanceof Arrayable) {

return $this->serializeModel($data);

} elseif ($data instanceof DataProviderInterface) {

return $this->serializeDataProvider($data);

} else {

return $data;

}

}

/**

* @return array the names of the requested fields. The first element is an array

* representing the list of default fields requested, while the second element is

* an array of the extra fields requested in addition to the default fields.

* @see Model::fields()

* @see Model::extraFields()

*/

protected function getRequestedFields()

{

$fields = $this->request->get($this->fieldsParam);

$expand = $this->request->get($this->expandParam);

return [

is_string($fields) ? preg_split('/\s*,\s*/', $fields, -1, PREG_SPLIT_NO_EMPTY) : [],

is_string($expand) ? preg_split('/\s*,\s*/', $expand, -1, PREG_SPLIT_NO_EMPTY) : [],

];

}

/**

* Serializes a data provider.

* @param DataProviderInterface $dataProvider

* @return array the array representation of the data provider.

*/

protected function serializeDataProvider($dataProvider)

{

if ($this->preserveKeys) {

$models = $dataProvider->getModels();

} else {

$models = array_values($dataProvider->getModels());

}

$models = $this->serializeModels($models);

if (($pagination = $dataProvider->getPagination()) !== false) {

$this->addPaginationHeaders($pagination);

}

if ($this->request->getIsHead()) {

return null;

} elseif ($this->collectionEnvelope === null) {

return $models;

} else {

$result = [

$this->collectionEnvelope => $models,

];

if ($pagination !== false) {

return array_merge($result, $this->serializePagination($pagination));

} else {

return $result;

}

}

}

/**

* Serializes a pagination into an array.

* @param Pagination $pagination

* @return array the array representation of the pagination

* @see addPaginationHeaders()

*/

protected function serializePagination($pagination)

{

return [

$this->linksEnvelope => Link::serialize($pagination->getLinks(true)),

$this->metaEnvelope => [

'totalCount' => $pagination->totalCount,

'pageCount' => $pagination->getPageCount(),

'currentPage' => $pagination->getPage() + 1,

'perPage' => $pagination->getPageSize(),

],

];

}

/**

* Adds HTTP headers about the pagination to the response.

* @param Pagination $pagination

*/

protected function addPaginationHeaders($pagination)

{

$links = [];

foreach ($pagination->getLinks(true) as $rel => $url) {

$links[] = "; rel=$rel";

}

$this->response->getHeaders()

->set($this->totalCountHeader, $pagination->totalCount)

->set($this->pageCountHeader, $pagination->getPageCount())

->set($this->currentPageHeader, $pagination->getPage() + 1)

->set($this->perPageHeader, $pagination->pageSize)

->set('Link', implode(', ', $links));

}

/**

* Serializes a model object.

* @param Arrayable $model

* @return array the array representation of the model

*/

protected function serializeModel($model)

{

if ($this->request->getIsHead()) {

return null;

} else {

list ($fields, $expand) = $this->getRequestedFields();

return $model->toArray($fields, $expand);

}

}

/**

* Serializes the validation errors in a model.

* @param Model $model

* @return array the array representation of the errors

*/

protected function serializeModelErrors($model)

{

$this->response->setStatusCode(422, 'Data Validation Failed.');

$result = [];

foreach ($model->getFirstErrors() as $name => $message) {

$result[] = [

'field' => $name,

'message' => $message,

];

}

return $result;

}

/**

* Serializes a set of models.

* @param array $models

* @return array the array representation of the models

*/

protected function serializeModels(array $models)

{

list ($fields, $expand) = $this->getRequestedFields();

foreach ($models as $i => $model) {

if ($model instanceof Arrayable) {

$models[$i] = $model->toArray($fields, $expand);

} elseif (is_array($model)) {

$models[$i] = ArrayHelper::toArray($model);

}

}

return $models;

}

}

一键复制

编辑

Web IDE

原始数据

按行查看

历史

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值