应弃用 league/fractal,因其在 PHP 8.1+ 下因迭代器接口废弃而崩溃,官方已废弃且无安全更新;Laravel 原生 JsonResource 是功能更全、零依赖、深度集成的替代方案。

别用 league/fractal 构建 Laravel 标准化 API —— 它在 PHP 8.1+ 环境下会直接报 Call to undefined method League\Fractal\TransformerAbstract::current(),且官方已标记为 abandoned,无安全更新。
为什么 league/fractal 在 Laravel 里跑不起来
核心问题是迭代器接口废弃:PHP 8.1 移除了 Iterator 接口的隐式 current()、key()、next() 调用,而 league/fractal v0.19.x 及所有基于它的封装(包括 spatie/laravel-fractal)都依赖这一行为。即使降级到 PHP 8.0,Composer 也会因 illuminate/support ≥ v10 的约束拒绝安装兼容版本。
-
fractal()->collection($users, new UserTransformer())在 PHP 8.1+ 下首次调用就崩溃 -
spatie/laravel-fractal只是轻量封装,没重写底层迭代逻辑,同样失效 - 强行用
composer require league/fractal:^1.0.0会在 PHP 8.2+ 触发CreationContext::create()弃用警告,且部分 Transformer 方法签名已不匹配
Laravel ≥ 8.x 的标准替代方案:原生 JsonResource
它不是“类似 Fractal”,而是功能覆盖更全、无额外依赖、且深度集成 Eloquent 关系加载与分页元数据的正式方案。迁移成本远低于修复 Fractal 兼容性问题。
- 关系嵌套用
$this->whenLoaded('posts'),而非includePosts()隐式调用 - 字段条件返回用
$this->when($this->email_verified_at, 'verified'),比auto_excludes更可控 - 分页响应直接
UserResource::collection($users)->response()->getData(true),自动带meta.total字段 - JSON:API 兼容?加
use Illuminate\Http\Resources\Json\JsonResource;+ 自定义with()返回links和meta即可
如果必须保留 Fractal 风格语法,注意三个硬限制
某些遗留项目短期无法重构,但强行续用需明确边界:
立即学习“PHP免费学习笔记(深入)”;
- PHP 版本锁死在
8.0.*,且composer.json中必须声明"php": "^8.0"并禁用platform-check -
allowedIncludes(['posts', 'profile'])必须显式声明,否则?include=xxx会触发BadMethodCallException(Fractal 不检查方法是否存在) - 分页 total 字段不会自动出现,得手动在序列化器里注入:
$paginator->toArray()['meta']['total'] = $paginator->total()
真正麻烦的从来不是怎么写 Transformer,而是当 league/fractal 在 CI 环境里突然崩掉、没人记得当初为什么选它、也没有人敢动那段“能跑就行”的代码——这种技术债比重写 Resource 多花十倍时间。



















