agm1984
agm1984

Reputation: 17160

In PHP/Laravel, what is the proper term for what "Model::class" is, given `return $this->belongsTo(Model::class);`

In this example code here:

public function user()
{
    return $this->belongsTo(User::class);
}

public function sandwich()
{
    return $this->belongsTo(Sandwich::class);
}

I want to know what User::class is called, because you could also write that above example like this:

public function user()
{
    return $this->belongsTo(\App\User);
}

public function sandwich()
{
    return $this->belongsTo(\App\Sandwich);
}

So I like that Laravel "just knows" where the model is when you use that syntax sugar, but what is it called? I'd like to read some documentation about it so I better understand what's happening behind the scenes.

It reminds me in some ways of "route model binding", so the answer that I would like is a link to the relevant docs page somewhere, or a term I can Google to understand what exactly is going on there.

Upvotes: 1

Views: 940

Answers (3)

Udochukwu Enwerem
Udochukwu Enwerem

Reputation: 2823

I want to know what User::class is called

A wholesome name to call this is class name resolution. It combines both the PHP resolution operator :: and the class keyword. lt is not a Laravel syntax sugar but a PHP one.

It, in all situations, returns the Fully qualified name of the class which is simply a string containing the absolute/relative path of the class file - depending on the namespace of the file/class where it is used.

From the PHP Manual

... use ClassName::class to get a fully qualified name of class ClassName

On the other hand, from the Laravel use-case you mentioned

public function user()
{
    return $this->belongsTo(User::class);
}

The Laravel Eloquent method belongsTo() and all similar methods specify that the parameter to be passed is a string. These methods resolve the string parameter to locate the model's class definition.

From the Laravel Docs

The first argument passed to the hasOne method is the name of the related model.

Therefore using

return $this->belongsTo('\App\User');

OR

return $this->belongsTo(User::class);

are syntactically equivalent. That means that the method definition are exactly the same and there is no parameter type checking as both parameters are string.

So I like that Laravel "just knows" where the model is when you use that syntax sugar.

Yeah, it just knows. But it is really straight forward. It uses the string parameter of the Eloquent method (now we know that regardless of the syntax, it is a String) and the provided Namespace of the current class to locate the model definition.

For instance this class definition

<?php

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

is equivalent to

<?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(Phone::class);
    }
}

and also equivalent to

<?php

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::class);
    }
}

You will notice that the first and third examples do not need the namespace directive because they are using the Absolute path names.

Upvotes: 3

B. Fleming
B. Fleming

Reputation: 7220

The ::class syntax is class name resolution. This syntax returns the string representation of the fully qualified class name, including any namespace information otherwise omitted.

A couple of the benefits of this feature are 1. not needing to explicitly specify the fully qualified namespace of the class, and 2. being able to pass around the fully qualified namespace as a string while allowing an IDE to locate the class name when refactoring or searching for references.

Upvotes: 4

OsDev
OsDev

Reputation: 1252

Actually Laravel is not aware where the model is

If this example works:

public function user()
{
    return $this->belongsTo(User::class);
}

It's becase probably the models lives in the same folder or Namespace if not you probably should to import the required model from other namespace like this.


//At the top of the file you will import the class

use Maybe\Another\Folder\Namespace\OtherObject;

public function user()
{
    return $this->belongsTo(OtherObject::class);
}

if you don't want to "import" the object you should use the complete path to the class like this.

public function user()
{
    return $this->belongsTo(App\OtherFolder\OtherObject::class);
}

In summary laravel doesn't know where to look for class definitions, but if you pass an instance in a param that would be resolved for the Service Container but this is another topic more related to the model binding

public function method(MyObject $instance)
{
    //Laravel will try to automatically generate an instance of $instance
}

Upvotes: 1

Related Questions