为什么雄辩的模型关系不使用括号,它们如何运作?

时间:2016-05-18 19:27:35

标签: php function object methods 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');
    }
}

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

$phone = User::find(1)->phone;

为什么phone而不是phone()又有什么区别?

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

一些额外信息:

看起来电话正在返回对象(App \ Models \ Phone)而phone()正在返回对象(Illuminate \ Database \ Eloquent \ Relations \ HasOne)

如果我运行以下代码:

User::find(1)->phone->count()

Framework执行以下SQL语句:

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

如果我运行以下代码:

User::find(1)->phone()->count()

Framework执行以下SQL语句:

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

2 个答案:

答案 0 :(得分:2)

一种思考方法是public function phone()函数定义关系,因此使用$obj->phone()可以使您获得雄辩的关系本身(而不是该关系的结果),然后可以使用各种查询构建器元素(如果需要)。

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

因此,$obj->phone$obj->phone()->first()相同。

答案 1 :(得分:1)

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

$obj = User::find(1);
$phone = $obj->phone;

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

至于第一个解释,对阵列也可以这样做:

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

echo test()['phone'];