54

In kohana framework I can call controller via command line using

php5 index.php --uri=controller/method/var1/var2

Is it possible to call controller I want in Laravel 5 via cli? If yes, how to do this?

6 Answers 6

67

There is no way so far (not sure if there will ever be). However you can create your own Artisan Command that can do that. Create a command CallRoute using this:

php artisan make:console CallRoute

For Laravel 5.3 or greater you need to use make:command instead:

php artisan make:command CallRoute

This will generate a command class in app/Console/Commands/CallRoute.php. The contents of that class should look like this:

<?php namespace App\Console\Commands;

use Illuminate\Console\Command;
use Symfony\Component\Console\Input\InputOption;
use Illuminate\Http\Request;

class CallRoute extends Command {

    protected $name = 'route:call';
    protected $description = 'Call route from CLI';

    public function __construct()
    {
        parent::__construct();
    }

    public function fire()
    {
        $request = Request::create($this->option('uri'), 'GET');
        $this->info(app()['Illuminate\Contracts\Http\Kernel']->handle($request));
    }

    protected function getOptions()
    {
        return [
            ['uri', null, InputOption::VALUE_REQUIRED, 'The path of the route to be called', null],
        ];
    }

}

You then need to register the command by adding it to the $commands array in app/Console/Kernel.php:

protected $commands = [
    ...,
    'App\Console\Commands\CallRoute',
];

You can now call any route by using this command:

php artisan route:call --uri=/route/path/with/param

Mind you, this command will return a response as it would be sent to the browser, that means it includes the HTTP headers at the top of the output.

Sign up to request clarification or add additional context in comments.

3 Comments

For Laravel 4: php artisan command:make CallRoute. The kernel is actually the router, so the command needs to have $this->info(app()[\Illuminate\Routing\Router::class]->handle($request));. The command is added to artisan in app/start/artisan.php with Artisan::add(new CallRoute);
This solution seems to have stopped working for Laravel 5.4, with this error: exception 'Illuminate\Contracts\Container\BindingResolutionException' with message 'Target [\Illuminate\Contracts\Http\Kernel] is not instantiable.'
Found a fix. Instead of: app()['Illuminate\Contracts\Http\Kernel'], use: app()->make(\Illuminate\Contracts\Http\Kernel::class)
60

I am using Laravel 5.0 and I am triggering controllers using this code:

$ php artisan tinker
$ $controller = app()->make('App\Http\Controllers\MyController');
$ app()->call([$controller, 'myMethodName'], []);

the last [] in the app()->call() can hold arguments such as [user_id] => 10 etc'

9 Comments

is there a way to call this non-interactively?
php artisan tinker opens up a shell, into which I have to put the other 2 lines. But I would like to just have that executed, for I am putting it in a script. As of now I just solved by making line 2 and 3 a single one, and piping it into the first - was wondering if there was a better solution
hmm well I used this for tests so I just wrote each line at a time and saw the response after sending line 3
@grasshopper if you putting it in a script then this is the wrong tool. You should instead be using a custom artisan command. You can then simply run php artisan mycommand instead of tinker.
Thank you @JamesHulse, I solved for now by echoing the command and piping it to php artisan tinker. I am working on code which is not mine (never used laravel before), could you advise which tool should I use? I am initialising and bootstrapping a laravel application from vagrant provisioner
|
22

For Laravel 5.4: php artisan make:command CallRoute

Then in app/Console/Commands/CallRoute.php:

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Http\Request;

class CallRoute extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'route:call {uri}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'php artsian route:call /route';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $request = Request::create($this->argument('uri'), 'GET');
        $this->info(app()->make(\Illuminate\Contracts\Http\Kernel::class)->handle($request));
    }

}

Then in app/Console/Kernel.php:

protected $commands = [
    'App\Console\Commands\CallRoute'
];

Call like: php artisan route:call /path

5 Comments

This is a very elegant solution for Laravel 5.5 too.
Works in Laravel 5.6 too.
Nice solution. Remember to add 'App\Console\Commands\CallRoute' under $commands in the config/tinker.php config file so that you can run this command from tinker.
In Lumen this generates: Target [Illuminate\Contracts\Http\Kernel] is not instantiable
This answer is better than the excepted one.
6

Laravel 5.7

Using tinker

 // URL: http://xxx.test/calendar?filter[id]=1&anotherparam=2
 $cc = app()->make('App\Http\Controllers\CalendarController');
 app()->call([$cc, 'getCalendarV2'], ['filter[id]'=>1, 'anotherparam' => '2']);

Comments

6

You can do it in this way too. First, create the command using

php artisan command:commandName

Now in the handle of the command, call the controller and trigger the method. Eg,

public function handle(){
 $controller = new ControllerName(); // make sure to import the controller
 $controller->controllerMethod();
}

This will actually do the work. Hope, this helps.

DEPENDENCY INJECTION WON'T WORK

3 Comments

DI is ignored calling method in this way.
DI - dependency injection. Right?
There are no commands defined in the "command" namespace.
1

To version 8 of laravel.

First step: type command in terminal
php artisan tinker

Secound step:

$instante = new MyController(null);

Or if argument by an instance of model, then, pass name model class.
Example:

$instante = new MyController(new MyModelHere());

Press enter.

Finally, call method with $instante->myMethod() here.

See: enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.