最近在使用 Laravel 开发产品原型时,遇到了各种各样的问题,在这里总结一些常见问题以免走弯路。
类似于 Laravel 这样的 PHP 框架,内置了许多常用库和包,减少了重复造轮子,我们可以把时间精力集中在业务逻辑上。很常见的例子是,API开发中,只要在 Controller 的 Method 中把结果 return 给框架,而无需自行管理输出格式(或在中间件 Middleware
中统一处理)。
class MainController extends Controller { public function getHome() { $results = Model::get(); return $results; } }
某天,发生了意想不到的问题,该结果集无法正常返回并且报错:
The Response content must be a string or object implementing __toString(), "boolean" given.
经过跟踪调试,框架处理返回结果时会自动判断数据类型,对于 Illuminate\Database\Eloquent\Model
和 Illuminate\Database\Eloquent\Collection
这样的 JsonSerializable
的实现,会使用 jsonSerialize()
方法尝试获取可序列化的数据后 以 json_encode()
返回结果。
出于业务需求,我们在 Model 中使用了设值方法和拓展字段 $appends
;在 getSomeVarAttribute()
方法中,我们进行了 json_decode
操作;因为对该段代码逻辑没有有效性验证, json_decode
解析无效字符产生了解析错误(可以用 json_last_error_msg()
获取),导致框架获取结果时 json_encode()
取到的是 bool(false)
,故不能将结果正常显示。
我们可以撇开框架用如下代码复现:
<?php class SomeObject implements JsonSerializable { protected $hello = "world"; public function jsonSerialize () { json_decode("{"); //尝试解析无效的字符导致JSON错误 return ["hello" => $this->hello]; } } $obj = new SomeObject(); var_dump(json_encode($obj)); // 此时结果为 bool(false)
尽管这个问题不是框架原因产生的,但由于框架让我们习惯了偷懒,加上框架较一般的 PHP 脚本调试难度大,解决这个问题所花的时间也比一般情况下多,所以写代码时我们要尤其注意这些细节。