简体   繁体   English

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

[英]Why eloquent model relationships do not use parenthesis and how do they work?

I kept searching the web for an hour but couldn't figure this out. 我一直在网上搜索一个小时,但无法解决。 If we look at the eloquent relationships documentation: https://laravel.com/docs/5.2/eloquent-relationships 如果我们看一下雄辩的关系文档: https : //laravel.com/docs/5.2/eloquent-relationships

The example User model: 示例用户模型:

<?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');
    }
}

Just below it, how to access the phone number of a user with id=1: 在其正下方,如何访问id = 1的用户的电话号码:

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

Why is it phone and not phone() and what is the difference? 为什么是phone而不是phone() ?有什么区别?

Also how does it work? 还如何运作? If I try to call an object->name without parenthesis in my code PHP thinks I am looking for a class variable named name ? 如果我尝试在代码中调用不带括号的object->name ,PHP会认为我正在寻找一个名为name的类变量?

Some extra information: 一些额外的信息:

It looks like phone is returning object(App\\Models\\Phone) and phone() is returning object(Illuminate\\Database\\Eloquent\\Relations\\HasOne) 看起来电话正在返回对象(App \\ Models \\ Phone),而电话()正在返回对象(Illuminate \\ Database \\ Eloquent \\ Relations \\ HasOne)

If I run the code below: 如果我运行下面的代码:

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

Framework executes following SQL statements: 框架执行以下SQL语句:

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

If I run the code below: 如果我运行下面的代码:

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

Framework executes following SQL statement: 框架执行以下SQL语句:

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

One way of thinking about it is that the public function phone() function defines the relationship, so using $obj->phone() would get you the Eloquent relationship itself (not the results of that relationship) which you could then modify with various query builder elements if you wanted. 考虑这种情况的一种方法是, public function phone()函数定义了关系,因此使用$obj->phone()将获得Eloquent关系本身(而不是该关系的结果),然后可以使用各种方式对其进行修改。如果需要,查询构建器元素。

Leaving out the brackets is the Eloquent shorthand for adding ->get() or ->first() at the end of the expression (Eloquent knows which to use based on if it's a hasOne, hasMany, etc. relationship, as defined in the function), which returns an Eloquent collection. Eloquent省略括号的方法是在表达式末尾添加->get()->first() (Eloquent根据是否具有hasOne,hasMany等关系来知道要使用哪个关系,如函数),它返回一个Eloquent集合。

So, $obj->phone is the same as $obj->phone()->first() . 因此, $obj->phone$obj->phone()->first()

I don't know Laravel/Eloquent and you would need to show the find() method for more information, but User::find(1) returns an object so the ->phone accesses the phone property of that object. 我不了解Laravel / Eloquent,所以您需要显示find()方法以获取更多信息,但是User::find(1)返回一个对象,因此->phone访问该对象的phone属性。 This has nothing to do with the find() method that you have shown. 这与您显示的find()方法无关。 It is shorter than this that would do the same: 它比这样做的时间短:

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

Do a var_dump($obj); 做一个var_dump($obj); and you should see a phone property. 您应该会看到一个phone属性。 If not, then another possibility is that the class implements a __get() magic method so that when you attempt to access the phone property it runs the phone() method and returns the value. 如果不是,则另一种可能性是该类实现__get()魔术方法,以便当您尝试访问phone属性时,它将运行phone()方法并返回该值。

As for the first explanation, the same can be done with arrays: 关于第一个解释,对数组也可以这样做:

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

echo test()['phone'];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM