[php] Why I'm getting 'Non-static method should not be called statically' when invoking a method in a Eloquent model?

Im trying to load my model in my controller and tried this:

return Post::getAll();

got the error Non-static method Post::getAll() should not be called statically, assuming $this from incompatible context

The function in the model looks like this:

public function getAll()
{

    return $posts = $this->all()->take(2)->get();

}

What's the correct way to load the model in a controller and then return it's contents?

This question is related to php laravel eloquent

The answer is


You defined your method as non-static and you are trying to invoke it as static. That said...

1.if you want to invoke a static method, you should use the :: and define your method as static.

// Defining a static method in a Foo class.
public static function getAll() { /* code */ }

// Invoking that static method
Foo::getAll();

2.otherwise, if you want to invoke an instance method you should instance your class, use ->.

// Defining a non-static method in a Foo class.
public function getAll() { /* code */ }

// Invoking that non-static method.
$foo = new Foo();
$foo->getAll();

Note: In Laravel, almost all Eloquent methods return an instance of your model, allowing you to chain methods as shown below:

$foos = Foo::all()->take(10)->get();

In that code we are statically calling the all method via Facade. After that, all other methods are being called as instance methods.


Just in case this helps someone, I was getting this error because I completely missed the stated fact that the scope prefix must not be used when calling a local scope. So if you defined a local scope in your model like this:

public function scopeRecentFirst($query)
{
    return $query->orderBy('updated_at', 'desc');
}

You should call it like:

$CurrentUsers = \App\Models\Users::recentFirst()->get();

Note that the prefix scope is not present in the call.


For use the syntax like return Post::getAll(); you should have a magic function __callStatic in your class where handle all static calls:

public static function __callStatic($method, $parameters)
{
    return (new static)->$method(...$parameters);
}

Check if you do not have declared the method getAll() in the model. That causes the controller to think that you are calling a non-static method.


I've literally just arrived at the answer in my case. I'm creating a system that has implemented a create method, so I was getting this actual error because I was accessing the overridden version not the one from Eloquent.

Hope that help?


TL;DR. You can get around this by expressing your queries as MyModel::query()->find(10); instead of MyModel::find(10);.

To the best of my knowledge, starting PhpStorm 2017.2 code inspection fails for methods such as MyModel::where(), MyModel::find(), etc (check this thread). This could get quite annoying, when you try let's say to use PhpStorm's Git integration before committing your code, PhpStorm won't stop complaining about these static method call warnings.

One elegant way (IMOO) to get around this is to explicitly call ::query() wherever it makes sense to. This will let you benefit from a free auto-completion and a nice query formatting.

Examples

Snippet where inspection complains about static method calls

$myModel = MyModel::find(10); // static call complaint

// another poorly formatted query with code inspection complaints
$myFilteredModels = MyModel::where('is_beautiful', true)
    ->where('is_not_smart', false)
    ->get();

Well formatted code with no complaints

$myModel = MyModel::query()->find(10);

// a nicely formatted query with no complaints
$myFilteredModels = MyModel::query()
    ->where('is_beautiful', true)
    ->where('is_not_smart', false)
    ->get();

Why not try adding Scope? Scope is a very good feature of Eloquent.

class User extends Eloquent {

    public function scopePopular($query)
    {
        return $query->where('votes', '>', 100);
    }

    public function scopeWomen($query)
    {
        return $query->whereGender('W');
    }

}

$users = User::popular()->women()->orderBy('created_at')->get();

Eloquent #scopes in Laravel Docs


You can give like this

public static function getAll()
{

    return $posts = $this->all()->take(2)->get();

}

And when you call statically inside your controller function also..


Solution to the original question

You called a non-static method statically. To make a public function static in the model, would look like this:

public static function {
  
}

In General:

Post::get()

In this particular instance:

Post::take(2)->get()

One thing to be careful of, when defining relationships and scope, that I had an issue with that caused a 'non-static method should not be called statically' error is when they are named the same, for example:

public function category(){
    return $this->belongsTo('App\Category');
}

public function scopeCategory(){
    return $query->where('category', 1);
}

When I do the following, I get the non-static error:

Event::category()->get();

The issue, is that Laravel is using my relationship method called category, rather than my category scope (scopeCategory). This can be resolved by renaming the scope or the relationship. I chose to rename the relationship:

public function cat(){
    return $this->belongsTo('App\Category', 'category_id');
}

Please observe that I defined the foreign key (category_id) because otherwise Laravel would have looked for cat_id instead, and it wouldn't have found it, as I had defined it as category_id in the database.


Examples related to php

I am receiving warning in Facebook Application using PHP SDK Pass PDO prepared statement to variables Parse error: syntax error, unexpected [ Preg_match backtrack error Removing "http://" from a string How do I hide the PHP explode delimiter from submitted form results? Problems with installation of Google App Engine SDK for php in OS X Laravel 4 with Sentry 2 add user to a group on Registration php & mysql query not echoing in html with tags? How do I show a message in the foreach loop?

Examples related to laravel

Parameter binding on left joins with array in Laravel Query Builder Laravel 4 with Sentry 2 add user to a group on Registration Target class controller does not exist - Laravel 8 Visual Studio Code PHP Intelephense Keep Showing Not Necessary Error The POST method is not supported for this route. Supported methods: GET, HEAD. Laravel How to fix 'Unchecked runtime.lastError: The message port closed before a response was received' chrome issue? Post request in Laravel - Error - 419 Sorry, your session/ 419 your page has expired Expected response code 250 but got code "530", with message "530 5.7.1 Authentication required How can I run specific migration in laravel Laravel 5 show ErrorException file_put_contents failed to open stream: No such file or directory

Examples related to eloquent

Eloquent: find() and where() usage laravel How to select specific columns in laravel eloquent Laravel Eloquent where field is X or null Laravel Eloquent limit and offset laravel collection to array Eloquent get only one column as an array Laravel 5.2 - Use a String as a Custom Primary Key for Eloquent Table becomes 0 Laravel 5.2 - pluck() method returns array Eloquent ORM laravel 5 Get Array of ids eloquent laravel: How to get a row count from a ->get()