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?
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.