I love . Laravel As a PHP developer with a history of working in everything from WordPress to CodeIgniter, when Laravel came on the scene it was a revelation. From the design to the usability, it is an absolutely top-notch framework that contains untold depths of power. That said, sometimes Laravel's own opinionated structure can get in the way of what can feel like pretty simple intentions, such as adding custom global arguments to all Artisan commands. What do I mean by "custom global arguments?" As an example, Artisan commands have the all same set of arguments and options that can be used during runtime: --raw To output raw command list --format=FORMAT The output format (txt, xml, json, or md) [default: "txt"] --short To skip describing commands' arguments -h, --help Display help for the given command. When no command is given display help for the list command -q, --quiet Do not output any message -V, --version Display this application version --ansi|--no-ansi Force (or disable --no-ansi) ANSI output -n, --no-interaction Do not ask any interactive question --env[=ENV] The environment the command should run under -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug But, what if we wanted to add options and arguments? our own A Wild Problem Has Appeared! I've always been a pretty big fan of for both its power and ease-of-use—okay, maybe not so much lately thanks to how poorly they've communicated their most recent , but I've been a fan. Heroku security incident historically One of Heroku's most frustrating drawbacks, though, is how limited the Scheduler is. A kind of half-assed cron, allows you to run any command on 10-minute, 1-hour, or 1-day intervals, which is useful, but also woefully insufficient for many different types of jobs. Heroku's Scheduler kind of What if I only need something run weekly, monthly, or even yearly? Scheduler says "no." So, in order to work around this (within a typical Laravel application), I have traditionally added an additional argument to my Artisan commands that limits running on specific days. For example: php artisan run:command --day=friday Pretty simple design, right? It gets the job done, but it's hardly scalable. Copying the same several lines of " " logic can get pretty tedious (not to mention nothing close to DRY), so I dug into Artisan to better understand how I could add additional global parameters that can be applied to commands, rather than just the ones I specify. if current day == --day parameter, then run, otherwise return 0 all Extending Artisan Thankfully Laravel, being the object-oriented framework that it is, is pretty easy to extend. The challenge isn't so much in the extension as it is in properly writing said extension up into the rest of the application. That said, before we can actually wire up, we first need to extend the class and add our own custom argument. To do this, create a new file called and paste the following code in: anything Console\Application --day ./app/Console/Application.php <?php namespace App\Console; use Illuminate\Console\Application as Artisan; use Illuminate\Support\Str; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class Application extends Artisan { /** * Runs the current application. * * @return int 0 if everything went fine, or an error code */ public function doRun(InputInterface $input, OutputInterface $output) { if ( !$this->checkDay($input) ) { $output->writeln(sprintf('<comment>This command can only be run on %s.</comment>', Str::plural(ucfirst($input->getParameterOption('--day')))), OutputInterface::VERBOSITY_QUIET); return 0; } return parent::doRun($input, $output); } protected function getDefaultInputDefinition() { $definition = parent::getDefaultInputDefinition(); $definition->addOption(new InputOption('--day', null, InputOption::VALUE_OPTIONAL, "Only run the command on the specified day of the week")); return $definition; } public function checkDay(InputInterface $input) { $day = $input->getParameterOption('--day'); if ( !$day ) { return true; } return strtolower(now()->englishDayOfWeek) === strtolower($day); } } What the above code is doing can be broken down into a few parts: It creates a new method that gets our custom global parameter ( ) and checks the value against the current day of the week. If the two values are matched (or is not provided), then will return , otherwise it will return . checkDay() --day --day checkDay() true false It extends the method and checks the value of before running the rest of the command. If returns false, the command will immediately and print a comment indicating that the command can only be run on the specified day. doRun() checkDay() checkDay() return 0 Finally, because we want anyone that types to this new argument, we extend and add a new definition indicating that both , and how it works. php artisan --help know about getDefaultInputFunction() --day exists Wiring It Up So, we've extended our console application, but if we were to run our new argument won't show up yet. That's because we need to about our new class, otherwise it will load the original class by default. php artisan --help --day tell Laravel Console\Application To do this, open up and add the following function to the class: ./app/Console/Kernel.php Kernel /** * Retrieve the artisan application instance. * * @return \Illuminate\Console\Application */ protected function getArtisan() { if (is_null($this->artisan)) { return $this->artisan = (new \App\Console\Application($this->app, $this->events, $this->app->version()))->resolveCommands($this->commands); } return $this->artisan; } What the above function does is tell Laravel to load our newly defined class when setting Artisan up, rather than the default class. Because we extended the original class, the existing functionality will still be maintained, but with the new functionality we just added. \App\Console\Application \Illuminate\Console\Application Console\Application Now, if we were to type , we would see a new argument listed in the response: php artisan --help --raw To output raw command list --format=FORMAT The output format (txt, xml, json, or md) [default: "txt"] --short To skip describing commands' arguments -h, --help Display help for the given command. When no command is given display help for the list command -q, --quiet Do not output any message -V, --version Display this application version --ansi|--no-ansi Force (or disable --no-ansi) ANSI output -n, --no-interaction Do not ask any interactive question --env[=ENV] The environment the command should run under --day[=DAY] Only run the command on the specified day of the week -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug Fin. That's it! All-in-all, it's a pretty straightforward change with some potentially powerful implications. Also published at flower.codes