-
Notifications
You must be signed in to change notification settings - Fork 11.7k
Description
- Laravel Version: 9.x
- PHP Version: 8.1
- Database Driver & Version: Mysql 8
Description:
I created a couple of commands, that are suppose to be available only locally for development, both children of a common a parent class.
abstract class Dumper extends Command
{
public function __construct()
{
parent::__construct();
dump($this->connection_name);
}
public function handle()
{
if (!app()->environment('local')) {
return $this->info('This command is only available for development.');
}
// ...
}
}
class DumperA extends Dumper
{
protected string $connection_name = 'A';
}
class DumperB extends Dumper
{
protected string $connection_name = 'B';
}While developing though I realized that every command class loaded in Laravel is instantiated every time any one of them is run.
In fact even running a completely unrelated command, like config:clear the constructor of both my new commands was executed (note the command does execute successfully anyway):
$ php artisan config:clear
"A" // app/Console/Commands/Dev/Dumper.php:30
"B" // app/Console/Commands/Dev/Dumper.php:30
INFO Configuration cache cleared successfully.
I found this odd as I would expect each command to be completely independent from each other; in fact in the constructor of those dev commands I set some config variables that at this point I suppose would affect other commands.
Am I doing something wrong or missing something? Is using the constructor to set some common attributes not OK for some reason in this case?
This behavior also caused an issue once I pushed to staging, where the commands are also instantiated when the artisan package:discover command is executed (my command looks for a local file that on staging is not available):
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover
[2023-03-17 17:38:29] stack.ERROR: Missing weather.cnf file {"exception":"[object] (Exception(code: 0): Missing weather.cnf file at /tmp/build_f49ece74/app/Console/Commands/Dev/Dumper.php:44)Now, this might not be considered a bug, however I'd say it is a potentially dangerous unexpected side effect that would be worth clearly documenting, and I'd be happy to send a PR for that.
At the same time, is there maybe a different pattern or method to use to safely set class or instance attributes outside the constructor, or the only/best option is to do so inside the handle method?