When passing arguments to a command, you cannot access the arguments in the constructor method
php artisan make:command TestArguments
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
class TestArguments extends Command
{
protected $variable;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'command:test {variable=0}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Testing arguments in Constructor method';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
$this->variable = $this->argument('variable');
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
//
}
}
php artisan command:test
Running command will output:
Symfony\Component\Debug\Exception\FatalThrowableError : Call to a member function getArgument() on null
at /var/www/entry_system_customdomain/vendor/laravel/framework/src/Illuminate/Console/Command.php:274
270| if (is_null($key)) {
271| return $this->input->getArguments();
272| }
273|
> 274| return $this->input->getArgument($key);
275| }
276|
277| /**
278| * Get all of the arguments passed to the command.
Exception trace:
1 Illuminate\Console\Command::argument("variable")
/var/www/entry_system_customdomain/app/Console/Commands/TestArguments.php:33
2 App\Console\Commands\TestArguments::__construct()
[internal]:0
Please use the argument -v to see more details.
Not possible, Laravel need to construct the command during the bootstrap process because it need to know the command signature. Only when the command is executed then you can access the argument/option
As the output described,
Call to a member function getArgument() on null
$this->input variable is null. (Illuminate\Console\Command class)
$this->input is set when Command::run() is executed.
public function run(InputInterface $input, OutputInterface $output)
{
...
return parent::run(
$this->input = $input, $this->output
);
}
But, that happens after TestArguments::__construct() is executed.
If you inserted echo, print into these functions as debug, you could understand very easily.
Is this then by design? Why would you not want to be able to access arguments within the constructor method?
Why would you not want to be able to access arguments within the constructor method?
Because Laravel uses Symfony and that is simply how the Symfony console works. Like in most code, the constructor is used to "set up" things, not "run" things. So you can change/set _how_ the command behaves but you don't run it. And unless you run it, you don't have access to any of what you want.
This never worked, this is not expected to work. IMHO there's no bug here.
You can make a constructor facade: a function that is just a normal function, but it is called immediately in the handle method. That way it can act as a constructor for you and handle things related to the argument provided in the command.
Think of it like the 2nd constructor.
public function constructor_facade()
{
// Do stuff with $this->argument('id');
}
public function handle()
{
$this->constructor_facade();
// Do the rest of your command
}
Most helpful comment
Because Laravel uses Symfony and that is simply how the Symfony console works. Like in most code, the constructor is used to "set up" things, not "run" things. So you can change/set _how_ the command behaves but you don't run it. And unless you run it, you don't have access to any of what you want.
This never worked, this is not expected to work. IMHO there's no bug here.