看看 Eloquent 中的 find 方法

在我们的 User 模型中写上这样一个方法

public static function getUserById($id)
{
    return self::find($id);
}

在我们的 routes.php 去是调用以下这个方法

get('/', function () {
    return App\User::getPostById(1);
});

能得到你想要的结果。

如果你使用 IDE,你会发现找不到我们 Model 中的 find 方法,但是我记得在 laravel5.1 之前一直是存在的,忍不住看了一下 5.1 的 5.0 的代码,大概猜到了可能是我们的 eloquent 更新了。

5.0

很简单的就找到了我们的 find 方法

这里细节先留在,在 5.1 的版本中来看看,因为区别几乎没有。

5.1

既然在5.1的 model 中没有找到 find() 这个方法,然后在具体模型又可以去调用这个方法,想必只有一个可能吧

call()callStatic() 这个两个魔术方法

那我们在 model 中去找到 __call(), __callStatic()

可以看到,当触发 __callStatic() 是会去触发 __call()

原来我们使用的 User::find(1) $user = new User;$user->find(1) 就来自于此

如果你愿意,在__call()return 之前随便 dd 以下,然后调用我们的 getUserById() 肯定是会断点的。

increment()decrement() 就不用多说,只是对某个字段进行加减

不过这边这两个方法为什么使用魔术方法来调用就不太清楚了,可以讨论一下。

接着看 newQuery() 这个方法

call_user_func_array([$query, $method], $parameters) 我觉得通过这段代码你都能猜到是调用 $query 这个对象的 find() 方法了。

接着是 newQueryWithoutScopes() 这个方法怎么去实例化我们的 query

$builder = $this->newEloquentBuilder(
    $this->newBaseQueryBuilder()
);

在我们的 newEloquentBuilder() 方法传递一个新的 builder(这个builder与我们的数据库操作层紧密耦合)

/**
 * Create a new Eloquent query builder for the model.
 *
 * @param  \Illuminate\Database\Query\Builder  $query
 * @return \Illuminate\Database\Eloquent\Builder|static
 */
public function newEloquentBuilder($query)
{
    return new Builder($query);
}

传递什么参数,返回什么对象注释都写得很清楚,本着探索的精神还是接着看下去。

Illuminate\Database\Eloquent\Builder 的构造方法

public function __construct(QueryBuilder $query)
{
    $this->query = $query;
}

接来下看如何拿到这个 QueryBuilder 的对象,我们之前的 newBaseQueryBuilder()

中间还是封装了很多细节,连起来就是

  • Query\Builder 封装了底层的数据库操作

  • Eloquent\Builder 依赖上面的 Builder 封装了一系列非常好用的方法

最后你可以看到我们的 Eloquent\Builderfind()

这样看就比较简单了,调用 modelgetQualifiedKeyName() 拿到主键,然后使用 __call 来调用 where() 去查询数据库...

结论

我们的 find() 方法只是被简单的换到了 Eloquent\Builder 这个类中。

如果你多看一些的话,你会发现,和数据库操作更加耦合的一部分方法都被移到了 Eloquent\Builder,这大概也是 Eloquent 的一次重要升级吧。

能力有些,有不好的错误的还请指正。

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 1

譬如 现在有个表是 「products」, getQualifiedKeyName() 返回的是 products.id ,可是我这边只想返回 id,否则查询结果就有错误

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!