如何替换Laravel Builder类
如何替换Laravel Builder类
我想用自己扩展的类来替换Laravel的构建器类。我原以为只需要使用App::bind
就可以了,但似乎并不起作用。在Laravel中,我应该在哪里放置绑定,以及正确的方法是什么?
这是我尝试过的代码:
我的Builder类:
use Illuminate\Database\Eloquent\Builder as BaseBuilder; class Builder extends BaseBuilder { /** * 通过主键查找模型。 * * @param mixed $id * @param array $columns * @return \Illuminate\Database\Eloquent\Model|static|null */ public function find($id, $columns = array('*')) { Event::fire('before.find', array($this)); $result = parent::find($id, $columns); Event::fire('after.find', array($this)); return $result; } }
然后,我尝试在bootstrap/start.php文件中注册绑定,代码如下:
$app->bind('Illuminate\\Database\\Eloquent\\Builder', 'MyNameSpace\\Database\\Eloquent\\Builder'); return $app;
问题出现的原因是之前给出的方法在Laravel 5之后的版本中不再适用。为了解决这个问题,需要使用新的方法来替换Laravel Builder类。具体的解决方法如下:
首先,通过访问以下链接找到解决方法的源代码:
https://github.com/laravel/framework/blob/5.2/src/Illuminate/Database/Eloquent/Model.php#L1868
然后,使用以下代码替换原来的方法:
protected function newBaseQueryBuilder() { $conn = $this->getConnection(); $grammar = $conn->getQueryGrammar(); return new QueryBuilder($conn, $grammar, $conn->getPostProcessor()); }
问题的出现原因是需要在Laravel中替换Builder类,具体分为两种情况:更改Eloquent Builder和更改Database Query Builder。
对于更改Eloquent Builder,可以创建一个新的类CustomEloquentBuilder,继承自Eloquent Builder,并添加自定义方法。然后创建一个Custom Model,重写newEloquentBuilder方法,返回CustomEloquentBuilder的实例。
对于更改Database Query Builder,可以创建一个新的类CustomQueryBuilder,继承自Database Builder,并添加自定义方法。然后创建一个Custom Model,重写newBaseQueryBuilder方法,返回CustomQueryBuilder的实例。
实际代码如下:
更改Eloquent Builder的代码:
use Illuminate\Database\Eloquent\Builder; class CustomEloquentBuilder extends Builder { public function myMethod() { // some method things } }
创建Custom Model并重写newEloquentBuilder方法:
use Namespace\Of\CustomEloquentBuilder; use Illuminate\Database\Eloquent\Model; class CustomModel extends Model { public function newEloquentBuilder($query) { return new CustomEloquentBuilder($query); } }
更改Database Query Builder的代码:
use Illuminate\Database\Query\Builder; class CustomQueryBuilder extends Builder { public function myMethod() { // some method things } }
创建Custom Model并重写newBaseQueryBuilder方法:
use Namespace\Of\CustomQueryBuilder; use Illuminate\Database\Eloquent\Model; class CustomModel extends Model { protected function newBaseQueryBuilder() { $connection = $this->getConnection(); return new CustomQueryBuilder( $connection, $connection->getQueryGrammar(), $connection->getPostProcessor() ); } }
以上代码适用于Laravel 5.5版本,但尚未经过测试。
Laravel框架中的Illuminate\Database\Eloquent\Builder
类是一个内部类,因此它没有被依赖注入到Illuminate\Database\Eloquent\Model
类中,而是硬编码在那里。
为了实现你想要的功能,可以通过扩展Illuminate\Database\Eloquent\Model
类来创建MyNamespace\Database\Eloquent\Model
类,并重写newEloquentBuilder
函数。
public function newEloquentBuilder($query) { return new MyNamespace\Database\Eloquent\Builder($query); }
然后在app/config/app.php
的aliases
中将MyNamespace\Database\Eloquent\Model
别名为Eloquent
。