Maker Bundle: Let's Generate Some Code!
Hats off for nearly making it through the first Symfony tutorial. You've taken a huge step toward building whatever you want on the web. To celebrate, I want to play with MakerBundle: Symfony's awesome tool for code generation.
Composer require vs require-dev
Let's get it installed:
composer require symfony/maker-bundle --dev
We haven't seen that --dev flag yet, but it's not that important. Move over and open composer.json. Thanks to the flag, instead of symfony/maker-bundle going under the require key, it was added down here under require-dev.
| { | |
| // ... lines 2 - 84 | |
| "require-dev": { | |
| // ... line 86 | |
| "symfony/maker-bundle": "^1.52", | |
| // ... lines 88 - 89 | |
| } | |
| } |
By default, when you run composer install, it will download everything under both require and require-dev. But require-dev is meant for packages that don't need to be available on production: packages that you only need when you're developing locally. That's because, when you do deploy, if you want, you can tell Composer:
Hey! Only install the packages under my
requirekey: don't install therequire-devstuff.
That can give you a small performance boost on production. But mostly, it's not a big deal.
The Maker Commands
Now, we just installed a bundle. Do you remember the main thing that bundles give us? That's right: services. This time, the services that MakerBundle gave us are services that provide new console commands. Drumroll please. Run:
php bin/console
Or, actually, I'll start running symfony console, which is the same thing. Thanks to the new bundle, we have a ton of commands that start with make! Commands for generating a security system, making a controller, generating doctrine entities to talk to the database, forms, listeners, a registration form.... lots and lots of stuff!
Generating a Console Command
Let's use one of these to make our own custom console command. Run:
symfony console make:command
This will interactively ask us about our command. Let's call it: app:ship-report. Done!
This created exactly one file: src/Command/ShipReportCommand.php. Let's go check that out!
| // ... lines 1 - 2 | |
| namespace App\Command; | |
| use Symfony\Component\Console\Attribute\AsCommand; | |
| 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; | |
| ( | |
| name: 'app:ship-report', | |
| description: 'Add a short description for your command', | |
| ) | |
| class ShipReportCommand extends Command | |
| { | |
| public function __construct() | |
| { | |
| parent::__construct(); | |
| } | |
| protected function configure(): void | |
| { | |
| $this | |
| ->addArgument('arg1', InputArgument::OPTIONAL, 'Argument description') | |
| ->addOption('option1', null, InputOption::VALUE_NONE, 'Option description') | |
| ; | |
| } | |
| protected function execute(InputInterface $input, OutputInterface $output): int | |
| { | |
| $io = new SymfonyStyle($input, $output); | |
| $arg1 = $input->getArgument('arg1'); | |
| if ($arg1) { | |
| $io->note(sprintf('You passed an argument: %s', $arg1)); | |
| } | |
| if ($input->getOption('option1')) { | |
| // ... | |
| } | |
| $io->success('You have a new command! Now make it your own! Pass --help to see your options.'); | |
| return Command::SUCCESS; | |
| } | |
| } |
Cool! This is a normal class - it is a service, by the way - but with an attribute above: #[AsCommand]. This tells Symfony:
Yo! See this service? It's not just a service: I would like you to include it in the list of console commands.
The attribute includes the name of the command and a description. Then the class itself has a configure() method where we can add arguments and options. But the main part is that, when somebody calls this command, Symfony will call execute().
This $io variable is cool. It lets us output things - like $this->note() or $this->success() - with different styles. And though we don't see it here, we can also ask the user questions interactively.
The best part? Just by creating this class, it's ready to use! Try it out:
symfony console app:ship-report
That's so cool! The message down here comes from the success message at the bottom of the command. And thanks to configure(), we have one argument called arg1. Arguments are string that we pass after the command, like:
symfony console app:ship-report ryan
It says:
You passed an argument: ryan
... which comes from this spot in the command.
Building a Progress Bar
There are a lot of fun things you can do with commands... and I want to play with one of them. One of the superpowers of the $io object is to create animated progress bars.
Imagine we're building a ship report... and it requires some heavy queries. So we want to show a progress bar on the screen. To do that, say $io->progressStart() and pass it however many rows of data we're looping through and handling. Let's pretend we're looping over 100 rows of data for this report.
Instead of looping over real data, create a fake loop with for. I'm even going to include the $i variable in the middle! Inside, to advance the progress bar, say $io->advance(). Then, here is where we would do our heavy query or heavy work. Fake that with a usleep(10000) to create a short pause.
After the loop, finish with $io->progressFinish().
| // ... lines 1 - 16 | |
| class ShipReportCommand extends Command | |
| { | |
| // ... lines 19 - 31 | |
| protected function execute(InputInterface $input, OutputInterface $output): int | |
| { | |
| // ... lines 34 - 44 | |
| $io->progressStart(100); | |
| for ($i = 0; $i < 100; ++$i) { | |
| $io->progressAdvance(); | |
| usleep(10000); | |
| } | |
| $io->progressFinish(); | |
| // ... lines 51 - 54 | |
| } | |
| } |
That's it! Spin over and give that a try:
symfony console app:ship-report ryan
Oh, that is so cool.
And... that's it people! Give yourself a high five... or, better, surprise a co-worker with a jumping high five! Then celebrate with a well-deserved beer, tea, walk around the block or frisbee match with your dog. Because... you did it! You took the first big step into being dangerous with Symfony. Then, come back and try this stuff out: play with it, build a blog, create a few static pages, anything. That will make a huge difference.
And if you ever have any questions, we watch the comment section below each video closely and answer everything. Also keep going! In the next tutorial, we're going to become even more dangerous by diving deeper into Symfony's configuration and services: the systems that drive everything you'll do in Symfony.
Alright, friends, see you next time!
37 Comments
This whole course was incredibly clear and helpful.
Two thumbs up!
Thanks @Sam35!
The course is amazing! Thank you so much 🥰
We're glad you liked it!
I am an enterprise developer with very little front-end knowledge, and following this course was super easy and very enlightening. It was presented in a fun way (live long and prosper ;-) and when I was stuck (once), Ryan responded very quickly. I am impressed and considering spending money to access the rest of the courses.
As a developer who is mostly doing ERP code work and interacting with a web developer team that manages our company web site written in Drupal (which is written in Symfony), this will help me communicate better with the off-shore dev team and also understand their responses. Hopefully I can also make some small code changes, but at the very least I may be able to understand some Drupal code better.
Finally I want to add, that I am pretty much a one man show at the company next to the CEO who also does some ERP code work. I am taking on many tasks that go far and beyond his capabilities by doing lots of research. We have two projects at the company that I intend to turn into Symfony projects. Both will heavily depend on database interaction with our ERP system. This should be fun!
So far I am very impressed with how easy coding in Symfony is, but now I need to take the leap to accessing database entities which is the meat and potato of my overall work.
Thank you, Ryan, for being a great presenter!
Hey Kay,
Thank you for such kind words about this course! You made our day ❤️
You will find the Doctrine (DB entities) course in the Symfony 7 track too: https://symfonycasts.com/tracks/symfony . However, the next one would be better to watch: https://symfonycasts.com/screencast/symfony-fundamentals/ - that will be the correct course order to follow :)
Cheers!
This course is exceptionally well designed. Thank you...
You're welcome :]
Nice sessions. There is a lot with Symfony that was unknown to me. The Stimulus and turbo are killers.
it is really dangerous now. See you in the next session. Thank you!
Hey @Abhi
In that case, I bet you'll love this other course https://symfonycasts.com/screencast/last-stack
Cheers!
I started with HTML, CSS, and JS two years ago. I've been using PHP and SQL for four months now. Now I discovered Symfony, and it's fantastic, just like this tutorial! I laughed a few times. I loved the phrase "Super Nice." Super Nice! Thanks!
I'm happy to hear it! I'll assure Ryan reads this :]
Really great work on this course and thanks for providing it for free. I think I'm hooked on Symfony now.
Hey Marshall,
Thank you for this feedback and your interest in SymfonyCasts tutorials! We're super happy to hear you liked this free course, and hearing that you're hooked on Symfony is 🖤
Happy coding with Symfony!
Cheers!
I love this series. When I first started learning Symfony, I was so confused. Now, I have a clear image of Symfony, and I am ready to dive deep into it
Hey mr_kava,
We're happy to hear you love it ❤️ Stay tuned for more cool tutorials :)
Cheers!
Great tutorial, thanks! Learned a lot, and yeah Symfony is cool
You're welcome!
Thanks for the course, this is great stuff
Hey Leed,
Thank you for your feedback!
Cheers!
Awesome! loved this first course! thank-you for putting it together!
Hey Richard,
Thank you for the kind words about this course! We're happy to hear you liked it! :)
Cheers!
A very busy week to successfully complete this course during it. Thank you very much!!!
Hey Erick,
You made it, well done! 👏
Cheers!
It is so nice and joyful to see Ryan back as the instructor in this course. Very handy content, expect to see many other new courses like that. Thanks to all SF team!
Hey @iclaborda!
Unfortunately, I'm not back as an instructor (this course was from before all the craziness), but I am slowly working more with Kevin (and our other behind-the-scenes helpers) to keep up the same quality and fun. And hopefully, to accelerate our content-creation pace! A lot of cool work happening!
Cheers!
Hey @iclaborda ,
Thank you for your feedback! ❤️ Stay tuned for more courses ;)
Cheers!
Great, Thanks a lot
Excellent, I've learned a lot and enjoyed it very much
Hey @tomoguchi ,
Thank you for your feedback! We're delighted to hear you enjoyed it!
Cheers!
Beautiful and very useful course. Thank you so much!
Hey Jared,
Thank you for your feedback! We're thrilled to hear you liked this course and that it was useful for you :)
Stay tuned for more content ;)
Cheers!
Hello,
Do you have any course for integration symfony+react +typescript together?
Hey @Mahmut-A
We have a tutorial about Symfony + React 16. React is integrated through Symfony Encore, which uses Webpack under the hoods. Ryan does not use Typescript in that tutorial but it should be easy to support it by configuring Webpack.
Tutorial link: https://symfonycasts.com/screencast/reactjs
Cheers!
thank you. I will try to follow below link also.
https://symfony.com/bundles/ux-react/current/index.html#usage
That was so good!
Thanks!
Hey Saidazim,
We're glad to hear this video was useful for you!
Cheers!
"Houston: no signs of life"
Start the conversation!