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

theilen's avatar

PhpStorm: Method not found in class

I'm a bit lost while configuring PhpStorm, maybe someone can help.

First, I installed the Laravel-Ide-Helper, which seems to work so far. For example in routes.php I can use

Route::get(...

and get no warnings from the IDE.

I can type

app('events')->

and get code completion as expected.

But in my controller some eloquent methods generate a warning in PhpStorm: I have a model

class Post extends Model 
{ ...

In a controller method

$foo = Post::all();

works fine.

$foo = Post::findOrFail(3);

gives me a "method not found in class" warning.

Is there a way to fix this?

0 likes
40 replies
theilen's avatar

I just found that it works as expected when I let my model extend \Eloquent instead of Model.

Happy to hear if there is a more elegant way though.

1 like
opheliadesign's avatar

@theilen interesting. I've been wondering about this myself.. +1 for more details if anyone can provide them.

theilen's avatar

Extending \Eloquent seems a bit like an ugly hack because it is just a wrapper provided by Laravel-Ide-Helper. So I'll have to ship _ide_helper.php with my project and mostly everything suddenly depends on this file. Seems weird to me.

How do you PhpStorm users handle this? Extend \Eloquent? Just disable the warning? Ignore it? Or do you have another simple yet elegant solution?

zoransa's avatar

_ide_helper.php is just a convenient peace of code for PHPStorm and it is never loaded in the code base of laravel.

theilen's avatar

Now I'm somewhat confused... ;-)

If my Post model extends \Eloquent and _ide_helper.php is not present, the site still works. (PhpStorm complains about "method not found" obviously)

But as far as I can see there is no class Eloquent in the Laravel codebase. How does that work?

theilen's avatar

Yeah, I saw it. Obviously Laravel is a lot smarter than me... ;-)

vincej's avatar

I have similar problems. I just installed Storm 9.0 and now I have a sea of "method not found". Yet the code works and I get auto completion on some of my classes.

I have Barry's IDE helper installed as well as the Laravel plugin from Daniel esplanade. I have set up my directories in Storm with public as Resource roots and app & vendor as Source Folder. I have done a cache:clear.

Strangely it seems to find some classes but not others. It does not find Eloquent, nor Laracasts/Flash but it will find DB::table().

I've tried changing the use statements, from, for example,

use Flash to use Laracasts\Flash\Flash

There is nothing wrong with my code as it all works fine. But here is a typical screen shot with lots of nice warnings:

Many thanks

jimmck's avatar

@vincej Hey Vince remember to remove any excluded sub-directories from your vendor directory min the Directories settings. Also remember to re-generate the ide helper file when add packages. Storm loves to mark new Composer packages as ignore and I have to go in and change it.

Here are the artisan commands

ide-helper
  ide-helper:generate         Generate a new IDE Helper file.
  ide-helper:meta             Generate metadata for PhpStorm
  ide-helper:models           Generate autocompletion for models

Jim

vincej's avatar

@jimmck

Hi Jim ! Thanks for coming to the rescue again ! :o)

I did the things you asked for and it has not made any difference that I can see. However I don't quite understand what you mean with this statement:

remember to remove any excluded sub-directories from your vendor directory min the Directories settings.

Here is what my directories look like copied from your post of 2 months ago:

1 like
jimmck's avatar

No that is good. When I add new composer packages they can come in and be excluded. and a I have to mark them as included. Can you post a simple fie that I can copy to have a look. Make sure to close Storm and Reopen so it can get new composer entries. Run the ide help art commands with Storm closed as well.

vincej's avatar

@jimmck

well I had a good look at your stuff and things are improving. No more form::open errors in Blade and most of the errors are gone in my models. However the controllers are still giving 'method not found' errors on vendors classes which are there like laracasts\flash\flash.

I did see that you had .idea as a resource, however I don't have bin\ or bin\coverage - I guess that's a GIT thing.

I now notice a different error which could be relevant: multiple definitions exist for class ABC

When I do a ctrl +B to see where the conflicts are they all point towards the IDE_helper. Not sure how to fix that.

I'm not sure what you mean by this:

Can you post a simple file that I can copy to have a look.

jimmck's avatar

Your Models are fixed good. I was looking for a sample file to compare to my ide helper.

jimmck's avatar

@vincej Forgot add, remember to exclude the storage directory so the compiled files do not get indexed. Jim

vincej's avatar

@jimmck Hi Jim, Sorry, I have been away for a week. Thanks for your reply.

When you say a sample file, do you mean a whole controller class ? I'll copy and paste if that is what you really want.

I still am getting two different kinds of errors:

  • "multiple definitions exists for class xyz" class xyz is always clashing with the ide_helper_models.php file

  • "method xyz not found in ...." or "undefined class xyz"

jimmck's avatar

@vincej Hey, Make sure you exclude the storage directory so you don't double dip the compiled functions with their true places in your source. I was looking for a sample file to see what kind of messages I get on my setup. I would need to see an example of what you mean by method "xyz".

Jim\

vincej's avatar

@jimmck

Yup - storage has been excluded all along. Storm is " double dipping" into ide_helper_models.php placed under the root directory.

Here is the controller where I am getting the errors:

<?php
namespace App\Http\Controllers;

use App\Models\Contractor;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;
use DB;
use Laracasts\Flash\Flash;
use Illuminate\Mail;

class ContractorsController extends Controller
{

    protected $contractor;

    public function __construct(Contractor $contractor)
    {
        $this->contractor = $contractor;
        $this->middleware('auth');  // $this->middleware('auth', ['only' => 'contractorConfirm']);
    }


    /**
     * Display a listing of the resource.
     * GET /contractors
     *
     */
    public function index()
    {

        return View('labour/contractors/index');
    }


    /*
     * Show the form for creating a new resource.
     * GET /contractors/create
     */
    public function create()
    {

        $crews = DB::table('crews')->lists('crew_name', 'id'); // finds all the existing crews.
        $skills = DB::table('skill_type')->lists('skill', 'skill_id'); // finds all the existing skills.
        return View('labour/contractors/create', ['crews' => $crews, 'skills' => $skills]);
    }





    /**
     * Store a newly created resource in storage.
     * POST /contractors
     */
    public function store(Request $request)
    {

        $this->validate($request,
            [
                'first_name' => 'required',
                'last_name' => 'required',
                'cellphone_number' => 'required',
                'square_rate' => 'required|numeric',
                'hour_rate' => 'required_if:square_rate, 0.00',
            ]);

        Contractor::create(Input::all());

        $email = $request->email;

        Mail::send('emails.new_contractor', ['email' => $email], function ($message) use ($email) {
            $message->to($email)->subject('Laravel Email');
        }
        );

        Flash::success('New Contractor Created');


        return redirect('labour/contractors/show');

    }

    /**
     * Display the specified resource.
     * GET /contractors/{id}
     * @param  int $id
     */
    public function show()
    {

        $contractors = $this->contractor->showContractor();

        return View('labour/contractors/show', compact('contractors'));
    }

    /**
     * Show the form for editing the specified resource.
     * GET /contractors/{id}/edit
     * @param  int $id
     */
    public function edit($id)
    {
        $skills = DB::table('skill_type')->lists('skill', 'skill_id');
        $crews = DB::table('crews')->lists('crew_name', 'id');
        $contractor = Contractor::find($id);

        return View('labour/contractors/edit', ['contractor' => $contractor, 'crews' => $crews, 'skills' => $skills]);
    }

    /**
     * Update the specified resource in storage.
     * PUT /contractors/{id}
     * @param  int $id
     */
    public function update($id, Request $request)
    {

        $this->validate($request,
            [
                'first_name' => 'required',
                'last_name' => 'required',
                'cellphone_number' => 'required',
                'square_rate' => 'required|numeric',
                'hour_rate' => 'required_if:square_rate, 0.00',
            ]);

        Contractor::whereId($id)->update($request->except(['_method', '_token']));

        return redirect('labour/contractors/show');
    }

    /**
     * Remove the specified resource from storage.
     * DELETE /contractors/{id}
     * @param  int $id
     */
    public function destroy($id)
    {
        //
    }

    /**
     * identify the active and inactive contractors
     * using a collection $contractors, then filter twice.
     * labour/contractors/inactive
     */
    public function inactive()
    {
        $contractors = $this->contractor->activeContractor();
        $inactives = $this->contractor->inactiveContractor();

        return View('labour/contractors/show', ['contractors' => $contractors, 'inactives' => $inactives]);
    }

}
vincej's avatar

@jimmck

updated the markdown correctly.

the md is not capturing the errors.

jimmck's avatar

@vincej Sorry??? Whats being flagged? I cannot reproduce from a code fragment with this many dependencies...

ARCANEDEV's avatar

@theilen

You know that findOrFail method belongs to Eloquent (@return static|null...).

There are solutions (work arounds) to get the autocomplete in your IDE:

// Solution N°1
class Post extends Model 
{
    // ...

    /**
     * [findOrFail description]
     * 
     * @param  int|string  $id
     *
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
     * 
     * @return self
     */
    public static function findOrFail($id)
    {
        return parent::findOrFail($id);
    }

    // ...
}

// Solution N°2

/** 
 * @var \App\Post $post
 */
$post = Post::findOrFail(3);

IMO, i prefer the solution n°2.

And for more details check : http://phpdoc.org/docs/latest/index.html

vincej's avatar

@jimmck I thought you wanted the whole controller, since I gave you a screenshot of the errors on page one.

jimmck's avatar

@vincej The screen shot of your includes does not show excluded. The screenshot of Storm does not show method 'xyz'.

vincej's avatar

@jimmck

Thanks for your patience !

the screenshot on page 1 shows those classes and methods which are not being found.

Here is another screenshot of of the whole screen. Also featuring the a class with multiple definitions. Hope this helps:

vincej's avatar

@jimmck

_ide_helper_models.php is giving me all the double dipping and creating this "multiple definitions" error

when I was using L4.2 I did not have this pesky file _ide_helper_models.php and it all worked fine.

I can get auto completion for things like routes::post or DB::table

But it is not seeing other vendor classes like Laracasts/laracasts/flash or mail or my own classes.

Storm is great, but this frustrating to say the least.

jimmck's avatar

@vincej Please search your project for Contractor class. What is generating this _ide_helper_models.php? I re-ran all of the helper artisan commands and that file is not generated? rename to vince.php or something.

Regarding Mail facade, generate punts when it cannot connect to something. I have my DB connection in my .env, I added default Mail from sample .env file. Look at the output when I run generate on my project...

Jamess-MacBook-Pro:laravel5 jimm$ art ide-helper:generate
Exception: Error Connecting to server (61): Connection refused
Skipping \Illuminate\Support\Facades\Mail.
Exception: Error Connecting to server (61): Connection refused
Skipping \Illuminate\Support\Facades\Password.
A new helper file was written to _ide_helper.php

the art is just my shortened command for php artisan

Why the hell it cares about connecting I don't know. I am going put a breakpoint in the code and see...

Are you sure storage is excluded? B/C that error is Storm encountering a class definition more than once, hence the project search.

Just select the top most branch of your tree on left hand window, press shift + CMD (What ever that is on your Linux box) + F5 Make sure to check the recursive box under the directory name in the search dialog.

jimmck's avatar

@vincej when you rename that rename the extension to something other than .php...

vincej's avatar

@jimmck

Ok - I understand what you mean by Mail, however it would be nice for Storm to find Laracasts and my own models.

_ide_helper_models.php is generated when you install Barry's ide_helper package. It is an option during install with the default set to "yes" so I just hit yes. It generates a vaste page of commented out model references. Here is a specimen:

?php
/**
 * An helper file for your Eloquent Models
 * Copy the phpDocs from this file to the correct Model,
 * And remove them from this file, to prevent double declarations.
 *
 * @author Barry vd. Heuvel <barryvdh@gmail.com>
 */


namespace App\Models{
/**
 * App\Models\Contractor
 *
 * @property integer $id
 * @property string $company_name
 * @property string $first_name
 * @property string $last_name
 * @property string $status
 * @property string $crew_id
 * @property string $street_address
 * @property string $city
 * @property string $province
 * @property string $postcode
 * @property string $country
 * @property string $cellphone_number
 * @property string $business_number
 * @property string $email
 * @property integer $wcb_number
 * @property integer $gst_number
 * @property string $skill_type
 * @property float $square_rate
 * @property float $hour_rate
 * @property string $website
 * @property string $notes
 * @property \Carbon\Carbon $created_at
 * @property \Carbon\Carbon $updated_at
 * @method static \Illuminate\Database\Query\Builder|\App\Models\Contractor whereId($value)
 * @method static \Illuminate\Database\Query\Builder|\App\Models\Contractor whereCompanyName($value)
 * @method static \Illuminate\Database\Query\Builder|\App\Models\Contractor whereFirstName($value)
 * @method static \Illuminate\Database\Query\Builder|\App\Models\Contractor whereLastName($value)
 * @method static \Illuminate\Database\Query\Builder|\App\Models\Contractor whereStatus($value)
 * @method static \Illuminate\Database\Query\Builder|\App\Models\Contractor whereCrewId($value)
 * @method static \Illuminate\Database\Query\Builder|\App\Models\Contractor whereStreetAddress($value)
 * @method static \Illuminate\Database\Query\Builder|\App\Models\Contractor whereCity($value)
 * @method static \Illuminate\Database\Query\Builder|\App\Models\Contractor whereProvince($value)
 * @method static \Illuminate\Database\Query\Builder|\App\Models\Contractor wherePostcode($value)

This file is referenced by laravel_ide_helper > src > console > ModelsCommand as below:

/**
 * A command to generate autocomplete information for your IDE
 *
 * @author Barry vd. Heuvel <barryvdh@gmail.com>
 */
class ModelsCommand extends Command
{
    /**
     * @var Filesystem $files
     */
    protected $files;

    /**
     * The console command name.
     *
     * @var string
     */
    protected $name = 'ide-helper:models';
    protected $filename = '_ide_helper_models.php';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Generate autocompletion for models';

    protected $properties = array();
    protected $methods = array();
    protected $write = false;
    protected $dirs = array();
    protected $reset;

    /**
     * @param Filesystem $files
Next

Please or to participate in this conversation.