Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Ponous's avatar
Level 3

Get Model instance from Class name

Hey,

I noticed that in some cases, Laravel does something that I want to implement. You specify the Model's class name, and laravel under the hood will instantiate the model or execute any queries. E.g. when creating a factory

protected $model = \Modules\MyModule\Entities\User::class;

I have several queries running in laravel and I want to implement something like the aforementioned. For instance I have a standard operation for several controllers, where I find a model by id and show a message to the user if the model is not found, I apply several manipulations on the model's result and further operations that I want to apply. So far I do something like the following

// I instantiate in the contructor the model I want to query on
$model = new User();

// Inside a method I am doing the following
$this->model->newModelQuery()-> (more calls here)

Does anyone know how can I convert my example to be similar to Laravel's? I want to specify the class and not instantiate a new model every time. I tried digging into the documentation or checking how Laravel's model work but so far I couldn't reproduce it.

Any suggestions are welcomed.

0 likes
18 replies
LaryAI's avatar
LaryAI
AI
Best Answer
Level 58

To achieve the behavior you're looking for, you can use Laravel's resolve function or the app helper to instantiate a model from its class name. This way, you don't need to manually instantiate the model every time. Here's how you can do it:

  1. Using the resolve function:
use Modules\MyModule\Entities\User;

class YourController extends Controller
{
    protected $modelClass;

    public function __construct()
    {
        $this->modelClass = User::class;
    }

    public function someMethod($id)
    {
        $modelInstance = resolve($this->modelClass);

        $model = $modelInstance->newQuery()->find($id);

        if (!$model) {
            // Handle the case where the model is not found
            return response()->json(['message' => 'Model not found'], 404);
        }

        // Apply your manipulations and further operations here
        // ...

        return response()->json($model);
    }
}
  1. Using the app helper:
use Modules\MyModule\Entities\User;

class YourController extends Controller
{
    protected $modelClass;

    public function __construct()
    {
        $this->modelClass = User::class;
    }

    public function someMethod($id)
    {
        $modelInstance = app($this->modelClass);

        $model = $modelInstance->newQuery()->find($id);

        if (!$model) {
            // Handle the case where the model is not found
            return response()->json(['message' => 'Model not found'], 404);
        }

        // Apply your manipulations and further operations here
        // ...

        return response()->json($model);
    }
}

In both examples, the resolve function or app helper is used to instantiate the model class dynamically. This approach allows you to specify the model class once and reuse it throughout your controller methods without manually instantiating the model each time.

This should help you achieve the desired behavior similar to how Laravel handles model instantiation in factories and other parts of the framework.

1 like
vincent15000's avatar

To get the model instance from the class name, you just have to do like this.

$class = 'Book';

$fullClass = 'App\Models\'.$class;

$book = new $fullClass;
$book->...
1 like
Ponous's avatar
Level 3

@vincent15000

Thanks for your response. Does this really work though? Cause I get an error

1 like
rodrigo.pedra's avatar

@Ponous

Markdown rendering is missing the double backslashes, which should be typed 4 times for correct rendering, a paper cut when writing code snippets

If this works for you, please mark @vincent15000 's post as correct

$class = 'Book';

$fullClass = 'App\\Models\\'.$class;

$book = new $fullClass;
$book->...
1 like
karim_aouaouda's avatar

we must know that laravel is a framework, that's mean is a code executed in a specific order,

when you specific the namespace of the class in a member variable, you must use some thing to initiate it, for example :

protected $model = User::class; 

// ServiceProvider Or Constructor
$this->model = $this->model::query;

//then in the function 
$this->model->where(..)->... 

how ever you can do that in a more advanced example using when() method in service providers, let's assume that you want to bind a User Object when the AuthController called so u need to do that in a ServiceProvider (for example AppServiceProvider) :

public function boot(){
	$this->app->when([
		AuthController::class,
		... //other classes that needs USer Class
	])
	->needs(Builder::class) // a query builder to call where() ...
	->give(function(){
		return User::query(); //or return a specific user User::find('some id') 
	});
}

after that you must add in AuthController constrictor like that :

class AuthController
{
	public function __construct(protected Builder $user){}

	//in method
	public function doSomeThing(){
		$this->user->where(...)// ...
	}
}

for more details ask

2 likes
vincent15000's avatar

@karim_aouaouda

we must know that laravel is a framework, that's mean is a code executed in a specific order,

A framework is a toolbox to help a developer to code an application.

The fact that it's a framework is not related to the fact that a code is executed in a specific order.

karim_aouaouda's avatar

@vincent15000 I was trying to simplify the explanation of the sollution that i give for him, I didn't mean to give him a definition about what a framework is ! , the definition of a software or a website is a statements executed in a specific order statement after statement, that's was i mean

1 like
Ponous's avatar
Level 3

@karim_aouaouda

Thanks for your response. This is actually a nice idea but for the purposes I need it, at the moment AI's solution covers me. In the future, this may indeed come in handy

For my problem, the trick was to use resolve or app functions to instantiate the model, just like the AI proposed

1 like
Snapey's avatar
protected $model = \Modules\MyModule\Entities\User::class;

Simply sets $model to equal the class name (as a string) - nothing more.

1 like
Ponous's avatar
Level 3

@Snapey

Thanks Snapey. I know. The question was how to use this string to instantiate an Object (specifically an Entity that extends the Eloquent Model class)

Some of the comments above answered this question already though

1 like
jlrdw's avatar

Just have a use statement in the controller where you need to use a class model:

use App\Models\User;

And in a method:

User::   whatever

Laravel handles DI for you.

I suggest the free 30 days to learn laravel course.

1 like
Ponous's avatar
Level 3

@jlrdw

Thanks for your input but this was not what I asked. I asked how to get rid of this solution actually.

Some of the answers above already solved my problem

1 like
puklipo's avatar

This is a feature of PHP, not Laravel.

class User {}

$model = User::class;
$user = new $model;
dump($user);

$model = 'User';
$user = new $model;
dump($user);

$user = new ('User');
dump($user);

https://www.php.net/manual/en/language.oop5.basic.php

Laravel also uses new $model internally.

return new $model($attributes);

https://github.com/laravel/framework/blob/af1298c2b8639fbb52656bd49623d2367cdfe46c/src/Illuminate/Database/Eloquent/Factories/Factory.php#L766

2 likes
Ponous's avatar
Level 3

@puklipo

Thank you. This is very informative. Eventually, I used Laravel's helper methods to do the job but I was really curious on how Laravel did this under the hood.

1 like
rodrigo.pedra's avatar

If you have a model instance, which seems to be the case from your code, you can get its class name from the ::class constant:

$className = $this->model::class;
$newInstance = new $className();

Alternatively, you can use newInstance() from the model instance

$newInstance = $this->model->newInstance();
1 like

Please or to participate in this conversation.