为什么 eloquent 模型关系不使用括号,它们是如何工作的?

Evr*_*sen 6 php methods function object eloquent

我一直在网上搜索一个小时,但无法弄清楚。如果我们查看 eloquent 关系文档:https : //laravel.com/docs/5.2/eloquent-relationships

示例用户模型:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Get the phone record associated with the user.
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}
Run Code Online (Sandbox Code Playgroud)

在它的正下方,如何访问 id=1 的用户的电话号码:

$phone = User::find(1)->phone;
Run Code Online (Sandbox Code Playgroud)

为什么是phone和不是phone(),有什么区别?

还有它是如何工作的?如果我尝试object->name在我的代码中调用不带括号的 ,PHP 认为我正在寻找一个名为name?

一些额外的信息:

看起来手机正在返回对象(App\Models\Phone)和手机()正在返回对象(Illuminate\Database\Eloquent\Relations\HasOne)

如果我运行下面的代码:

User::find(1)->phone->count()
Run Code Online (Sandbox Code Playgroud)

框架执行以下 SQL 语句:

select * from `phone` where `phone`.`user_id` = '1' and `phone`.`user_id` is not null limit 1
select count(*) as aggregate from `phone`
Run Code Online (Sandbox Code Playgroud)

如果我运行下面的代码:

User::find(1)->phone()->count()
Run Code Online (Sandbox Code Playgroud)

框架执行以下 SQL 语句:

select count(*) as aggregate from `phone` where `phone`.`user_id` = '1' and `phone`.`user_id` is not null
Run Code Online (Sandbox Code Playgroud)

小智 12

一种思考方式是该public function phone()函数定义了关系,因此使用$obj->phone()将使您获得 Eloquent 关系本身(而不是该关系的结果),然后您可以根据需要使用各种查询构建器元素对其进行修改。

省略括号是 Eloquent 的简写,用于添加->get()->first()在表达式的末尾(Eloquent 根据函数中定义的 hasOne、hasMany 等关系,知道使用哪个),它返回一个 Eloquent 集合。

所以,$obj->phone和 一样$obj->phone()->first()


Abr*_*ver 0

我不知道 Laravel/Eloquent,您需要显示该find()方法以获取更多信息,但User::find(1)返回一个对象,以便->phone访问phone该对象的属性。find()这与您所展示的方法无关。它比这更短,可以做同样的事情:

$obj = User::find(1);
$phone = $obj->phone;
Run Code Online (Sandbox Code Playgroud)

执行此操作var_dump($obj);,您应该会看到一个phone属性。如果不是,那么另一种可能性是该类实现了一个__get()魔术方法,以便当您尝试访问该phone属性时,它会运行该phone()方法并返回该值。

对于第一个解释,对于数组也可以做同样的事情:

function test() { return array('phone'=>'713-555-1212'); }

echo test()['phone'];
Run Code Online (Sandbox Code Playgroud)