Building a Symfony 8 Application (and Shipping It on Laravel Cloud)
Chapters10
The host announces that Laravel Cloud now supports Symfony, and outlines two main tasks for the session: trying Symfony for the first time in years and deploying the app on the cloud. [00:04:15]
Learning Symfony 8 live, Nuno Maduro builds a PHPNews site from scratch and ships it on Laravel Cloud, comparing Doctrine, Twig, and routing ideas along the way.
Summary
Nuno Maduro dives into Symfony 8 from scratch, aiming to build a full PHPNews-like site with landing pages, an admin area, authentication, and article management. He starts by spinning up a Symfony 8 web app with the Symfony CLI, notes the folder structure (controllers, templates, migrations, and Doctrine integration), and quickly sketches a plan to compare Symfony basics with Laravel concepts. The stream showcases practical workflow choices: Twig templates with Tailwind CSS via CDN, Symfony’s routing attributes, and the Symfony Profiler for debugging, all while deploying locally with Symfony’s server and testing with PHPUnit. A core part of the journey is modeling data with Doctrine (User and Article entities, repositories, migrations) and wiring security (login/logout, form handling) using Symfony’s security layer and invocable console commands. Throughout, AI-assisted planning is leveraged in “plan mode,” guiding step-by-step file creation, migrations, and validation before moving forward. By midstream, the app supports admin CRUD for articles, public article views, and slug-based routing that auto-resolves Article entities, with form validation and lifecycle callbacks built into the entities. The finale demonstrates a real deployment on Laravel Cloud (PHP 8.5, Postgres 18 in prod, SQLite for dev) and shows the Symfony app running on the platform, confirming that Symfony 8 can play nicely with Laravel Cloud’s deployment flow while delivering a fully working admin and public interface.
Key Takeaways
- Using Symfony CLI with the web-app workflow (symfony new phpnews.com-8 --web-app) creates a traditional app skeleton with controllers, templates, and migrations.
- Doctrine integrates naturally into Symfony for data mapping; the workflow includes creating User and Article entities, repositories, and schema migrations that work across SQLite (dev) and Postgres 18 (prod).
- Symfony’s routing can leverage attributes on controllers for clean, declarative routes, reducing the need for traditional routes.php-like wiring.
- Symfony Profiler provides deep insight into HTTP requests, database queries, forms, and security flows, helping you diagnose issues in real time.
- Plan-mode with AI (plan, execute step, validate files) keeps the live build methodical, ensuring each change is reviewed before moving on.
- Public-facing routes render articles by slug, with Doctrine-based parameter conversion allowing automatic Article entity resolution by slug in routes.
- Laravel Cloud can host Symfony apps end-to-end (PHP 8.5, Postgres 18, migrations, asset handling via CDN), enabling smooth CI/CD via GitHub Actions and built-in deployment hooks.
Who Is This For?
Essential viewing for Symfony developers exploring Symfony 8, Doctrine-based data modeling, and deployment on Laravel Cloud. Also valuable for Laravel developers curious about Symfony routing, templates, and admin tooling in a live, step-by-step workflow.
Notable Quotes
"Today we are going to develop a PHP news website."
—Nuno sets the scope and domain for the live Symfony 8 project.
"Wow, this is badass, chat."
—Praising the Symfony Profiler’s capabilities as it’s demonstrated.
"Don’t use Docker. This is a very important, Shad."
—Emphasizing a preference for simplicity and local development flow.
"Attributes are goats, you know."
—Expressing preference for attribute-based routing over traditional routing files.
"We are using Symfony 8 for the win."
—Highlighting the chosen major version and the stream’s optimistic tone.
Questions This Video Answers
- How do you deploy a Symfony 8 app on Laravel Cloud and what changes are needed for prod databases?
- Can Symfony’s routing attributes replace routes.php in Laravel-style apps, and how does it affect controller organization?
- What role does Doctrine play in Symfony 8 authentication and admin CRUD work, and how does it compare to Laravel Eloquent?
Symfony 8Laravel CloudDoctrineTwigTailwind CSSSymfony CLIPHP 8.5PostgreSQL 18SQLiteDoctrine Migrations/Entities`,`Symfony Profiler`,`Attribute Routing`
Full Transcript
Black jump. All right. Yeah. Black. Ah. Wonder. Hey, hey, hey, hey, hey, hey, hey, hey, hey, hey, hey, hey, hey. What's up, beautiful PHP family? Welcome back to another live stream. How everyone is feeling today? It's literally Friday, man. Hope everyone is about to have a good weekend. Badabin, what's up, dude? H a hml is gross. I think it's gross, but it's worse than that. All right, that is that is even worse than that. So, we're chilling. We're chilling. Winnie 26, what's up, dude? Nice to see you. How you doing today? I'm doing fantastic. Thanks for asking, man.
LDS is saying the following. Good to be here from Nigeria. Welcome, man. Welcome to my live stream. Jarg day, what's up, dude? Nice to see you. Wie, what's up, dude? Nice to see you. Pick and flow. Thank you so much for becoming a premium sponsor. Always supporting me for from since day one. I really appreciate you. You are absolutely awesome. Yonis from Morocco. What's up, dude? How dumpsters neighbor? Well, what's up, dude? Everyone is feeling fantastic, man. It's awesome. That's awesome. Dinosaur, what's up? Schemer Luiz, nice to see you all. Daniel, what's up, dude? Welcome back, chat.
And today, today, Shad, we have an amazing live stream. Okay, so recently, I don't know if you guys are aware of this, but recently Laravel Cloud added support to Symfony on Laravel Cloud, meaning that Symfony developers can actually deploy their apps on Laravel Cloud. Will we just work? Now, we are going to do two things today. Okay, number one, we are going to try Symfony for the very first time in [ __ ] 20 years, man. The last time I've tried Symfony was I was even working at Alolia back in the day. So that was a long time ago and you know I barely remember anything.
So this will be a new experience for me and maybe for some of you as well. I don't know if we have experienced Symfony developers on the chat. If you have tried or if you used or if you know Symfony just type yes. If you don't know Symphony, if you are like me, like a newbie on Symfony, just type no because you are about to discover Symphony for the first time like I am today. Okay. So, the only thing I have done so far went to symfony.com. I have created a repo so we can work together.
Call it symfony 8 example. Here we go. Here we go. Okay. Symphfony. Oh, Symphony Expert here. I see. I see. We have a couple of Symphony Symphony Experts. You guys are going to help me out, man. because I know [ __ ] about Symfony. Okay, the only thing I know about Symfony is that they use Doctrine behind the scenes. They have a bunch of configuration files. That's the only thing I know. Okay, so we'll be will be kind of new for me all of this story. Okay, and the goal is actually developing a full thing together. Okay, so we have cloud code, we have GitHub, we have PHPtorm, we have the full thing here to be able to develop a full a bul an application.
Okay, and I want to kind of develop a website called it phpnews.com. Okay, so that's what we're going to do. a phpnews.com website. So, we have a landing page with a bunch of articles. We are going to have an admin section. We are going to have an authentification. It'll be awesome. Okay. Okay. We are going to develop a PHP news website. So, you guys know Laravel news. We are going to do the PHP news. Okay. That's the goal. Okay. We are going to use cloud code. We are going to use PHPtorm, PHP 8.5, all the greatest stuff here.
Okay. We are going to do some testing. That will be awesome, chat. It will be absolutely awesome. Okay, we have a few people like most of you guys are also newbies on symfony which is good man you know which is absolutely good. Okay, I'm also a newbie on symphfony so we are going to discover all of this together. Okay, okay, okay. So chat before we get started let's say thanks to our sponsors and we have a new sponsor a new sponsor. So say welcome to the family SER API chat. And SER API is basically a service that allows you to scrap Google or any any other search engine like Amazon and everything.
So you can just basically use this service and pay a monthly fee. And if you do that, you have nice scrapping uh that you can do to Google. They really just work. They have a bunch of companies that trust them already. Check them out. Okay? Check them out. So basically if you want to kind of query Google you can use this beautiful API and it really just works. Okay so wer API for supporting my work and you guys now can also uh I have literally used this product before accepting this sponsorship and it it's legit.
It's legit really just works check them out. Okay Mail trap of course the company who have this beautiful development email solution they now have production emails too. Check them out. Mail trap for the win. Redberry International, the digital agency that works with Laravel. They work with Vue. They're absolutely awesome and fast. Check them out as well. Jet Brains International. The Jet Brains, of course, you guys know Jet Brains. Okay. Jet Brains is a company behind the beautiful editor PHP Storm. They're absolutely awesome. Titan, of course, they build and rescue web apps and development teams. They're company behind the book Laavel up and running from Matt Staer.
Check them out. Okay. Code Rabbit, of course, if you want to have some nice AI reviewing your code through pull requests, this is your partner. And we have also Devon AI. If you want to offload some tasks through Slack or through linear, this just works. You just say, "Davin, do this and you will get [ __ ] happen." Okay, Shad. By the way, we have a new YouTube video. Call it native PHP, which is, by the way, my best performing video so far on the channel. Okay, native PHP build mobile applications with PHP and Lavel and there is something you guys can do for me.
Okay, if you guys love me, if you guys love my work, the only thing you have to do to support my work is go to this video, watch the video, and if you enjoy the video, you just have to click on this like button. Okay, literally takes no time whatsoever. It's free. You just click on this beautiful like button and that's it. That that's the only thing I'm asking. Okay, you rock. You have more sponsor than an important soccer team. Thank you. Thank you. Roberto Inso is saying the following. My agent is better for code reviews.
That's right. Your agent can also do code reviews. Boom. Boom. Boom. What's up, Symfony lovers? Welcome to the chat. By the way, chat, if you just arrived, my name is Nun Maduro, PHP Laravel developer. I'm also Laravel Core team member trying for the first time in 10 years. Symfony. Okay, I'm going to try Symphfony for the first time in 10 years. Um, I don't even know what to expect, but this will be an awesome live stream hopefully. And at the very end, we are going to deploy this Symfony application on Laravel Cloud. And with any luck, this will just work.
Okay, with any luck. All right, let's get started. Are you guys excited? I'm excited. Type yes if you're excited. I'm super excited. Okay, chat. Insanely excited here. Let's go. Let's go. Let's go. Let's go. All right. So, let's open the symphfony.com website. This is the website, by the way, guys. In case you guys want to check it out, okay, check it out. symphfony.com. Build with confidence at any scale. What we can do with Symfony build web apps. I I suppose yeah, web application development also CLA development. Actually, I do think that for developing CLA applications, Symfony console component is actually the most powerful in the planet.
Okay, so it really just works. We can also develop APIs apparently with Symfony. They have 36 billion downloads. Okay. They also power a bunch of these PHP ecosystem frameworks. Okay. They power frameworks like Magento. They also power some of the components in Laravel. So massive respect for Symfony by the way. I have massive respect for the people behind the Symfony world. Okay. And today we are developing a web app. So the only thing I have done so far is ran this command. Okay. Okay. So when you start a new a new symfony application you can actually the there is actually multiple paths you can take.
Okay I have taken the path of using the symfony CLI. Okay so the symfony CLI is something that you install globally via brew for example and then suddenly you have access to this beautiful symony CLA CLI uh application. Okay, this is basically the artisan or the Laravel CLI that you also ship at Laravel. Okay, and obviously with the Symfony CLI you can do multiple things including starting a new project which is exactly what I have done. I have typed this thing called it symfony new phpnews.com- version 8 because we want to use the symfony 8 version- web app.
Now I'm not super familiar between the difference between using this flag or not using this flag but I have used this flag because it tells me that I'm I'm creating a traditional web application. So I want controllers, I want views. Um so we are going to use that. Okay. Drupal is also powered by many of the Symfony components. That's right. Okay. CVTML is saying but don't use d- version but use d- web app. Yeah that's what we are we have used so far. Okay. So I just went to the console and I have typed this command.
Okay. And the outcome is the following. Okay. This is the outcome that I got when I've typed Symfony new application. Okay. Now there is a few things here that immediately are different from Laravel. I don't think they are bad or good. They are just different. And I want to tell you guys something very important when working with web frameworks. Web frameworks at least the good ones. Okay. At least the good ones, shots fired to some of the JavaScript frameworks we see out there. At least the good ones, they come with a few things out of the box.
I expect to find here authentification, caching, database layer. So I expect kind of the basics to be built in on this framework. Okay. Uh Laravel comes with that. I expect Symfony to equally come with that. And honestly, if you if you choose a web framework, just choose a web framework that comes with all of all of this [ __ ] Okay? And many of the good web frameworks they come with that. Okay, we're talking about Django, we're talking about Rails. Um, Symfony, of course, I expect to come with that too. And Laravel comes with that as well.
Okay, beautiful, beautiful, beautiful. Jill Dwart is saying the following. If you use without the web app, it installs the application with minimal files as possible. That's interesting. Okay. So, what Jill Dwart is saying is that because I have used the D- web app, it came with a bunch of little little folders that it might not be necessary if I'm building a CLI app. Okay. But of course, because I'm building a traditional web app, I can see already many of the folders I would expect like controllers, entities, and [ __ ] like that. Okay. Thank you, Gildo, for that feedback.
I really appreciate is saying, "Nuno, be careful. Symfony is very powerful." Oh, thank you. Thank you. I will be careful. coding bat is saying the following. I am junior in Symfony lover. This framework is so cool. CLI is so powerful. It's so easy and fast to build things. Boom boom bada boom bada boom. So web app is not the default. Well, apparently let's go back to the documentation. Okay, chat. By the way, this stream will be slow intentionally. It might take more than expected because the goal is that we learn Symfony. The goal is not that we just build something and just deploy it.
Okay, so we are going to take our time to understand all the all of the options here and I hope you guys appreciate and also want that pace. So apparently here says the following run this command is actually the very first one if you are building a traditional web application which is exactly what we are doing. So I'm going to run this command with d- web app is this is what I have done so far and of course all the way down if I'm building a micros service or a console application or an API. Okay, so if you guys want to build an API, you just work.
So just run this command but without web app. Okay, now this is with a symfony CLI. You can also use if you want to apparently the composer create project thing. Okay, just like you can do this with the level as well. Easy peasy lemon squeezy. Let's go back into the PHP storm. I kind of want to see some of the files that got created here. Okay, I want to kind of compare the folder structure uh with Lavel if I can because it's the only thing I can compare with. Okay, how the Symfony DI work like Laval?
I expect the Symfony container to work exactly like the Lavl one. So I expect out resolution by default and well hopefully I don't have to [ __ ] specify every single thing that can be injected and it will just work. That's only that's I do expect that. Okay. Okay. El Treba 97 is saying the following. Wait, by app you mean REST API? No, I mean a web app with um views, with layouts, with controllers, with tweak, with all that [ __ ] That's what I do expect. Okay, CVTML is saying that it's the container works exactly like Laravel one to one.
So, you know, that's what I was expecting as well. Okay, that's what I was expecting. Now, let's take a look at the files we have here. So, we have this file called it assets. Okay, assets which is basically JavaScript files in Lavel. You find this under resources um JavaScript. So you know just a different directory for the assets we have been. Okay. So currently all the CLI or their artisan is placed at bin console level. So I can type here like this I expect. Here we go. Here we go. So dash um you know bin console- version displays symfony uh 8.0.5 and this is the equivalent of artisan.
We also have phpunit. That's a great like weird thing like why do we have phpunit at this level. Interesting. I would expect phpunit to be just at vendor bin phpunit level though. Okay. I'm confused. I'm not really sure what this thing does differently. Oh it does nothing differently. It just requires phpunit. Okay. Gotcha. Gotcha. Gotcha. Yeah. I don't really understand why do we have this PHP unit here. Like I would expect to access PHP unit through vendor bin PHP unit but you know bada boom bada boom. It's just for the CLI. Gotcha. Just an allias basically right.
It's not like we have to use it. But all right. [ __ ] 100 people on YouTube. YouTube people go all the way down and click like on this video. It's super important so we can show the world how cool PHP is. Okay, so everyone YouTube people just stop what you are doing. Go all the way down and click like on this video and subscribe the channel if you are enjoying this content today. Okay, that's really important. It also means the world to me. So we have a couple of allias to use on the console. Okay, easy peasy lemon squeezy.
We have a bunch of configuration folders. uh currently. Okay. Now, this is one of the little things that I was kind of expecting to find on Symfony and I kind of don't really like I don't like the fact that we have a just a bunch of configuration files just being published on my app. So, you know, I kind of would like Symfony to just have this at vendor level, you know, cuz I don't really care about these options in in their defaults, you know. But um yeah, we have a bunch of configuration files for the messenger component for the monologue which is logging for the notifier which is apparently emails and slack and [ __ ] like that.
Um what else we have? We have routing uh security a bunch of stuff here being uh published by default including the tweet configuration as well. Okay, so this is equivalent of the config app.php database.php PHP like those files that you typically see on Laravel see have the same thing but under the YAMLy file and this is actually a good question for you all. What do you guys personally think about files? If you like it, type yes. If you don't like it, type no. I am okay with YAML. I am okay with YL even though I think I prefer PHP because I'm just used to it.
Okay. But yeah, they use ML files for configuration. Okay. We see a few me. We see a yes. We see YAML sucks. We see a no. Okay. Luis Cruz is saying the configuration files in Laravel are more cleaner. Yeah. You know it's also like what you are used to you know and this is just we are in our comfort zone and immediately if someone just gives you a YAML file and you haven't seen it yet you will think [ __ ] that sucks but uh the reality is that probably like the symfony people are super okay with this you know it's okay yl okay yeah so the difference here chat is that um yeah symfony uses yl uses PHP files One interesting thing here is that we equally see a couple of PHP files at this level too.
That's interesting though. That's interesting. So there's a couple of PHP files here as well. Okay, a couple of PHP files. I don't know exactly what they are doing. I assume what they are doing here is that they allow me to configure how do I want to use bundles. By the way, bundles means packages in the Laravel world. Okay. So, Symfony have this approach of calling bundles um their packages. So, if you were to compare with Laravel, a bundle would be like Socialite or Octane or you know like our packages but they call it bundles. Okay.
So, uh that's all good. Uh what else we have? So, let's close this stuff. Okay. That's a configuration folder. We have migrations. Okay. Migrations being placed at root level. While in Laravel we have database migrations. So that's all good. We have the public folder which comes with the index.php file. So that's all good. We have controllers entities. Now one really interesting thing here shad is that the way the namespace controllers is without the s without the plural. So in Laravel you see app controllers or app http controllers and you see app http models or whatever being plural and on symfony they have this in the singular way.
So there is there is no controller that is controller and entity and repository. Okay. And that's actually the first thing I want to do is create a new controller. What else we have? We have templates which in Laravel it's placed at resources uh views. Here it's placed at root level. We have tests which we don't have a single test. So we have to work on that. We have translations. We have var. Interesting. They take the Linux approach to place all of the temporary folders like [ __ ] like uh logs and [ __ ] like that and caching and everything.
That's very interesting. Very very interesting. Bundle is a package not a plug-in. Okay. The battle is Eloquent versus Doctrine. Totally different things. Okay. So, Eloquent is active record. Uh doctrine is data mapper. We we can talk about this once we start using um those two projects here today. Okay. Uh tabels tabs and yaml are a little bit annoying. Lol. Tabs. What do you mean by tabs and yaml? Oh, like the giving a space for the configuration. Got you. All right, chat. Let's move forward. Uh we have var, we have vendor, we have a couple of files.
So, this is a kind of expected. We have a uh for the current thing. We have a just for development and we have a for testing. Expected composer.json. Okay. Composer.json. So all of the symfony little components being explicitly set here. This is interesting. Laravel does another approach instead which is just Lavl framework and that package framework thing just includes all of the little packages inside. Okay. What else we have? Bada boom bada boom bada boom doctrine which is their active their data mapper implementation for the database. What else we have? We have twig which is laval blade.
Uh going all the way down and we have all the poly fields. Interesting. Boom. Boom. Boom. Raoom. I think that's it. We have they have they choose PHPUnit as testing framework which is okay. And a couple of other uh symfony components for local development. Okay. Browser kit which is probably like past 4 or laval dusk. Uh stopwatch web profiler. Okay. That's interesting. I think that's it. It's time to move forward. It's time to actually create our first controller. Let's do that. All right. You haven't used Symfony since 2015. Well, welcome to the club. Uh, same thing.
I haven't tried Symphony for a while. By the way, Shad, I really appreciate we have more than 100 people watching the live stream. Go all the way down and click like on this video. Insanely important. Okay, insanely important. Let's create our first controller. That's the first thing we are going to do. Okay, so I'm going to go here and I'm going to just say the following. I'm going to type here sh uh first commit. So, basically just committing the skeleton that got proposed to me when typing symphony in new app. Okay, nothing really crazy. And let's just commit this stuff to main.
Again, this repo is open source. Let me just share it to you real quick. Symfony 8 example. Here we go. Right here. Easy peasy. First commit. Easy peasy. Here we go. Here we go. Here we go. Here we go. So, this is really right here. Let's go back into the console. Let's actually create our first controller. That's the first thing I want to do. Let me place this right here. Here we go. So, bada boom, bada boom, bada boom. Uh, let's go all the way down. Set up that [ __ ] I don't care about that. Running Symfony applications.
Okay, running Symfony applications. So, in production, you need to use a web service like engine X or Apache. But locally, use this little thing called it symfony server start. Let's use that. Okay, let's go here. Go all the way up and just open a new tab real quick and type symfony server start. because that's starting a web server locally for me. Okay, a web server locally. I'm going to go all the way up and apparently this web server is running on PHP 8.5. And here I can just copy this, open on the browser and hopefully we see Symfony 8.
Bada boom bada boom. Really just works. And um nice welcome page by the way. I like this welcome page. What do you guys think? It's okay. Right. This is the equivalent of artisan serve. Exactly. The file got included on Git. That's weird. If that happened, that's weird. Wait, what? Uh, that's not Maybe let's see. This is a symfony thing. That's not expected. Oh, the file. Maybe it's like expected to be included, but not the.local. local. This must be a a Symfony thing, you know. So, what they have here is that the dove in.lo is not included, but this one gets included.
That's really weird, by the way. Well, maybe maybe it's not weird because if you want to run this on the CI, you kind of need this. Um, yeah. I don't know. This must be a symfony thing. Let's just ignore it for now, I think. Hit that like button. Exactly, Domino Soros. Hit that like button. By the way, chat, if you just arrived, my name is Nuno, a PHP and lot of health developer trying Symphony for the first time in 10 years. If you are enjoying today's live stream, go all the way down and click like on this video.
Insanely important. Also, subscribe to the channel if you want to see this number going up. You see this number? It will go up if you subscribe to the channel. All right, so we got the Symfony welcome page. Your application is ready. Thank you. Thank you. You are seeing this homepage because the homepage URL is not configured and debug mode is enabled. Create your first page to replace a placeholder. Create your first page in Symfony. Ah, interesting. Create a page router and controller. Suppose you want to create a lucky number route that generates a lucky well random number and prints it.
To do that, just create a controller class and the number method inside it. All right, I'm going to just copy this and I'm going to go into this controller thing. I think I'm going to create this lucky controller.php file. I'm going to place this. Okay. Uh, what is this? Oh, I want to Wait, what? PHP storm. I'm using PHP 8.5. What do you mean? What the [ __ ] Let's fix this real quick. Oh my god. PHP Storm. Come on. Let me click on that place without any problems. Uh uh uh uh. Can I PHP Storm? You are disappointing me now a little bit.
Would be really cool if you allow me to click here. Jesus Christ. Can I type PHP version? Let me see. PHP version. Of course, I cannot type PHP version. Jesus Christ. All right, let's just do this for now. What happens if I do read only class? Will PHP storm complaining too? Of course. Uh, more actions switch to What the [ __ ] Oh my god. Leave me alone. PHP is so bad nowadays. It's not bad. No, PHP Storm is the goat, man. You just have some weird [ __ ] sometimes. Okay, everyone have weird [ __ ] Honestly, I'm trying to switch to PHP 8.5 and I cannot.
I'm going to use a PHP like um like a PHP 5 thing. So then I can switch to that. More actions. Switch to PHP 4. All right, let's just keep this for now. Jesus Christ. Boom. It's on the composer. Oh, really? No. Composer is already on PHP 8.5 hopefully. Oh, we want to be on PHP 8.5 chat. Here we go. All right. So, we're good to go. We are creating a random lucky controller real quick. Uh, so that's just working. Now, how do I cable this on the routing thing? Of course, it's the next piece of the documentation.
I just use this route thing all the way top. Bam, bam, bam. And then I use this attribute. [ __ ] I'm going to tell you something. Okay, I'm going to tell you something insanely important. Okay, I kind of wish that in Laravel we would use this [ __ ] too. Okay, I honestly don't understand why the Laravel community is so connected to the [ __ ] routes.php file when something like this is just so much better. Okay, I have done a I have done a pull request uh literally a couple years ago to Laravel in the community just put a bunch of thumbs down because they like the brows.php.
So maybe like let's do let's do a let's let's see what you guys think. Okay, if you prefer the attributes approach, type attributes. If you prefer the routes.php file like we have on Laravel, type routes.php file. I like attributes, but I want to see what you guys think. Okay. Yeah, I think attributes. Everyone loves attributes, man. You know, you know, everyone loves attributes. I love attributes, too, man. We need to revisit this at Laravel because attributes are goats, you know. Oh, we see a few people preferring routes.php. Now, there is a question though about attributes, which is if you want to apply like a group middleware, for example.
So, you have a bunch of controllers and you want the entire folder to be under a middleware. That is a question that potentially we could make here, you know, like how the hell do you do I do that even with attributes? So maybe both is actually a good approach like Ricky is saying. That's true. That's true. Maybe like both is the correct approach here. So I just have done that. Now it would be kind of cool if Symphfony would automatically just work from this point. Okay. So let's go here into the lucky number and see if we see a lucky number on the browser.
Okay. So the only thing I will do is this. Look at that. Lucky number 97. [ __ ] yeah. Really just works. Nice, nice, nice. So, Symfony apparently automatically will through this attribute, we'll just understand this. So, we'll scan the controller folder and just do that for us. That's cool, man. W Symfony chat W Symfony. What else we have? Oh, what do we have here? What is this [ __ ] Oh my god. Is this like Laravel debug bar? This is Lavel debug. Holy [ __ ] This is big. Oh, this is called symfony profiler. Shad. Wow. That's badass, by the way.
This is badass, chat. Wow. Wow, that's a lot of [ __ ] No calls to validator were collected. There is forms, exceptions, cast, translation, security, HTTP client, doctrine, debug, messages, email notifications, and serializer. Wow, this is not bad, I must say. Okay, this is pretty cool. Can I see the queries that got made in [ __ ] like that? That's not bad. That's not bad at all, honestly. Wow. And I can also see all of this [ __ ] I want to I wonder if I have an exception. Let's throw an exception chat real quick. Throw new subscribe this channel. If you are enjoying the stream, okay, so I'm going to throw an exception that does not exist.
I expect this to literally just throw an exception. Let me just close this lucky number. Okay. Attempted to load class. Subscribe this channel if you are enjoying the stream from N space. So this is does not exist. So this is the equivalent of the page we have on Laravel 2. But we also have this thing all the way down which allows me to debug the exception. That's interesting. We can see the logs where it came from. All of the [ __ ] All right. [ __ ] W Symfony Profiler. Okay, everyone typing W Symfony Profiler because this is actually cool.
Okay, I think like in terms of taste, it could be a little bit more appealing in terms of more beautiful, but in terms of functionality, it's there. Everyone Symphfony W Symfony Profiler. Okay. Xdebug inside. What do you mean? Wait, what? No, I don't I don't have XDbug. It would be cool to have XD bug inside, but we don't have that. We don't have that. Okay, so props to this [ __ ] This [ __ ] is cool, by the way. Okay, this [ __ ] is cool. All right, what else we have? So, I just throw an exception that's working. Bada boom, bada boom, bada boom.
What else? Let's go all the way up and see uh what else gets suggested to try it out. By the way, Shad, we need to talk about this AI made thing. So I was just literally opening links and [ __ ] like that and I was wondering okay maybe we are going to use cloud code to develop this project but does symfony have some sort of laval boost now I opened this symfony AI mate and I need you guys a symfony experts to explain me is this the equivalent of laval boost like will this just make my symfony developer better if I use the mate component my Syfony development experience better.
It's not like Boost. It's more like Laravel AI SDK. Oh, that's interesting. Oh, okay. So, I don't need this. I don't need to install this [ __ ] right? Because when I went all the way down, I'm going to explain you why do I think this is like Symfony Boost or whatever. Because when I went all the way down, I see a thing called it. There we go. Symfony Bridge. Okay. And apparently like if I can if I install this it will deliver container introspection in profiler data tool. Okay. So no needed. Okay. [ __ ] You guys don't think I need this thing.
Okay. Let's not install this then. Okay. Well, uh, reap symfony mate. I don't know what this is, but apparently it's not necessary, I guess. Okay. Let's just close this. Okay. All right. Next step. Bada boom. Bada boom. Bada boom. how to install uh packages and [ __ ] like that. I think it's the t this is the time to just explore one more few things. I want to kind of talk about this symfony check requirements. So basically before running that Symfony new app, I have run this thing called it symfony check requirements and apparently this will tell me if my PHP installation is kind of ready for Symfony.
And I got this message telling me that we are good. What else we have? Uh D. We have this PHP bin console about. Let's run this real quick to see the output. Okay. Tells me a little bit about my application. Similar probably very similar to PHP artisan about. Tells me the Symfony app I'm using when it comes to the end. Blah blah blah blah blah kernel [ __ ] We don't care about any of that. All good. All good. All good. And this we have tried it already. All right. So, it's time to kind of start developing the application.
I think I'm going to just discard this file because we no longer need it. Why do we have Why do we have four changed files? My GitHub UI is just getting broken. Here we go. Okay, so we're good to go. Um, we don't have anything here. The next step is actually using cloud code and make sure. Let me just move this to PHP 8.5 real quick. Sure. Uses PHP 8.5. Bam. Bam. Bam. Commit this [ __ ] Go back. Let's open cloud code and let's actually go into plan mode. And this is just the hard reality shed.
People just use cloud code all the time to develop apps right now. And this shrimp will be no different from that. Okay. So, we are going to jump into plan mode kind of uh have a nice plan explain AI that we are learning Symfony. So, we want to go slowly but surely and at the same time we just go insanely slow. Okay. So, what we need here, let me just open here my notes real quick so I don't forget anything. All right. So, let's say the following. We are building together a website uh called it uh phpnews.com.
Okay. At the same time, we are learning uh Symfony 8. So, be sure to explain all of the tech options you take on this project. Regarding the plan, I want you to execute the plan very slowly. Be sure to ask me for validations of the steps before moving to the next step. I want to check all files. What else we need? Uh so we need front end. So of course for the front end by the way does symfony does symfony people are super into tuin css this is just a yes right like symfony people just say just say that to me we are using teloon CSS for this [ __ ] right just confirm to me by the way okay I would really appreciate that I mean I hope so right I hope everyone in symphony world is like into tailwind CSS develop an app that uh earns a Lambo Oh my god.
All right. So, apparently everyone is using tailwind CSS. So, let's just say the following. The front end should be using by the way, what we're going to use for the front end. I think I want to use Twig, but I want to make sure we are in the right place. So, I went to this Symfony UX page and apparently on Symfony, there is multiple UX options. So, we can obviously go to React, we can go to Vue.js, GS we can go to spelt but there is also other stuff here which got me a little bit confused like live components we see turbo we see stimulus and we see tweak components I was thinking about using twig like back in the days which is the equivalent of laval blade so what do you guys think I think we should go for twig and just tweak in CSS like keeping it stupidly simple mazeka is saying that twig is like played with some changes yeah I think we should goes for twig start with twig okay let's go twig Okay.
Twig, twig, twig, twig, twig. So, let's say the following to cloth code. The front end should be on Twig plus Tailwind CSS. Include Tailwind CSS uh via CDN. So, I don't want a JavaScript pipeline here. We don't want JavaScript chat. Wigg. Yeah, exactly. Wigg W Simplicity. [ __ ] uh a JavaScript pipeline. We don't need that. Okay. We don't need that. We may use stimulus at the end but you know at the end. So someone in the chat is saying that tweak turbo and stimulus can can achieve stuff like reacting view. Yeah I think like I don't you know I don't want to kind of pretend that I know what I'm talking about but I believe Symfony have their own livewire [ __ ] Okay they they I mean livewire you guys you guys may think that LiveWire is like totally new and whatever but you know this frameworks they also have their LiveWire [ __ ] Okay.
So, Symphony have this their live wire probably like Turbo or Stimulus this will be live wire behind the scenes. I don't know but like on on other frameworks they also have their own LiveWire version um as well. Yeah, Stimulus is their LiveWire. Yeah, I was kind of expecting that you know LiveWire is dope of course but uh what else? Let's go back. So, the front end will be on Tweaked Tailwind CSS include Tailwind CSS via CDN. What else we need? By the way, Tik Tockers, what's up? Nice to see you all, man. I'm sorry I was not paying attention, but welcome to the live stream.
Okay. So, uh authentia console command accepting uh uh email and a password of course allow via slashlo. uh this admin to log in. Okay, I think that's it for O. Uh yes, yes, yes, yes. Um what else? What else we need? Chat, what else we need here? Uh so we have that, we have that boom, bada boom, bada bad. The admin can create articles, can edit articles, can delete articles as well. So what else we need here? And I think that's it. Yep, yep, yep, yep. And don't use Docker. Don't use Docker. Very important, Shad.
This is probably Oh, by the way, we also need logout. Uh, plus logout. Don't use Docker. This is a very important one. Sh. Okay. If we want productivity, if you want to be fast and move like, don't use Docker. Okay. Just don't. For the database, use SQLite. However, in production, we are going to use PGSQL version 18. Okay, we're going with SQLite. Keep it stupidly simple. Okay. Okay. Okay. Uh, forget password. Yes, I forgot the No, I didn't forgot the the password. It's at the end. You probably cannot see it. It's right there. Let me show you.
Let me show you. Let me show you. Here we go. You guys can see it now. You guys can see it now. What is easy admin? I think like um if easy admin is the equivalent of filament and nova and whatever I don't want to use it because I kind of want to build it myself the back end. I understand that easy admin may give me like [ __ ] productivity under the hood on the admin side but I kind of want to keep it simple if you guys don't mind and kind of build the back end myself so I can learn in the process.
Is that okay? Type yes if it's okay. Okay. Type super yes. W yes if you guys think it's okay. I'm doing fantastic. By the way, Chad, we have more than 150 people watching this live stream. Insanely important, Chad. Stop everything you are doing. Go all the way down and click like on this video, but also subscribe the channel to see this number going up. Okay. If you subscribe to the channel, this number is going up. It will be awesome. Okay. Okay. Okay. Okay. Ba boom, bada boom, bada boom, bada boom. So, don't use Docker, use SQLite, of course.
That's an insanely productivity tip. Uh, what else? Boom. Boom boom boom. I think we ready, Shad. Did I forget anything? It's not like we cannot do it later, but uh did I forgot anything? Were we good to go? Now, very important thing, Shad. This is a master class in terms of productivity with cloth code. When you prompt for something like this, you always want to be on plan mode. You see this thing right here all the way down? Plan mode. Super important. Okay. So, we ask AI, but she will deliver to us a plan and we validate the plan.
Okay? We validate the plan. So AI will start just moving through the codebase. Here we go. We just allow everything. Yes, you can read. Yes, you can read. Yes, you can find. We just allow everything. It's just exploring the codebase getting familiar with Symfony 8 in with the current existing files. But then we are going to validate the plan and kind of also validate files one by one using this GitHub UI desktop situation. Okay. Okay. Okay, let's take a moment to read the chat while AI is cooking. So AI is cooking as we speak. Okay, as we speak.
And we are going to validate every single file AI will output. Okay, let's see how AI will solve this. Hopefully we will solve this very very very slowly. Okay, and I kind of forgot to tell AI that I'm learning Symfony 8, I think. So what's up Shiman? Nice to see you. Sim, what's up? Nice to see you as well. Learn the basics and use AI to generate the compos file if you have it too. Ba. Let's cook it, man. I'm so ready. So, what we want to build today, by the way, Shad, if you just arrived, is a phpnews.com website.
Okay, and we are using Symfony 8. Okay, Symfony 8 for the win. Okay, we just saw the Symfony Profiler situation, which is in my opinion the best thing I've seen so far. Okay, I don't know what you guys think, but in my opinion, the Symfony Profiler situation, it's indeed the best thing I have seen so far. Okay, looks really badass if I'm going to be honest with you. So, I don't know who have developed the symphony profile thing, but props to them. Okay, props to them. Bada boom, bada boom, bada boom. [ __ ] Today, I went five day I went five times to the gym this week, man.
I'm feeling so strong, man. Like so strong, tired at the same time. Try the symfony console as well. Dude, I have actually developed uh something called it laval zero, which is on top of symfony console. Okay, I'm very very familiar with the symfony console component. I'm also familiar with the fact that it's one of the best components out there. Okay. Okay. So, AI is still cooking. It's thinking. It's thinking. Gate and policy stuff is handled via YAML.configuration file. Uh in Laravel, I'm not fan of policies or gates. Okay. I don't know what are gates and policies on Symfony, but if they look like Laravel, I don't like them.
Okay. Symfony Profile. Meet Tech is just saying Symfony Profiler has at least six, seven years with that design. Yeah, I think the design is the only thing I would change here. Okay. Uh the design of Symfony Profiler is not super appealing. I think this is like [ __ ] 10 years old in terms of, you know, in terms of being pretty. It's 67. Let's go. 67 chat. Here we go. I agree with 67. Man, my nephew is just saying that [ __ ] all the time. I'm still yet to understand what it what does mean what does mean. By the way, Shad, we have a new YouTube video about native PHP.
If you want to build mobile applications with PHP and Laravel, check this video out. I would really appreciate that if you enjoyed the video, just click on this like button. [ __ ] takes no time whatsoever and it would means the world to me. Okay, it's still planning. Holy [ __ ] Cloud code is taking a while. Okay, it's taking a while. Probably getting familiar with doctrine and [ __ ] like that. That's why boost is so important on Laravel kind of speeds things a little bit. Uh so, you know, but let's see how it goes. Let's see how it goes.
The profiler has at least dark mode. It does. Were we in dark mode though? Oh, we are on dark mode. Okay, that's interesting. That's interesting. Can someone explain me what 670 means? Uh, we don't know that. That's the whole point is that nobody knows. Okay, but my ne my nephew is just saying that [ __ ] all the time. Still yet to understand. Let him cook. Let him cook. Let's see what Cloud Code is doing. Yeah, still cooking. Still cooking, chat. By the way, again, the plan was that we give Cloud Code the plan. it will deliver the plan to us and then we go step by step reviewing every single change of this plan.
Okay, we are going to walk through doctrine. Okay, doctrine versus eloquent. We are going to walk through the controller situation. We are going to see the container situation, the tweak stuff. We are going to see all of that in detail. Okay, this won't be like just do it and push. Okay, we are going to dive into all the small details. Okay. Now, uh, regarding the the skeleton, I'm going to I'm going to be honest with you. That is one thing that immediately triggers my OSD, which is the fact that controllers don't have the S situation.
Okay, so the controller folder is singular instead of being plural. That triggers my my OS, you know, just [ __ ] triggers me a little bit. So here I would expect here this to be controllers and entities and repositories you know because there is multiple files inside but not crazy but something to consider. Okay. Something to consider. I think maybe I can just change this honestly, but I don't know. 67, I guess. 67. All right. Let's go back here and see how it goes. Still cooking. This is taking a little bit. Taking more than 5 minutes already.
Why do you like profiles and gates? So, I like profiles. I don't like gates and policies. Okay. Okay. Showtoper is saying the following. Watched your last video and saw UIDs. Why this is not a default? Yeah, UIDs should be the default on any Laravel app, but also like Sniffy apps, UUIDs for the windshot, they are fast, they are time sortable, they are indexable, it's just the best thing in the planet. EUIDs by default. Okay, in my opinion, Eloquent gives 200 to doctrine. Well, uh, that's a matter of taste. I agree with you, but you know, that's a matter of taste, I guess.
The controller name space feels better. I don't think so. Controllers though, it does feel better. Why UID when security is not an issue? Is that a benefit? Um, there is multiple benefits on UIDs. I'm going to make a full video about that topic. Okay, I'm going to be I'm going to make a full video about that topic. Cloud code is [ __ ] going hard on this [ __ ] man. Oh my god, it's still thinking. I'm wondering if just, you know, just broken. Let's wait a little bit more. Okay. I took your prompt saying I want to read every file too.
Literally, you know, rolebased access controls. Yes, I'm familiar with that [ __ ] Pickinfo.cloud.symphony. What is that? Pick and flow. I'm going to copy the link. What is that? What is that? Holy [ __ ] What is this [ __ ] Syfony concept map for Laval developers. Click on notes to compare. Oh. Oh, it's kind of explained in a very graphical way. Um, you know what is entity manager? What is repositories? What is entities? That's interesting. All right. chat is cloud code over. I was not expecting cloud code to take this. Oh, excellent research done. Now, let me write the final plan.
So, that was still researching. Jesus [ __ ] Christ. Cloud code. I'm using, by the way, cloud code for OP uh 4.6. Okay. Oppos 4.6. Okay. And for the plan, we kind of want to be in this way. We want to be on this uh the latest and the greatest model. By the way, meanwhile, type on the chat which model are you using at the minute? I'm using cloth code Opus 4.6 and you know happy with it. Happy with cloth code in general. But let me know what you are using at the minute. Oh my god, it's ready.
It's almost ready, Shet. It's almost ready. The graph made me more lost. All right, Shet. We got it ready. Let's go all the way up and see what we have here. We may have a few things to adjust. Okay, we may have a few things to adjust. Okay, so in terms of context, we are building phpnews.com. So that all that [ __ ] blah blah blah blah blah PHP 8.5 with doctrine tweak security form validator asset mapper in maker. Okay, this will give us the opportunity to walk through all the full thing. The goal a public facing useite with an admin created via CLI.
We can log in and manage the articles. This is exactly what we want. No Docker, SQLite for dev, PGSQL 18 for production. Tailwind CSS via CDN. Step one, database configuration. So this is step one uh which is using SQLite for devah. Symfony loads.mm for defaults and then.local for local overrides. Sh. This is exactly what we talked about. Okay. So apparently Symfony have the M4 default. So the that's why we see the M being committed. One of the very first questions you guys had is why are we committing the M file? The reason why we are committing the M file on Symfony is that M file on Symfony is meant for the defaults.
Okay, if you want to have different things locally, you must have aim.local which I assume in production this will be.in.production. Okay. Okay. Okay. Okay. So in terms of defaults it will change the to uh SQLite which is a local database uh under var data db. Okay we are going to equally configure doctrine.ml file. This look is this is looking good by the way. This is looking good so far. Okay. Uh I'm going to kind of intentionally ignore step two, step three, step four in xyz because I want to check this later. Okay. So I'm going to say the following.
Okay. I'm going to say the following. execute the step one and stop and ask me ask me for validation when you are done implementing this step. Okay. After explain me the next step before you execute it. Okay. So I'm going to type enter so we can update the plan. I think so. And then we execute the step one. Okay, it's kind of a mental shift. I'm going to be honest. I don't like the don to have defaults. I think this should belong to the configuration file. Just my opinion. Okay. [ __ ] We only have 25% of the context been used so far.
So, what we're going to do is uh move forward without clean without cleaning the context. We don't need to um clean the context. Okay. So I'm going to say yes and auto accept edits in hope hopefully we'll u wait for before moving to the next step. Let's go. Let's go. Let's go. Overrides yourin. I understand that cvtl I understand that. I just find weird that we are committing ain file. That's it. Maybe like this is a lot of thing but you know. All right let's go back into the GitHub UI and kind of reviewing every single bit we are talking about.
All right. So in terms of defaults we are using SQLite. This is looking good. And then what he did which is interesting is that when we are in production you guys are you guys seeing this? You guys seeing this? So in production we'll use the PGSQL platform Okay you know this is kind of what I was expecting the defaults to be and to be long but you know uh this is what we have. So, PGSQL in production and using SQLite for local development. Okay, Shad. Bada bada boom. What else we have? Is it done already?
No. Okay, it's asking me for permissions to create the database. So, I expect this to create a SQLite database. Invalidate the configuration. Let's say yes. You don't need permissions to ask me that again. So, it's literally failing for some reason. Cloud code will work on it. Let's see what we have. Uh schema validate. Yeah, you can do that. Maping files are correct. Okay. Okay. Okay. I'm wondering if this will be the moment where migrations will be created. I'm super curious to see how Symfony deals with migrations. Be console is the artisan command. Yes. Is there equivalent of artisan?
Okay. All right. Just finished with the step one. Let's see what we have. So we basically just have this little thing that SQLite will be used for local development and PGSQL will be used for production. That's it. So I'm going to type here feat configure database defaults. Okay, I approve this code and it's looking good. Configure database defaults. Bam. Bam. Bam. Done. The step two should be about what? Let's see. Step one is completed. We have done this [ __ ] Good to go. Key learning points. SQLite needs no server, no credentials. In productions, we are going to use, you know, um, PGSQL.
Bada boom, bada boom, bada boom, bada boom. Next step, uh, step two, user entity. We are going to create a user entity with ID, email, password. So, this will be through doctrine already. We are going to use doctrine. At this point, this entity implements the user interface and password authentificated user interface. This will be the equivalent of the user model in Laravel, by the way. Okay. So in Laravel every time you have a user model you are extending the user model that from the framework and on Symfony you do the same thing by implementing these two interfaces.
Okay and they are requiring for O to work. So Symfony ships with authentification as well. We are going to create a user repository as well. So shad I'm not a fan of repositories but when you use data mapper through doctrine you are forced to use uh um repositories. Okay I don't know what you guys think about repositories. I'm not a big fan but this is what we have and at the end we're going to create the database migration. Do you want me to proceed? Yes. Move ahead. So cloud code will now start move working a little bit through the dock tree and implementation migrations and everything.
Okay. Sabrita is saying the following. SQLite input GSQLF schema differences. How you are going to deal with that? So I expect that Symfony will give me back some sort of migration creator. You see in Laravel when you type something like um this column is a UID integer and you are basically just chaining methods. I expect symfony to equally offer me that so I don't have to have different migrations depending off the driver. Okay. I expect Symfony to literally give me that as well. If it doesn't that sucks, you know. So, okay, it does. Exactly. I am expecting Symfony to give methods that allow me to do that.
Okay. It's already in the process of migrating the database. So, we can literally just go here and see the migration chat. Okay. All right. Let's see. Let's see. Let's see. So, oh my god. Okay. Okay. We are working on the backend chat. We are literally working on the models, migrations, and all that [ __ ] Let's start with migrations. Okay. The very first file we are going to check this file is autogenerated. Please modify to your own needs. Okay, this is the migration name. Let's actually move here into uh the file itself so we can see it in more detail.
What is this? Why are you complaining? Jesus Christ, PHPtorm, leave me alone. Okay, Shad, how do we change the PHP version of this website? It's [ __ ] annoying me. Okay, here we are. PHP 8.5. Here we go. Okay, in her we are on PHP 8.5, too. Okay, we're good to go. This is the migration name. Get description. We don't need one up. Okay, this is exactly what I was expecting Symfony not to do. Okay, I'm going to ask cloud code why why it did it this way. Okay, this is not not looking good. No good. No good.
Okay, let's see if cloud code can do a little bit better than this. Let's say the following. Uh, do you want me to proceed? I'm going to say no. I have just noticed that migrations contain plain SQLite on it. Don't Symfony have something like Laravel that does you know table integer and [ __ ] like that. So this migration can work with any driver and with any luck Symfony does have this. Okay. Okay. Sabrita is saying you probably need doctrine DPL. It doesn't come by default. That's interesting. Oh, wait, wait, wait, wait, wait, wait, wait, wait, wait.
Great question. Yes, Doctrine absolutely has this the schema parameter that already passed into the up and down. Exactly. For that reason, the problem is that doctrine migrations diff generates a raw SQL by default, but you can rewrite it using a different API. So, this is exactly what I was expecting the migration to be using. Okay. So, and it just did it. Okay. Now, this is looking a thousand times better right now. Okay. So, we are adding a column ID which is an integer which will auto increment. We have an email which is a string la 118.
So this is looking much more like Laravel at the minute with nice enums which is not bad. Okay, this is looking good chat. This is looking good and hopefully this I mean the expectation now is that this [ __ ] will work automatically for um SQLite but also PGSQL. You know by the way um a lot of you are asking what is the GitHub UI interface I'm using. This is called GitHub desktop. Okay, GitHub desktop for the win. All right, chat. By the way, we have 150 people watching this stream. Can you guys go all the way down and click like on this video?
But also subscribe the channel if you want to see this number going up. Okay, enums for the win. I know shad enums are absolutely awesome. Okay, I actually think lot of query builder is actually fantastic for migrations or the schema builder. I apologize, but this is not bad either. Okay. Okay, so let's see what tables do we have. We have user table at the minute. We have messenger messages. I think this is basically an internal table for Symfony handle the messenger situation. Okay. And we have the down method which I'm not a big fan of.
Okay. I wish we can delete the down method. By the way, on Symfony world, Symfony experts, stop everything you are doing. Tell me, do you guys use the down method usually or I'm allowed to just delete it? You know, on Laravel, I'm not a big fan of done methods. I like to move forward instead. Oh, CVT Mal is saying no down method never, only forwards. Yeah, I'm not a big fan of the down method. I'm going to keep it because I'm not sure this will break like anything, you know. So, I'm going to just keep it a little bit if you guys don't mind.
So, now the migration is looking a thousand times better. Let's see just one last thing. What we have here? We have the ID which will be an integer email. We have ROS. I don't want a rolls, man. Do we need rolls? I don't think we need rolls. Rolls suck balls. We don't need rolls. Let me go here. Uh, and just ask for that. All right, I'm going to just say the following. Uh, want me to proceed? No, I don't think I don't think we need roles. Uh, do we going to just say this and kind of question the AI is heading roles to begin with?
You are right. Since we only have a single admin created via the console command, we don't need ROS. Nice, nice, nice, nice, nice, nice shaded. So, this is good to go. At least the migration. Let's now move forward to the entity itself. Okay, let me just remove this PHP storm files by going to the git ignore and ignoring the PHP um storm [ __ ] I'm going to just do this. Bam. Bam. Bam. I'm going to type inside PHP storm. Crap. Okay. Crap. Here we go. PHP storm crap for the win. And we are going to remove this IDE situation because we don't need this.
And it's gone. Okay. I don't know why this is not gone though. Oh, because it got committed. That's why it's not gone. [ __ ] All right. Let's just delete that that little thing. Uh first do ID is not even here. Okay, I'm going to just do this. And now I'm going to commit this. Ignore PHP Storm. Crap. Uh ignore PHP Storm. Crap. Okay. All right. So we we're okay with migrations. Let's now see the user entity. Now this is the equivalent of Laravel models. Okay. Shhat the equivalent of Laravel models. So we have uh user repository which is responsible uh to serve users on this app.
The table name will be called user which in my opinion should be should have been users. Anyways the unique identifier is the email. So all of that is good. Ooh, we see the properties as nullables. Is that expected chat? Is that expected that all of the properties on doctrine are just nullable by default? Nables are a code smell in general, by the way. But I kind of want to, you know, yeah, the attributes on doctrine. By the way, we probably need to speak about this, but on doctrine, this is the way that you specify that this is an ID.
It's a generated value. It's RM column as well. And this is the place where you specify some of the validation. Okay. Okay. People are saying that it's expected that the attributes are nullable. Okay. Let's keep that then. Okay. Let's keep that then. Let me just remove uh remove the g ignore here real quick. Bada boom, bada boom, bada boom. Let me push this situation. Uh let's go back here. Um I'm going to actually accept this for now. Okay, so doctrine is running the migrations. The migrations was were run successfully. Um it's validating the schema. I don't know what doctrine schema validate is.
I assume that what doctrine validation schema does is compare this [ __ ] right here with the given migration created. So we'll just compare everything that got created through the migration with my entity itself. Okay. And apparently went successfully. So we can just go back to the entity and just be finished with this. Okay. Okay. We see we still see get roles here which is kind of you know weird but let's keep it for now. We see get password. We see set password. Now one little thing this thing is not using which I don't think is expected is that it's not protecting the password from the logs.
So what we are going to do here is using this attribute called you guys remember the attribute that removes any kind of sensitivity. Oh sensitive parameter that's the name. Yeah let's use that. Okay. I was kind of expecting Symfony to do this. Okay. So, let's do it. Here we go. Here we go. Here we go. Sensitive parameters. Yes. Yes. Yes. Yes. Join to saying the following. I love attributes. It's true that Laravel will use more attributes on the next version. Yes, that's true. So, eloquent models will contain a bunch of attributes and you guys are going to love it.
Okay. Um, bada boom bada boom bada boom bada boom. Try to make use maker bundle. Uh, let's keep code for now, I guess. Okay. Money is saying the following. No, no, no. Don't forget to tell Doctrine to automatically populate the timestamp columns. Oh, do we have a time stamp columns even on this user? We don't have that at the minute. I will make sure we have that once we need it. Okay, Laravel models are super clean. Oh, they are super clean and badass. Okay, so this is looking okay. Okay, this is looking okay. Uh, let's go back into the GitHub UI and see if we are done with this.
We are done. I think we have also user repository. Again, in Symfony, if you want to access stuff on the database, you always need to go through the user repository right here. Okay. Okay. So, this is called the user repository. Okay. And let's go back into this file right here, user repository, and see what we have. So, we have a simp we have a bunch of comments. Oh, we don't have a bunch of comments. Okay. So, use repository extends service entity repository implements password upgrader interface. Jesus [ __ ] Christ. Why do we have all of this?
Okay. Apparently, it's like a symfony course thing security-wise. Let's just keep it. Uh, bada boom, bada boom, bada boom. Using to upgrade reash the user password automatically over time. Okay, I'm going to just trust this. I don't know what it is, but I'm going to just trust this. Give some space here. Remove this comment. And I think we're good to go. We can also remove a bunch of git ignores. Again, let's just do that. Remove this git ignore. Remove this git ignore. And this is the thing I was telling you about like app repository. I was expect this to be you know kind of um plural basically.
Okay. So I think we are happy with assure uh or feet users persistent layer. Okay, this is looking good. Do we have tests? That's a good question. Should we have tests for this [ __ ] By the way, chat, do you think on Symfony people would just test this stuff directly? Because it feels to me that I'm testing the framework itself. But um you know I was kind of I think we are going to write tests but only for actually making posts in making gets you know why do you use a repository to upgrade the password? I don't get it.
Well I don't get it either man honestly. Is cloud code doing some [ __ ] We can delete it if you we can actually ask. Okay let's do that. Why on the step two? Why do we have this thing on the user repository? Can you use past on symfony? Yes, you can. Okay. The answer from cloud code was the following. uh password upgraded interface tells Symfony Security, "Hey, I know how to save a new password ash for a user." Here's when it kicks in. Every time a user logs in, Symfony checks if the started password ash was created with a weaker algorithm in a lower cast factory.
If PHP or your configuration was since upgraded using a different algorithm for the ashing, Symfony will automatically reash the password with stronger settings and call upgrade password to save it. Without this interface, the user password would stay ashed with the old algorithm forever. So, seems to be to be a Symfony feature. That's a good feature, by the way. Okay. By the way, Shet, go all the way down and put like on this video. Insanely important. I'm going to keep this. This seems to be a good feature for me. Okay. All right. Sh times to move to step two.
Let's see what step two has uh for us about. Next step. Step three console command. We are going to create an app. Create admin. A symfony console command accepts the email and the password as an arguments. Ashes the password using the password asher [ __ ] and persists the admin on the database. This will use symfony 8 new invocable commands in the invocable [ __ ] All right, let's do that. uh you can move forward with the step three. By the way, this is how you guys should use AI, okay? Very slowly ask for a plan. Execute step by step, validate every single [ __ ] file created.
This is how you move with AI, okay? In 2026, I'm going to ask now move forward with the step three. So the step three will create a console command so we can have a user on the database which will be responsible for creating articles. Okay. bad chat. Oh boy, this is moving fast now. Exactly what we want. Now it's asking me to create the the user. Okay, the local user which will be admin phpnews.com and that's the email by the way. And this password will be secret123. I'm going to allow AI to do this admin uh user created successfully.
Beautiful. We can you see the console command? Yes, we can. All right, let's see the console command real quick. What do we have here? So the console command will be this beautiful thing. Let's go here into source command create admin command. We'll receive the entity manager interface and the user password ashure interface and I expect this here we go we were talking about the symfony container situation. I think like if we are asking for this interface, it will inject the user repository because it implements this interface. Okay. And if we are asking for the entity manager, I can resolve the repository of the user automatically using that.
Let me just confirm entity manager persist user. Oh no. So automatically the entity manager will resolve the container um the repository of the given entity user. Okay, that's the way it works. All right, let's see this very carefully and slowly. So we're creating a new user. We are setting the email of that user. We are setting the given password as well. Be before setting the password, we are ashing the password and then we say entity manager just resolve the user repository to persist that user. Okay. And then we flush it. Can anyone explain me why the [ __ ] we have this flush here?
What does the flush does? That's a very confusing thing. Does anyone know what the flush does? Otherwise, I can just ask cloud code. But this going to be open source. It is open source already, dude. It is open source already. Let me show you. Let me show you. So, this is the repo. Let me show you. Let me send it to you. Here we go. Here we go. This is the open source repo. Okay. So, I don't know what this flush does, by the way. I'm going to ask uh real quick uh cloth code. So, I'm going to say just don't do this.
Well, I'm going to actually allow it to finish. Can you explain me what the flush does? Okay. We're going to ask AI about this situation. Uh, so the command the thing is over. Uh, I'm going to just ask what entity manager flush does. I'm not familiar with this, so I I don't even know. I think the persist user makes sense, but the flush situation just got me confused a little bit. All right, let's see what we have. Think of doctrine as a middle as a middleman between your PHP code and the database. When you call persist user, you are telling doctrine, hey, keep track of this object and I want to save it eventually.
But nothing hits the database yet. The object is just queueing in memory. That's a very interesting thing. So apparently chat, what we have here is the following. When you guys call entity manager persist the user, you are basically queuing this operation. However, when you basically call flush, you are effectively committing the operation to the back end. Okay, ZTO is saying the following. Flush is like commit intransaction. Exactly what I Yeah, so Bose Laravel got me spoiled. Yeah, well, it's just different. Okay, we need to be open-minded, chat. Like every single time you work with a different framework, you will think like, oh, holy [ __ ] like I like so much more my framework.
It's just expected you know everything about that framework. Um, so you know in Lavl by the way the equivalent of all of this [ __ ] will just be this user create you will just specify email and password and that's This is the equivalent on Laravel of all of this [ __ ] By the way automatically Laravel will ash the password as well. Doesn't symphony have doctrine? This is exactly what we are going to exactly what we are using behind the scenes. This is doctrine behind the scenes. Okay, this is doctrine and this is the equivalent of the code below.
Okay, so good [ __ ] here. So this is working. This command is working. And then we have a success message to the CLI. Easy peasy. Lemon squeezy feed users create admin via CLI. Okay, this is good stuff. Good stuff. We don't have tests yet. We are going to add the test in the future. Okay, chat. Bada boom, bada boom, bada boom. So, step four. Let's see what the step four is about. Step four, security configuration. I will update the security. Mamel file to switch from the placeholder users in memory but to use an entity provider that loads the users from the database by email.
Configure the form login so Symfony intercepts the post request to login and automatically handles authentification. Also configure the logout and the access control situation. All right, move forward. Uh, want me to proceed with step four? Yes, do it. Boom, boom, boom, boom. Looks very PHP stand friendly. You mean Symfony? Yep. If you want to have a PHP a PHP stand friendly situation on lot of value, you can use lot stand. Okay. Let us stand. CV is saying the following. No one on Symfony World uses doctrine only. We write our own repository patterns which look similar to eloquent.
Is that true? Is that true, chat? Oh my god. Wow. Wow. Wow. Wow. Tox is saying the following. You don't write code anymore? Like to be really honest with you. No, I don't write code anymore. I basically just ask cloud code and I validate the code. said, you know, Jane is saying the following. We use Laravel filament. Is that good? Yeah, a lot of filament is fantastic. And apparently, like on Symfony, they use something called easy admin, which I'm not familiar with that. That's true. Oh, I see. I see. I see. By the way, Shad, really appreciate all of your support so far on the live stream.
Don't forget, go all the way down, click like on this video, and subscribe to the channel if you want to see this number going up. If I don't end up a year with a 100,000 subscribers, I will be super sad. All right, what do we have here? We have a bunch of changes regarding the security. So, apparently what we are doing right now is instruct Symfony that regarding authentification, we are effectively using the app entity user uh for that. Okay, this is exactly what's happening here. Okay, for authentification, we are using the app entity user.
Okay, login path will be app login. So I think this is a route name. I'm not sure yet, but I think this is a route name. Okay, maybe we will be, maybe it will not be, but I think this will be the route name. And then we have the logout with which is app logout. Okay, good stuff. Good stuff. Still under the fit users configures security. Bam. Done. Step five. Sh. What do we have here? Step five, login controller and template. We'll create a security controller with two routes. Security controller as a name looks [ __ ] Okay, looks [ __ ] I want to call this No way.
Call the controller session controller with uh store and destroy. Okay. Is this too Laravelish? What do you guys think? Store and destroy? I don't know. Should we just keep, you know, allow Symfony to be Symphfony? What do you guys think? We can go, we can create a security controller. Just feels bad as a name. Like security controller feels too generic. What do you guys think? Call it store session management controller. Jesus [ __ ] Christ. Why do we need all of that? Holy [ __ ] No, no, no, no. Let's call it session controller. And I'm creating a new session with create store where the create will handle the login form.
The store will persist like the user. And then we have delete, not delete, just destroy for log out for logout. Let's see what he thinks about it. What do you think about it? Okay, I'm going to ask like AI, what do you think about like this convention B symphfony Java? Oh no. Yeah, let's see what he thinks about this situation. It might be too lavalish for a cloud code symfony taste. Let's see. Let's see. I like it. All right. Cloud code likes it. Much more intuitive naming. Thank you. Thank you. Follows a resource pattern. Session is a resource and you are going to create a session and destroy it.
How's this map? Create will map to login. Store will map to post login. What happens if an intercepts blah blah blah blah blah? It's looking good. I think we're good. Tell me you are a laval developer without telling me you are a laval developer. I know, man. I just I just cannot avoid it. Do you want me to go with this approach? I'm going to say yes. This is looking much better, I think. Okay, this is looking much better. [ __ ] Bada boom, bada boom, bada boom. So now we are authenticating the given user. Um which by the way, oh here we go.
This is what I was expecting. So um this is the like the route name basically which is now session create session store session destroy. It's also writing the tweak stuff as we speak for the login. Okay. I'm going to allow to debug the routing situation. What is debug router by the way? I want to kind of type this [ __ ] and see what it gives to me. Oh, not bad. So, PHP bin/conole debug router is the equivalent of PHP artisan route list. Okay. Will basically tell you that if you hit this route will be blah blah blah blah blah.
Good stuff. Good stuff here. Well, actually this is a bug. Like this shouldn't be any. This needs to be uh only post. That's That's a bug, by the way. That's a bug. I just spot this. I'm gonna tell him that. Yeah, that's 100% sure a bug. Uh, let's go back to cloth code real quick. Just found a book. The session destroy should be not any, right? Authentificated session. That's a good one, too. I like session controller, though. Ah, see, I found the bug. This is why it's so important, Chad, to validate your code always. Okay.
Very, very important. So, basically, in the past, we were allowing get the vet, the verb method get to literally destroy a session. No good. Okay. No good. Now, we are requiring a post, which is much more safe. Okay. So, let's see the terms of files. What we got right now, we got this [ __ ] which I'm going to discard it. We have a security.ml file that points to session create, session store, and session destroy. We have a controller which is looking okay. Let's see what we have. Uh let's go back into PHP storm session controller. Let's remove this g ignore session controller.
We have route login name session create methods get. This will receive an authentification utils. What is this [ __ ] This is random stuff from Symfony. Okay. Authentification utils uh to get the last user from the last username. Sorry. And also the last authenticated error if any. And this is how we render the create form. Basically how we render the login form. Okay. This is how we store this method will never be reached. Symfony is login form intercepts the request. Huh? So, if it's never being reached, why do we even have this? That's weird. Anyways, so we don't need this.
Wait a second. Wait a second. Uh, wait. I see this. If the method will never be reach, why do we even have it? That's confusing. CVT Mal is saying the following. Get for destroy is okay if you are working with IDTP brokers. I have no idea what is IDP brokers by the way. Okay. By the way, chat if you just arrived today. We are trying Symfony 8 for the first time ever. Okay, we are discovering Symfony 8 alto together by building an app al together and at the very end we are going to ship that app on Laravel cloud hopefully and hope and just pray that everything works as expected.
Okay, we are in the process of dealing with authentification and we just found out that Symfony comes with a bunch of authentication tools just like uh Laravel does. Okay, Symfony router needs the route to exist. Oh, okay. That's why. So even though that is throwing an exception, Stephven still needs that route to exist. That's a weird thing, by the way. But okay, I'm going to just accept it. Bada boom, bada boom. This number chat is the number of subscribers of my YouTube channel. Okay, so if you guys want to see this number going up, just subscribe the channel.
Okay, so this is apparently a thing that Symfony requires. So I'm going to just keep it. Okay, this is good. Uh we are now in the process where we actually have um a controller. So it feels to me that we kind of want to test this. Okay. So I'm going to go here and say the following. Uh can you create a test for the session controller call it uh session controller test and test the off there. Okay. I don't know if I'm going too far and testing Symfony stuff, but I feel like this is the moment that we need to test.
We need a feature test for this stuff. Okay, what do you guys think? Are you ready to work on Symfony boost? Uh, well, not me, but uh I do think that Symfony needs a boost situation. Okay, they are missing out if they're not doing that already in my opinion. Okay, is past install it already? It's not. I'm going to use whatever Symfony does by default here in terms of um um testing. Okay, in Symphfony you do integration tests. Well, I have no idea what Symfony will actually do. Uh, I guess we are about to find out.
Okay, we're about to find out. I expect Symfony to have some sort of inbase in datab inmemory SQLite thing for the testing on the back end too. Um I'm going to actually make sure are you using uh in memory SQLite for testing I'm going to just prompt AI for about that situation. Okay. So tests are failing. Um but uh we want to make sure that we are using SQLite for testing here. Okay. DDN is saying the following. Try some Symfony UX stimulus and turbo. It's Symfony Livewireish. Yep. Yep. Yep. Yep. Constantine Ross is saying the following.
How do you like Symphony so far? I just saw the stream. Uh ah there is a few things that I was kind of expecting Symphony to be too verbose. You know, we talked about the create admin situation and I I don't think Doctrine is actually a good thing. Okay, doctrine is just too verbose for my taste. Um it does too many stuff. Um I'm also not a big fan of the amount of configuration files they ship by default, but you know, it's their thing. You know, they are configuration over convention. So, I feel it. Uh, but doctrine feels too much proposed to me.
I much rather use eloquent. Okay. I'm pretty sure symphony must have at least a skill. Well, you know, that would be helpful, by the way. That would be really helpful. Did he just nuke your local DB prior to the memory change? Well, hopefully not. He might have done that. Yes. By the way, Shad, is this expected? This is how you do integration testing with Symfony. Mr. Puya, what's up? That migration file name. Um, yeah, I don't know why I did that, but I think I think we're are going to just go with it. Okay, let's see the test.
By the way, let's go here into the test folder. Controller. We see a session controller test. We see uh a bunch of setup being done here. Jesus [ __ ] Christ. Drop and recreate the schema for a clean state before each test. Okay. Um are we using in-memory database? That's a good point. Why not in-memory database? Inmemory database is per connection. When Symfony security layer processes a form request, it may open a different connection, finding an empty database. No way this works this way. Let's go here and type Symfony testing. Okay, it must be they must have a better story than this.
Integration test. Here we go. This is what I want to use. All right, I'm going to ask Cloud Code to get familiar with this [ __ ] get familiar with integration testing on Symfony and rewrite that test because it looks because it looks ass. Okay. In integration, you mock your repositories. No HTTP calls made. No way. Are you serious? They don't have like actually post and delete and [ __ ] like that. Please no. Oh, they do have this though, like get content and [ __ ] like that. They don't have post. You get the verbose regarding doctrine. Patricio, what's up, dude?
Today you don't have a lot of el boo. That's right, man. I would love a Symphfony boost, though. Oh, they have this crawler situation, but still that doesn't allow me to use inmemory databases. Oh,…
Transcript truncated. Watch the full video for the complete content.
More from nunomaduro
Related Videos


🚨🚨 I am going to learn SQL on boot.dev. Yes, Sql, the whole dang thing. #ad 🚨🚨
06:05:00



Zero to Deployed: Build a Real Laravel App with Claude Code - No Terminal, No IDE, No Setup Required
01:30:32

React Native Full Course 2026 | Build, Publish and Monetize a Full Stack Mobile App to App Store
03:43:15
Get daily recaps from
nunomaduro
AI-powered summaries delivered to your inbox. Save hours every week while staying fully informed.



