zelaza's avatar

Controller Constructors and the Artisan route:list command

The Artisan route:list command seems to need to instantiate all of your Controllers, so if you ever put anything in a Controller constructor that causes an error when the constructor gets called from the command line, you will break your php artisan route:list command, which is not a happy thing.

You can usually prevent this by carefully avoiding putting anything in any of your Controller constructors that would cause an error when run from the artisan command line.

However, there are certain situations where it makes really good programming sense to put something in a Controller that will take an error when called via artisan route:list (e.g. Controllers with several methods that all require information from a real http request, which does not exist when the constructor is called by artisan).

In these cases I have been forced to put some logic in the Controller constructor that avoids taking the error by returning immediately when it detects that the constructor is being called by Artisan, e.g.:

    public function __construct(Request $request)
    {

        if (basename($_SERVER['SCRIPT_NAME']) == 'artisan') {
            return null;
        }

        ...

I don't really like the above approach for a number of reasons, but it works.

Is there a "better" way to solve this problem?

0 likes
7 replies
codenex's avatar

Hmm. I'd have to think about it. Honestly I haven't put anything in my controller constructors that would cause an error when run from the command line.

WebKenth's avatar

Can you give an example of when you actually WANT an error in your controllers constructor?

Seems like you should catch anything unwanted before you ever call the controller which is pretty much what middleware is for.

Mittensoff's avatar

Would making a function that takes in routes and controller actions (functions) as arguments and simulates what you need of artisan route:list?

You could define all that you need done there.

Art's avatar

I'm having the same issue. I'm retrieving oauth api user in constructor, as i need it in all controller methods.

Cronix's avatar

@art sounds like something that could be done in middleware

Punksolid's avatar

Same issue, I identify a tenant connection through the headers and initialize a querybuilder


    public function __construct()
    {

        $this->account = Account::whereUuid(\request()->header("X-Tenant-Id"))->first();
        $this->repository = $this->account->users();

        parent::__construct();
    }

I know I can use a middleware but I would like to know or fix right in my controller the 'datasource' that is providing my users. I have a lot of controllers, endpoints and some middlewares that seeing them in the api.php file its more confusing than seeing the code in the constructor.

Somebody found a better approach? I will use the one that @zelaza provided.

Update: I ended using

        if(!\App::runningInConsole()){
            $this->account = Account::whereUuid(\request()->header("X-Tenant-Id"))->first();
            $this->repository = $this->account->users();
        }
N3OGeorgy's avatar

Hello,

I have the same issue, when running php artisan route:list

I have one Controller with this constructor:

    public function __construct(Request $request)
    {
        $this->middleware('connectorGroup');
        $this->authGroup = AuthGroups::findOrFail($request->route('authGroup'));
        $this->authCategory = $this->authGroup->category;
    }

Even if i check in the middleware connectorGroup :

    public function handle($request, Closure $next)
    {
        if($request->route('authGroup')){
            return $next($request);
        }
    }

I get this error :

Illuminate\Database\Eloquent\ModelNotFoundException 
No query results for model [App\AuthGroups].

If i change only to find method, the next row fails :

ErrorException 
Trying to get property 'category' of non-object

The real question is, there is a nice workaround to fix this issue?

Please or to participate in this conversation.