我遇到了同样的问题(PHP 7.2 + Laravel 5.3),但我在这里看不到任何“好”的答案。对我来说,当我尝试从模型上的范围方法启动生成器时会出现问题:SomeModel::forUser() calls scopeForUser()
. 尝试构建一个新的 Query,它count($this->wheres)
会在没有初始值 ( null
) 的情况下跳闸。因为对作用域的神奇静态调用启动了构建器,所以没有在对象中放置其他条件,所以属性仍然null
在那个点。
我认为值得先分享我的解决方案,然后再看看为什么我认为它比 Ben 的答案更好。这不是个人的,我只是不同意。
解决方案
我从这个答案中得到了关于覆盖一些核心Illuminate\Database
类的提示......
- 扩展
Illuminate\Database\Eloquent\Model
我的是App\Overrides\Database\Eloquent\Model
- 扩展
Illuminate\Database\Eloquent\Builder
我的是App\Overrides\Database\Eloquent\Builder
- 扩展
Illuminate\Database\Query\Builder
你能猜到吗?App\Overrides\Database\Query\Builder
- 告诉 Laravel 使用 YOUR
Eloquent\Model
:
config/app.php 'aliases'
数组,将'Eloquent'
值
替换为Eloquent\Model
FQN
我的Model
:
namespace App\Overrides\Database\Eloquent;
/*
* Notes:
* * Using replacement Query\Builder with ALIAS
* * Use of Builder in this class is MY Eloquent\Builder
*/
use App\Overrides\Database\Query\Builder as QueryBuilder;
use Illuminate\Database\Eloquent\Model as EloquentModel;
class Model extends EloquentModel
{
public function newEloquentBuilder($query)
{
return new Builder($query);
}
protected function newBaseQueryBuilder()
{
$conn = $this->getConnection();
$grammar = $conn->getQueryGrammar();
return new QueryBuilder($conn, $grammar, $conn->getPostProcessor());
}
}
我的Eloquent\Builder
:
namespace App\Overrides\Database\Eloquent;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
class Builder extends EloquentBuilder
{
public function __construct($query)
{
parent::__construct($query);
/*
* FIX #1: Set properties treated AS arrays
* to empty arrays on construct.
*/
$this->wheres = [];
// Any other properties treated as arrays should also be initialized.
}
}
我的Query\Builder
:
namespace App\Overrides\Database\Query;
use Illuminate\Database\Query\Builder as QueryBuilder;
class Builder extends QueryBuilder
{
public function __construct()
{
parent::__construct(...func_get_args());
/*
* FIX #2: Set properties treated AS arrays
* to empty arrays on construct.
*/
$this->wheres = [];
// Any other properties treated as arrays should also be initialized.
}
}
这安全地保留了框架的功能,因为您所做的唯一实际更改是初始化应该首先存在的属性。其他一切都将通过instanceof
用于动态加载和依赖注入的检查。
观点
虽然我同意@ben-harold 关于他所说的“永远不要编辑供应商代码”的每条评论,但我不同意“解决方案”。这是对一个更复杂的问题的过度简化。
升级 Laravel:为了确保对 PHP 7.2 的支持,升级几个次要版本——如果不是主要版本的话——对于很多团队来说是不切实际的。作为一个长期目标,当然可以。作为我可以做些什么来摆脱我的最后期限的错误?没有。随着结构、名称和功能的变化,升级需要大量的计划和频繁的重写。这是要优先考虑的事情,但不是现在需要的答案。
降级 PHP:同样的问题。降级到 PHP 5.x 意味着 A) PHP 是 EOL,对于许多拥有安全策略的客户来说,这可能是一个交易破坏者,并且 B) 必须废弃 PHP 7.x 语言功能的任何使用。与升级框架一样,这很可能会引起很多麻烦。这也是一个更没用的解决方案,因为在语言中倒退只会让你更落后,并且需要更多的长期努力。