Chapters
Start Project
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Well hey guys! You know what? I'm pumped that you're learning Symfony, because it's the hardest framework ever! Relax, I'm kidding. Symfony does have a reputation for being tough to learn, but this is a trap! Or at least, it's an outdated idea.
Look: Symfony can be incredibly simple and will put you in a position to write powerful, well-designed code, whether it's for an API or a traditional web app. And when it does get a bit more difficult, it's usually because you're learning best practices and object oriented goodness that's turning you into a better developer.
Symfony Components & Framework
So what is Symfony? First, it's a set of components: meaning PHP libraries. Actually, it's about 30 small libraries. That means that you could use Symfony in your non-Symfony project today by using one of its little libraries. One of my favorites is called Finder: it's really good at searching deep into directories for files.
But Symfony is also a framework where we've taken all of those components and glued them together for so that you can get things done faster. This series is all about doing amazing things with the Symfony framework.
The Symfony Installer
Let's get our first Symfony project rolling. Head over to Symfony.com and click 'Download'. Our first task is to get the Symfony Installer
. Depending on your system, this means running commands from one of these boxes. Since I'm on a mac, I'll copy the curl
command and paste it into the terminal:
sudo curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony
Copy the second command and run that to adjust some permissions:
sudo chmod a+x /usr/local/bin/symfony
This gives us a new symfony
executable:
symfony
But hold on! This is not Symfony, it's the Symfony Installer: a tiny utility that makes it really easy to start new Symfony projects.
Downloading the Project
Let's start one! Run symfony new
and then the name of the project. Call the project aqua_note
:
symfony new aqua_note
I'll tell you more about it soon. In the background this is downloading a new Symfony project, unzipping it, making sure your system is configured, warning you of any problems and then dropping the new files into this aqua_note
directory. Not bad!
Tip
The project name - aqua_note
- is only used to determine the directory name: it's
not important at all afterwards.
Move into the directory and check it out.
cd aqua_note
ls
This is also not Symfony: it's just a set of files and directories that form a web app that use the Symfony libraries. Those libraries - along with other third-party code - live in the vendor/
directory.
Before I explain the other directories, let's get this thing working! Run:
php bin/console server:run
to start the built in PHP web server. Yes, you can also use Nginx or Apache: but this is much easier for development. When you're done later, just hit Ctrl
+C
to stop the server.
As the comment says here, go to http://localhost:8000
in your browser. And boom! Congrats! This is your first page being executed by the Symfony framework. That's right: this is being rendered dynamically from the files inside of your project. At the bottom, you'll see one of the best features of Symfony: the web debug toolbar. This is full of debugging information - more on that later.
Ok, let's start building our own pages!
127 Comments
The symfony its installed and its listening on localhost:8000. Symfony its installed on Z: A network Location
Hey Spiro Ciko
Did you solve your problem? if port 8000 is not open in your shared host, try with a different one
Cheers!
I try it to solve the problem but i cant i want to open on my own database example spyros.asdfsdfssdf/aqua_note
Hmm, interesting... that's not my area of expertise, but try starting the server like this:
$ php bin/console server:run 0.0.0.0:8000
If that doesn't work, can you contact your network admin? maybe he has some ideas
as of now (2020), the only way i found to install symfony 3 with the same folder hierarchy like in the video, is to clone `https://github.com/symfony/...` (the exact commit id i used is `cd07a8d`), i was able to finish `Joyful Development with Symfony 3` without any problem, (my OS is ubuntu 20.04), it may help somebody start learning 3.
its also important to install composer (the default dependency manager for symfony3) and run composer install before running server:run
composer is available for mac users on brew (brew install composer)
Hey Marouane,
Yes, you're right! Thanks for this tip for Mac users :)
Cheers!
Hey Ahmed N.
Yea... Symfony doesn't really want to you start a project with the old structure, it's really painful to do the switch later but for learning purposes it makes sense :)
Thanks for sharing it with others. Cheers!
after entering the command "~$ symfony new aqua_note" I get an error:
[RuntimeException]
The Symfony Installer is not compatible with Symfony 4.x or newer versions.
Run this other command to install Symfony using Composer instead:
composer create-project symfony/skeleton aqua
Is this a command from Symfony 4.x?
Hey Ya,
Here's where this error message from: https://github.com/symfony/...
Symfony installer is not a recommend way to install Symfony, starting with Symfony 4. As symfony.com suggested: https://symfony.com/download - use "composer create-project" command.
Cheers!
I can still use this command, but you need to specify Symfony version:
`symfony new aqua_note 3.4` (works only for Symfony 3.x)
Hey Serge,
Yes, it's still the best option for 2.x/3.x versions, but for new Symfony 4 user composer create-project command.
Cheers!
Not sure where to ask this but do you have a tutorial on sessions in symfony? Specifically I'm annoyed that, from a controller, I have to call two lines to set/get a variable:
$session = new Session();
$session->set('name', 'Drak');
It doesn't work for me if I leave out the first line as I get an error that $session is an undefined variable.
It looks like I can set up a constructor in each controller that sets a property for the controller to access?
private $session;
public function __construct(){
$this->session = new Session();
}
Then in my controller:
/**
* @Route("/", name="homepage")
*/
public function homeAction()
{
echo $this->session->get('name');
}
Is this poor coding? (are we not supposed to use constructors in controller classes for some reason?)
Also Is there any way to set up a global variable that's accessible to all my controllers so I don't have to do this work in all of them?
I'm also a little confused on the session type above and the session available in a request (ie forms). Are they tied together? Or are they separate?
Hey Terry,
Better do not handle session manually - Symfony has built-in service for it. To get it in your controller just do:
class DefaultController extends Controller
{
public function indexAction(Request $request)
{
$session = $this->get('session');
// or get session object from current request
$session = $request->getSession();
dump($session->get('name'));
$session->set('name', 'Drak');
}
}
It should work well!
Cheers!
Thanks for the response. I'm still a bit confused... I thought I was using symfony's built-in service, per this documentation. https://symfony.com/doc/cur...
Is what you are doing the same thing, but just a short cut from inside the controller?
I forgot to add that I need access to the session from outside the controller in a Service. Is that when I'd use this line: $session = $request->getSession();
Thanks,
tc
Also... how did you get that code you pasted to show up so nicely?!
Hey Terry!
Ok, you're tripping up over something that's (unfortunately) a bit common :). Symfony is 2 things. First, it's a bunch of small libraries (called components). You can use each of these components from outside of a Symfony project. Second, Symfony is a framework: where it takes all of those libraries and glues them together for you.
What you're reading is in the components section of the docs, where it's basically teaching you how you would use Symfony's session if you were installing it manually outside of a Symfony project. I know it's confusing - we have the challenge on the docs of talking to 2 different audiences: those using the Symfony framework, and those using the components standalone. As a rule of thumb, stay out of the components docs. Or, at least, realize that they will tell you how to instantiate certain objects that Symfony simply sets up for you when you're in the framework.
Specifically in this case, Symfony sets up the Session object for you, so you never need to create it new. Instead, you just need to go find it. As Victor's code shows, there are actually 2 different ways to get the Session: there is a service called session
, or, if you have the Request
object, you can call $request->getSession()
. If you need to access the session from a service, I would inject the @session
service into its constructor (just like you would with any other service).
Other than finding out where the Session lives, we don't talk about it much because it's super easy :). It basically has get/set/remove methods - it's kind of a glorified array: just get/set stuff on it and it works.
Let me know if this clears it all up! I can totally understand why it was confusing :).
Cheers!
Thanks for clearing that up! That helps!
Also I I ended up needing the request in a service as well. I found this article which is old but seems to indicate to inject the @request_stack as the request object isn't a "service": http://symfony.com/blog/new-in-symfony-2-4-the-request-stack
Services YML:
============
app.MySpecialUtilities:
class: AppBundle\Service\MySpecialUtilities
arguments: ['@request_stack']
MySpecialUtilities
================
class MySpecialUtilities
{
private $request;
private $session;
public function __construct(RequestStack $requeststack){
$this->request = $requeststack->getCurrentRequest();
$this->session = $this->request->getSession();}
public function SpecialService()
{my special code here}
}
Is this how you would suggest I do this?
Hey Terry,
You better store whole RequestStack object to the $requestStack property in a constructor and postpone getting current request inside methods - otherwise it could cause some errors.
Cheers!
Great job Terry! Victor is right about storing the $requestStack
- the reasons are subtle so don't over-think that part.
Overall, being in the framework is great... because you don't have to setup stuff your self! About your question:
What is Symfony doing differently when it creates the Request object?
Actually, not much. In fact, the Request object is created in your web/app_dev.php (or web/app.php) file... which is technically your's to edit. And you'll see that it is created the same way you did, with createFromGlobals
. The Session is created as a normal service by Symfony (i.e. just like the templating service, logger service, etc). Then, via an event listener (https://knpuniversity.com/screencast/symfony-journey/event-subscriber), when your app boots, it sets the Session on the Request. This whole setup is quite rare in Symfony: usually Symfony just has services, I can't think of another time that one is added to another like this via a listener.
Keep up the good work!
Thanks Guys... Just to be fully clear, is this is what Victor is suggesting I do?
class MySpecialUtilities
{
private $requestStack;
public function __construct(RequestStack $requestStack){
$this->requestStack = $requestStack;
}
public function SpecialService()
{
$request = $this->requestStack->getCurrentRequest();
$session = $request->getSession();
/// start using $request here...
}
}
Yes, this is it! You got it right ;)
Also, before your reply as I was trying to understand, I created the request object<br />$request = Request::createFromGlobals();<br />
I was not able to get the session from this request object.
<br />$session=$request->getSession();<br />
It returned Null, which I see in the documentation that it can return a "SessionInterface" or Null.
"createFromGlobals" documentation says it creates the Request object from PHP's superglobals. PHP's superglobals contains stuff like $_REQUEST and $_SERVER which should have the information to set up the session.
So when Symfony sets up the Request object it contains a session that you can retrieve, but when using the code above it does not include as session and returns Null.
What is Symphony doing differently when it creates the Request object?
Oh, and about the pretty code (I made your original comment pretty), you need to surround your code with:
<code><pre>
echo 'cool'!
</code></pre>
It's kind of a pain to type, but it looks great (escaped the tags above you so you could actually see the raw HTML) :).
Ah, that was in Components section. Check this one https://symfony.com/doc/cur... .
Well, you can get Session object from Request, but I think better to inject the `session` service into your custom service if you don't use Request in it at all.
I just use pre and code tags: check this docs page Syntax highlighting
Cheers!
Hi, I am following the example of the video but when i type symfony new + name of the project, i get a message "'symfony' is not recognized as an internal or external command,
operable program or batch file." . And i do have installed installer.
Hey Lazar,
Are you on Windows? Using Symfony installer on Windows is a bit different, you should move the downloaded file to your projects directory and execute it as php symfony
, i.e. execute it through the PHP interpreter, for example:
php symfony new your_project_name
Does it help you?
Cheers!
I already installed composer yday but thanks for answering anyway :D
Symfony installer allows you to do it much quicker, but Installing with Composer is a good alternative way indeed :)
Cheers!
Hello everybody. Is there a set of steps to install Symfony on Windows? Do you know where to find detailed information on Windows setup? Thanks in advance.
Hi Pablo!
Windows is always a *little* bit different, but it shouldn't be *too* different actually in this case :). Here are a few tips:
1) You *will* need to find a terminal and use it - that's just part of programming in Symfony. If you don't have a terminal you like already, I recommend installing git - which has nothing to do with terminals, but comes with a great "git bash" utility after you install it. Another good one is of course cygwin
2) The installation instructions for installing the Symfony installer are just a little bit different on Windows, but you can find them here: (click "install the Symfony installer" to reveal them): http://symfony.com/download
3) After that, it should be more or less the same: you'll run "symfony new aqua_note" to download the Symfony project, and can start the built-in web server with the same comment.
Let me know if this helps, or if you have any other questions!
Cheers!
Hi weaverryan,
Thanks a lot for your response. I've installed Git, with Bash, but without a different result.
I will stick to Ubuntu and maybe Mac, so I'll leave Windows out of scope for now.
It's very funny to see the a huge marketing text convincing people to move to this philosophy, with a lack of instructions to get it installed on a major OS.
I'm used to deal with terminals, last year I did it a lot with Apache Cordova, but with my 37yo I still surprise myself everytime using a terminal after years of OSs hiding them under GUIs :)
Kind regards,
Pablo.
Hi Pablo!
Well, I'm happy you got it working, even if it meant leaving Windows aside for now :). Keep asking questions as you go through stuff - we're happy to help, and these conversations help others.
Cheers!
Hi all.. Why the video could not be loaded?
Hi Henri!
Hmm, it must have been a momentary problem with our video host (Vimeo). If you keep having issues, let me know!
Cheers!
Hi weaverryan..
I must use http://unblocksites.co/ for watch the video :)
Hey, Henry!
Hm, you definitely have problem with your browser. Could you provide us a bit more about your environment? What browser and OS do you use? Could you make a screenshot of problem with video loading?
Right now, I can only suggest you to open KnpUniversity website in "Incognito window" which available in Google Chrome out-of-the-box. Did it help you?
Cheers!
Hi Victor!
Because in Indonesia, the Minister of Communication and Information block vimeo. But don't worry, i can use http://unblocksites.co/ :)
Thanks anyway...
[FYI]
My browser: Chrome, FireFox, Opera
My OS: Linux Zorin
Ah, that explains everything! The problem not in your environment but location. Well, we can't help you with it. :( We use Vimeo API for each our screencast.
I only can advise you to check the "Unlimited Free VPN - Hola" - it's a name of nice Google Chrome extension. I use it sometimes when have a problem with DNS. IIRC, Hola provide VPN without any advertising and has a several servers around the world.
Cheers!
Hi,
I have below questions regarding the installation - I am on Mac. and Installation is done by the symfony installer.
1. when I create a new symfony app, everything works fine, but when I go to localhost:8000/config.php, I get recommendations as below.
To enhance your Symfony experience, it’s recommended that you fix the following:
intl extension should be available
Install and enable the intl extension (used for validators).
a PHP accelerator should be installed
Install and/or enable a PHP accelerator (highly recommended).
Why do I get these? and is it important to fix these issues?
2. The installer does not ask about database (as opposed to installing it via composer).
Is a database automatically created when I create an app?
Thank you for your help.
Hey Nobuyuki!
Yea, good questions!
1) So, both the intl extension and a PHP accelerator (you should use opcache) are both good ideas :). How you install those... depends on how you installed PHP. I recommend installing PHP in a Mac with Homebrew. In that case, installing these extensions (once php is installed) is really easy! (The exact command will vary based on what version of PHP you choose to install):
brew install homebrew/php/php56-intl
brew install homebrew/php/php56-opcache
Let me know if that helps! It won't kill you not to have them... well, probably not :). Opcache just makes things run faster (yay!) and intl is used inside certain parts of the form component for internationalization (so, if you don't use that functionality you're ok, but if you do, you'll need it).
2) There is no database automatically created when you create your app. This is true for both the Symfony installer and installing via Composer. Symfony does come with some configuration (in app/config/parameters.yml) to connect to a database... but it's your responsible to create it (I usually do this through Symfony, with bin/console doctrine:database:create
). When you install via Composer, what you're seeing is not Symfony trying to create your database. Instead, it is simply asking you what database configuration you'd like. It uses this information to create the parameters.yml file. More info here: http://knpuniversity.com/screencast/symfony-fundamentals/parameters.yml-kernel.root_dir#why-is-parameters-yml-special
Let me know if that helps! And welcome :)
Hi, Weaverryan
Thank you for your explanation.
1. I have PHP70 in brew.
I tried below.
brew install homebrew/php/php56-intl
brew install homebrew/php/php56-opcache
But, they did not let me and told me to
brew unlink php70
So, I did. But, now I get the below error.
[Symfony\Component\Debug\Exception\ContextErrorException]
Warning: date_default_timezone_get(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezon
e setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you m
ost likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezon
e.
Now I canot run the server anymore...
What is the issue now? Your help is highly appreciated.
2. I signed up for your course. So, I guess I will learn how to connect it with database soon.
Regards,
Noby
Yo Noby!
Ah, great! So, change both of those commands to be homebrew/php/php70-intl and homebrew/php/php70-opcache - each version of PHP has its own package name for the extensions. So, I think when you ran these commands, you basically installed php 5.6, and so then it told you to "unlink" (basically, stop using) PHP 7 and use php 5.6 instead. That's not a big deal, but if you want to use php 7, then I would re-install it via brew :).
About the date.timezone warning, this is a classic first-time setup thing in PHP! It's annoying, but easy to fix:
1) Locate your php.ini file. You can do this by running this command:
php --ini
Look for the path next to "Loaded Configuration File" - mine is /usr/local/etc/php/5.6/php.ini
2) Open this file, find the date.timezone setting, uncomment it (remove the ; at the beginning if there is one) and set it to your timezone, or UTC. Examples:
date.timezone = America/New_York
; or
date.timezone = UTC
Here's the list of valid timezones: http://php.net/manual/en/timezones.php
3) If you have the bin/console server:run command running, press cmd+c to stop it, then run the command again. This basically "restarts" your web server :).
Cheers!
Yo Ryan!
Thank you very much. It is now working with php7. all installed.
Cheers,
Noby
Sweet! Keep up the good work!
Hi, Ryan
Everything is working except for I get these errors.
PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.57.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
Warning: PHP Startup: Unable to load dynamic library '/usr/local/opt/php70-intl/intl.so' - dlopen(/usr/local/opt/php70-intl/intl.so, 9): Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.57.dylib
Referenced from: /usr/local/opt/php70-intl/intl.so
Reason: image not found in Unknown on line 0
PHP 7.0.12 (cli) (built: Oct 14 2016 09:55:03) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.0.12, Copyright (c) 1999-2016, by Zend Technologies
They are already installed.
Any suggestion to make these errors go away?
Thank you,
Noby
Hey, it's the well known issue, just try to install intl extension from source: brew reinstall --build-from-source php70-intl
. Here's a link for more info: https://github.com/Homebrew/homebrew-php/issues/2544
Cheers!
Hi, Victor
Thank you very much. With the reinstall command you gave me, there is no more issue.
Kind regards,
Noby
Great! Happy coding! :)
Cheers!
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.1.*", // v3.1.4
"doctrine/orm": "^2.5", // v2.7.2
"doctrine/doctrine-bundle": "^1.6", // 1.6.4
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
"symfony/swiftmailer-bundle": "^2.3", // v2.3.11
"symfony/monolog-bundle": "^2.8", // 2.11.1
"symfony/polyfill-apcu": "^1.0", // v1.2.0
"sensio/distribution-bundle": "^5.0", // v5.0.22
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"composer/package-versions-deprecated": "^1.11" // 1.11.99
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.0.7
"symfony/phpunit-bridge": "^3.0" // v3.1.3
}
}
Hi !. I cant open the symfony on localhost:8000.. I use a network sharing host.. And i dont find the way to install it over there and to use it on that URL not in localhost but its not working in no one of this. I followed every step.. Thanks