2

Consider this example

class SomeClass extends Model{
    public function user(){
        return $this->belongsTo('App\User');
    }
}
$instance = SomeClass::findOrFail(1);
$user = $instance->user;

how do laravel know(i mean in core) that $instance->user (without brackets) return related model?

1 Answers1

6

Basically, whenever you try to access a property from a model, the __get magic method is invoked and it's something like the following:

public function __get($key)
{
    return $this->getAttribute($key);
}

As you can see that, the __get magic method calls another user defined method (getAttribute) which is something like the following:

public function getAttribute($key)
{
    if (! $key) {
        return;
    }

    // If the attribute exists in the attribute array or has a "get" mutator we will
    // get the attribute's value. Otherwise, we will proceed as if the developers
    // are asking for a relationship's value. This covers both types of values.
    if (array_key_exists($key, $this->attributes) ||
        $this->hasGetMutator($key)) {
        return $this->getAttributeValue($key);
    }

    // Here we will determine if the model base class itself contains this given key
    // since we do not want to treat any of those methods are relationships since
    // they are all intended as helper methods and none of these are relations.
    if (method_exists(self::class, $key)) {
        return;
    }

    return $this->getRelationValue($key);
}

In this case (for relation), the last line return $this->getRelationValue($key); is responsible for retrieving a relationship. Keep reading the source code, track each function calls and you'll get the idea. Start from Illuminate\Database\Eloquent\Model.php::__get method. Btw, this code is taken from latest version of Laravel but ultimately the process is same.

Short summary: Laravel at first checks if the property/$kay being accessed is a property of a model or if it's an accessor method defined in the model itself then it simply returns that property otherwise it keeps further checking and if it founds a method defined in the model using that name (property/$kay) then it simply returns the relationship.

The Alpha
  • 143,660
  • 29
  • 287
  • 307