本篇文章為大家展示了深如何在PHP中使用JSONAPI,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
<?php
use League\Fractal\Manager;
use League\Fractal\Resource\Collection;
$articles = [
[
'id' => 1,
'title' => 'JSON API paints my bikeshed!',
'body' => 'The shortest article. Ever.',
'author' => [
'id' => 42,
'name' => 'John',
],
],
];
$manager = new Manager();
$resource = new Collection($articles, new ArticleTransformer());
$manager->parseIncludes('author');
$manager->createData($resource)->toArray();
?>如果讓我選最喜愛的 PHP 工具包,Fractal 一定榜上有名,它隱藏了實現細節,讓使用者完全不必了解 JSONAPI 協議即可上手。不過如果你想在自己的項目里使用的話,與直接使用 Fractal 相比,可以試試 Fractalistic ,它對 Fractal 進行了封裝,使其更好用:
<?php Fractal::create() ->collection($articles) ->transformWith(new ArticleTransformer()) ->includeAuthor() ->toArray(); ?>
如果你是裸寫 PHP 的話,那么 Fractalistic 基本就是最佳選擇了,不過如果你使用了一些全??蚣艿脑?,那么 Fractalistic 可能還不夠優雅,因為它無法和框架本身已有的功能更完美的融合,以 Lavaral 為例,它本身內置了一個 API Resources 功能,在此基礎上我實現了一個 JsonApiSerializer,可以和框架完美融合,代碼如下:
<?php
namespace App\Http\Serializers;
use Illuminate\Http\Resources\MissingValue;
use Illuminate\Http\Resources\Json\Resource;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Pagination\AbstractPaginator;
class JsonApiSerializer implements \JsonSerializable
{
protected $resource;
protected $resourceValue;
protected $data = [];
protected static $included = [];
public function __construct($resource, $resourceValue)
{
$this->resource = $resource;
$this->resourceValue = $resourceValue;
}
public function jsonSerialize()
{
foreach ($this->resourceValue as $key => $value) {
if ($value instanceof Resource) {
$this->serializeResource($key, $value);
} else {
$this->serializeNonResource($key, $value);
}
}
if (!$this->isRootResource()) {
return $this->data;
}
$result = [
'data' => $this->data,
];
if (static::$included) {
$result['included'] = static::$included;
}
if (!$this->resource->resource instanceof AbstractPaginator) {
return $result;
}
$paginated = $this->resource->resource->toArray();
$result['links'] = $this->links($paginated);
$result['meta'] = $this->meta($paginated);
return $result;
}
protected function serializeResource($key, $value, $type = null)
{
if ($type === null) {
$type = $key;
}
if ($value->resource instanceof MissingValue) {
return;
}
if ($value instanceof ResourceCollection) {
foreach ($value as $k => $v) {
$this->serializeResource($k, $v, $type);
}
} elseif (is_string($type)) {
$included = $value->resolve();
$data = [
'type' => $included['type'],
'id' => $included['id'],
];
if (is_int($key)) {
$this->data['relationships'][$type]['data'][] = $data;
} else {
$this->data['relationships'][$type]['data'] = $data;
}
static::$included[] = $included;
} else {
$this->data[] = $value->resolve();
}
}
protected function serializeNonResource($key, $value)
{
switch ($key) {
case 'id':
$value = (string)$value;
case 'type':
case 'links':
$this->data[$key] = $value;
break;
default:
$this->data['attributes'][$key] = $value;
}
}
protected function links($paginated)
{
return [
'first' => $paginated['first_page_url'] ?? null,
'last' => $paginated['last_page_url'] ?? null,
'prev' => $paginated['prev_page_url'] ?? null,
'next' => $paginated['next_page_url'] ?? null,
];
}
protected function meta($paginated)
{
return [
'current_page' => $paginated['current_page'] ?? null,
'from' => $paginated['from'] ?? null,
'last_page' => $paginated['last_page'] ?? null,
'per_page' => $paginated['per_page'] ?? null,
'to' => $paginated['to'] ?? null,
'total' => $paginated['total'] ?? null,
];
}
protected function isRootResource()
{
return isset($this->resource->isRoot) && $this->resource->isRoot;
}
}
?>對應的 Resource 基本還和以前一樣,只是返回值改了一下:
<?php
namespace App\Http\Resources;
use App\Article;
use Illuminate\Http\Resources\Json\Resource;
use App\Http\Serializers\JsonApiSerializer;
class ArticleResource extends Resource
{
public function toArray($request)
{
$value = [
'type' => 'articles',
'id' => $this->id,
'name' => $this->name,
'author' => $this->whenLoaded('author'),
];
return new JsonApiSerializer($this, $value);
}
}
?>對應的 Controller 也和原來差不多,只是加入了一個 isRoot 屬性,用來識別根:
<?php
namespace App\Http\Controllers;
use App\Article;
use App\Http\Resources\ArticleResource;
class ArticleController extends Controller
{
protected $article;
public function __construct(Article $article)
{
$this->article = $article;
}
public function show($id)
{
$article = $this->article->with('author')->findOrFail($id);
$resource = new ArticleResource($article);
$resource->isRoot = true;
return $resource;
}
}
?>上述內容就是深如何在PHP中使用JSONAPI,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。