Buy
Buy

With a Subscription, click any sentence in the script to jump to that part of the video!

Login Subscribe

For our last trick, I want to introduce a bundle that's going to make our life awesome. And, for the first time, we are going to hook into Symfony.

Installing Maker Bundle

First, find your terminal, and install that bundle:

composer require maker --dev

Yep! That's a Flex alias for symfony/maker-bundle. And, in this case, "make" means - "make your life easier by generating code".

We know that the main purpose of a bundle is to give us services. And, that's true in this case too... but the purpose of these services isn't for us to use them directly, like in our controller. Nope, the purpose of these services is that they give us new bin/console commands:

php bin/console

Nice! About 10 new commands, capable of generating all kinds of things. And, more make commands are still being added.

Generating a new Command

So... let's try one! Let's use the MakerBundle to create our very own, custom bin/console command. Use:

php bin/console make:command

This will ask us for a command name - how about article:stats - we'll create a command that will return some stats about an article. And... it's done! We now have a shiny new src/Command/ArticleStatsCommand.php file. Open it!

... lines 1 - 2
namespace App\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
class ArticleStatsCommand extends Command
{
protected static $defaultName = 'article:stats';
protected function configure()
{
$this
->setDescription('Add a short description for your command')
->addArgument('arg1', InputArgument::OPTIONAL, 'Argument description')
->addOption('option1', null, InputOption::VALUE_NONE, 'Option description')
;
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$io = new SymfonyStyle($input, $output);
$argument = $input->getArgument('arg1');
if ($input->getOption('option1')) {
// ...
}
$io->success('You have a new command! Now make it your own! Pass --help to see your options.');
}
}

Hey! It even added some example code to get us started! Run:

php bin/console

And on top... yes! Symfony already sees our new article:stats command. Sweet! Um... so... let's try it!

php bin/console article:stats

It doesn't do much... yet - but it's already working.

Service autoconfigure

But... how does Symfony already know about this new command? I mean, is it scanning all of our files looking for command classes? Actually, no! And that's a good thing - that would be super slow!

Here's the answer. Remember: all of our classes in src/ are loaded as services:

... lines 1 - 5
services:
... lines 7 - 22
# makes classes in src/ available to be used as services
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../src/*'
exclude: '../src/{Entity,Migrations,Tests}'
... lines 28 - 37

Notice that our new class extends Symfony's base Command class:

... lines 1 - 4
use Symfony\Component\Console\Command\Command;
... lines 6 - 11
class ArticleStatsCommand extends Command
... lines 13 - 35
}

When the service was registered, Symfony noticed this and made sure that it included it as a command. This nice feature has a name - autoconfigure. It's not too important, but just like autowiring, this is activated thanks to a little bit of config in our services.yaml file:

... lines 1 - 5
services:
# default configuration for services in *this* file
_defaults:
... line 9
autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
... lines 11 - 37

It's just another way that you can avoid configuration, and keep working!

Next, let's have fun and make our command much more awesome!

Leave a comment!

  • 2018-05-31 Victor Bocharsky

    Yeah, probably so. Not sure what can you do then, probably that PowerShell ISE has some kind of configuration where this can be fixed, do not know :/

  • 2018-05-30 Raymond Dube

    I'm honestly not sure if this is a problem wiht MakerBundle, or with PowerShell ISE. I'm more inclined to blame ISE as it is working fine in a standalone PowerShell window

  • 2018-05-30 Victor Bocharsky

    Hey Raymond,

    Thanks for this notice. I personally haven't heard about this problem before. It makes sense to upgrade to the latest version of MakerBundle. If you still have this issue, feel free to open a bug in its repo with detailed steps to reproduce.

    Cheers!

  • 2018-05-29 Raymond Dube

    A quick note for those who may be using Windows10 PowerShell ISE.

    For whatver reason, it appears, at least on my system, that while in the ISE,the make:command doesn't execute properly and leaves you hanging at the "Choose a command name (e.g. app:some-thing):" prompt without allowing you to enter the command name.

    The good news, if you use the standalone PowerShell, this is not an issue.