Get Rewarded! We will reward you with up to €50 credit on your account for every tutorial that you write and we publish!

A basic guide to PHP Symfony - Setup

profile picture
Author
Moritz Fromm
Published
2019-04-16
Time to read
12 minutes reading time

Introduction

Symfony is a popular PHP framework.

A framework is a set of components and functions that can be reused multiple times.

For example, it contains Twig, which is a powerful templating engine, so the PHP code is separated from your HTML code.

This tutorial is split into multiple parts. In this one, we go over how to set up our Symfony project. We go over to learn more about controllers and routes. Afterward, we learn a bit about the .env file and start working with the database. Securing our application is crucial so we also take a look at authenticating users.

Series index

  1. Setup (You are here)
  2. Routes, templates and controllers
  3. Working with the database (Not yet finished)
  4. Security (Not yet finished)

Prerequisites

Please note: Those prerequisites are needed at the time of writing. The specific version required, may change at any time.

  • PHP version 7.1.3 or higher.
    • A fair amount of PHP experience is recommended
  • Composer.
    • In this tutorial, we will assume that composer is installed globally and accessible via the command composer
    • Otherwise, you can replace the composer command with php path/to/composer.phar (Read more...)
  • A (simple) code editor, I am using Visual Studio Code

This tutorial is tested on the following operating system:

  • Ubuntu 18.04.2 LTS bionic with PHP 7.2.15

Step 1 - Create a new Symfony project

We will start by creating a simple project. This is based on the symfony/website-skeleton. It provides an already configured Symfony application, so we don't have to configure everything ourselves. The last argument passed is the folder to use. In our case, we use the name of this tutorial: a-basic-guide-to-php-symfony.

$ composer create-project symfony/website-skeleton a-basic-guide-to-php-symfony
(Click to expand) Your output should be similar to this
Installing symfony/website-skeleton (v4.2.3.5)
  - Installing symfony/website-skeleton (v4.2.3.5): Downloading (100%)
Created project in a-basic-guide-to-php-symfony
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 99 installs, 0 updates, 0 removals
  - Installing ocramius/package-versions (1.4.0): Downloading (100%)
  - Installing symfony/flex (v1.2.0): Downloading (100%)

Prefetching 97 packages :notes:
  - Downloading (100%)

  - Installing symfony/polyfill-mbstring (v1.10.0): Loading from cache
  - Installing symfony/contracts (v1.0.2): Loading from cache[
  - Installing doctrine/lexer (v1.0.1): Loading from cache
  - Installing doctrine/annotations (v1.6.0): Loading from cache
  - Installing doctrine/reflection (v1.0.0): Loading from cache
  - Installing doctrine/event-manager (v1.0.0): Loading from cache
  - Installing doctrine/collections (v1.5.0): Loading from cache
  - Installing doctrine/cache (v1.8.0): Loading from cache
  - Installing doctrine/persistence (v1.1.0): Loading from cache
  - Installing symfony/doctrine-bridge (v4.2.3): Loading from cache
  - Installing doctrine/inflector (v1.3.0): Loading from cache
  - Installing doctrine/doctrine-cache-bundle (1.3.5): Loading from cache
  - Installing doctrine/instantiator (1.1.0): Loading from cache
  - Installing symfony/stopwatch (v4.2.3): Loading from cache
  - Installing symfony/console (v4.2.3): Loading from cache
  - Installing zendframework/zend-eventmanager (3.2.1): Loading from cache
  - Installing zendframework/zend-code (3.3.1): Loading from cache
  - Installing ocramius/proxy-manager (2.1.1): Loading from cache
  - Installing doctrine/dbal (v2.9.2): Loading from cache
  - Installing doctrine/migrations (v2.0.0): Loading from cache
  - Installing egulias/email-validator (2.1.7): Loading from cache
  - Installing jdorn/sql-formatter (v1.2.17): Loading from cache
  - Installing phpdocumentor/reflection-common (1.0.1): Loading from cache
  - Installing phpdocumentor/type-resolver (0.4.0): Loading from cache
  - Installing psr/cache (1.0.1): Loading from cache
  - Installing psr/container (1.0.0): Loading from cache
  - Installing psr/simple-cache (1.0.1): Loading from cache
  - Installing symfony/http-foundation (v4.2.3): Loading from cache
  - Installing symfony/event-dispatcher (v4.2.3): Loading from cache
  - Installing psr/log (1.1.0): Loading from cache
  - Installing symfony/debug (v4.2.3): Loading from cache
  - Installing symfony/http-kernel (v4.2.3): Loading from cache
  - Installing symfony/routing (v4.2.3): Loading from cache
  - Installing symfony/finder (v4.2.3): Loading from cache
  - Installing symfony/filesystem (v4.2.3): Loading from cache
  - Installing symfony/dependency-injection (v4.2.3): Loading from cache
  - Installing symfony/config (v4.2.3): Loading from cache
  - Installing symfony/var-exporter (v4.2.3): Loading from cache
  - Installing symfony/cache (v4.2.3): Loading from cache
  - Installing symfony/framework-bundle (v4.2.3): Loading from cache
  - Installing doctrine/common (v2.10.0): Loading from cache
  - Installing sensio/framework-extra-bundle (v5.2.4): Loading from cache
  - Installing symfony/asset (v4.2.3): Loading from cache
  - Installing symfony/dotenv (v4.2.3): Loading from cache
  - Installing symfony/expression-language (v4.2.3): Loading from cache
  - Installing symfony/inflector (v4.2.3): Loading from cache
  - Installing symfony/property-access (v4.2.3): Loading from cache
  - Installing symfony/options-resolver (v4.2.3): Loading from cache
  - Installing symfony/intl (v4.2.3): Loading from cache
  - Installing symfony/polyfill-intl-icu (v1.10.0): Loading from cache
  - Installing symfony/form (v4.2.3): Loading from cache
  - Installing monolog/monolog (1.24.0): Loading from cache
  - Installing symfony/monolog-bridge (v4.2.3): Loading from cache
  - Installing doctrine/orm (v2.6.3): Loading from cache
  - Installing doctrine/doctrine-bundle (1.10.2): Loading from cache
  - Installing doctrine/doctrine-migrations-bundle (v2.0.0): Loading from cache
  - Installing symfony/orm-pack (v1.0.6): Loading from cache
  - Installing symfony/security-core (v4.2.3): Loading from cache
  - Installing symfony/security-http (v4.2.3): Loading from cache
  - Installing symfony/security-guard (v4.2.3): Loading from cache
  - Installing symfony/security-csrf (v4.2.3): Loading from cache
  - Installing symfony/security-bundle (v4.2.3): Loading from cache
  - Installing symfony/serializer (v4.2.3): Loading from cache
  - Installing symfony/property-info (v4.2.3): Loading from cache
  - Installing webmozart/assert (1.4.0): Loading from cache
  - Installing phpdocumentor/reflection-docblock (4.3.0): Loading from cache
  - Installing symfony/serializer-pack (v1.0.2): Loading from cache
  - Installing swiftmailer/swiftmailer (v6.1.3): Loading from cache
  - Installing symfony/swiftmailer-bundle (v3.2.5): Loading from cache
  - Installing symfony/translation (v4.2.3): Loading from cache
  - Installing twig/twig (v2.6.2): Loading from cache
  - Installing symfony/twig-bridge (v4.2.3): Loading from cache
  - Installing symfony/validator (v4.2.3): Loading from cache
  - Installing psr/link (1.0.0): Loading from cache
  - Installing fig/link-util (1.0.0): Loading from cache
  - Installing symfony/web-link (v4.2.3): Loading from cache
  - Installing symfony/yaml (v4.2.3): Loading from cache
  - Installing symfony/process (v4.2.3): Loading from cache
  - Installing facebook/webdriver (1.6.0): Loading from cache
  - Installing symfony/polyfill-php72 (v1.10.0): Loading from cache
  - Installing symfony/var-dumper (v4.2.3): Loading from cache
  - Installing symfony/twig-bundle (v4.2.3): Loading from cache
  - Installing symfony/web-profiler-bundle (v4.2.3): Loading from cache
  - Installing symfony/profiler-pack (v1.0.4): Loading from cache
  - Installing symfony/monolog-bundle (v3.3.1): Loading from cache
  - Installing symfony/debug-bundle (v4.2.3): Loading from cache
  - Installing easycorp/easy-log-handler (v1.0.7): Loading from cache
  - Installing symfony/debug-pack (v1.0.7): Loading from cache
  - Installing symfony/dom-crawler (v4.2.3): Loading from cache
  - Installing nikic/php-parser (v4.2.1): Loading from cache
  - Installing symfony/maker-bundle (v1.11.3): Loading from cache
  - Installing symfony/phpunit-bridge (v4.2.3): Loading from cache
  - Installing symfony/browser-kit (v4.2.3): Loading from cache
  - Installing symfony/panther (v0.3.0): Loading from cache
  - Installing symfony/css-selector (v4.2.3): Loading from cache
  - Installing symfony/test-pack (v1.0.5): Loading from cache
  - Installing symfony/web-server-bundle (v4.2.3): Loading from cache
Generating autoload files
ocramius/package-versions:  Generating version class...
ocramius/package-versions: ...done generating version class
Symfony operations: 21 recipes (8580e8191ddcf764ce7b97e69964e730)
  - Configuring symfony/flex (>=1.0): From github.com/symfony/recipes:master
  - Configuring symfony/framework-bundle (>=4.2): From github.com/symfony/recipes:master
  - Configuring doctrine/annotations (>=1.0): From github.com/symfony/recipes:master
  - Configuring doctrine/doctrine-cache-bundle (>=1.3.5): From auto-generated recipe
  - Configuring symfony/console (>=3.3): From github.com/symfony/recipes:master
  - Configuring symfony/routing (>=4.2): From github.com/symfony/recipes:master
  - Configuring sensio/framework-extra-bundle (>=5.2): From github.com/symfony/recipes:master
  - Configuring doctrine/doctrine-bundle (>=1.6): From github.com/symfony/recipes:master
  - Configuring doctrine/doctrine-migrations-bundle (>=1.2): From github.com/symfony/recipes:master
  - Configuring symfony/security-bundle (>=3.3): From github.com/symfony/recipes:master
  - Configuring symfony/swiftmailer-bundle (>=2.5): From github.com/symfony/recipes:master
  - Configuring symfony/translation (>=3.3): From github.com/symfony/recipes:master
  - Configuring symfony/validator (>=4.1): From github.com/symfony/recipes:master
  - Configuring symfony/twig-bundle (>=3.3): From github.com/symfony/recipes:master
  - Configuring symfony/web-profiler-bundle (>=3.3): From github.com/symfony/recipes:master
  - Configuring symfony/monolog-bundle (>=3.1): From github.com/symfony/recipes:master
  - Configuring symfony/debug-bundle (>=4.1): From github.com/symfony/recipes:master
  - Configuring easycorp/easy-log-handler (>=1.0): From github.com/symfony/recipes:master]
  - Configuring symfony/maker-bundle (>=1.0): From github.com/symfony/recipes:master
  - Configuring symfony/phpunit-bridge (>=4.1): From github.com/symfony/recipes:master
  - Configuring symfony/web-server-bundle (>=3.3): From github.com/symfony/recipes:master
Executing script cache:clear [OK]
Executing script assets:install public [OK]

Some files may have been created or updated to configure your new packages.
Please review, edit and commit them: these files are yours.


 What's next?


  * Run your application:
    1. Change to the project directory
    2. Create your code repository with the git init command
    3. Run composer require server --dev to install the development web server or configure another supported web server https://symfony.com/doc/current/setup/web_server_configuration.html

  * Read the documentation at https://symfony.com/doc


 Database Configuration


  * Modify your DATABASE_URL config in .env

  * Configure the driver (mysql) and
    server_version (5.7) in config/packages/doctrine.yaml


 How to test?


  * Write test cases in the tests/ folder
  * Run php bin/phpunit

Now we can cd (change directory) into the a-basic-guide-to-php-symfony folder. The rest of this tutorial will assume that we are in this directory.

When you are developing "real" applications, using Git as a version control system is a great idea. You can initialize a repository and commit the initial state with the following command:

(Click to expand) How to start a git repository
$ git init
Initialized empty Git repository in /path/to/a-basic-guide-to-php-symfony/.git/
$ git add . # "Stage" all new files
$ git commit -m "Initial commit" # Commit, "takes a snapshot", the current state
[master (root-commit) f98ccb9] Initial commit
 49 files changed, 7412 insertions(+)
 create mode 100644 .env
 create mode 100644 .env.test
 create mode 100644 .gitignore
 create mode 100755 bin/console
 create mode 100755 bin/phpunit
 create mode 100644 composer.json
 create mode 100644 composer.lock
 create mode 100644 config/bootstrap.php
 create mode 100644 config/bundles.php
 create mode 100644 config/packages/cache.yaml
 create mode 100644 config/packages/dev/debug.yaml
 create mode 100644 config/packages/dev/easy_log_handler.yaml
 create mode 100644 config/packages/dev/monolog.yaml
 create mode 100644 config/packages/dev/routing.yaml
 create mode 100644 config/packages/dev/swiftmailer.yaml
 create mode 100644 config/packages/dev/web_profiler.yaml
 create mode 100644 config/packages/doctrine.yaml
 create mode 100644 config/packages/doctrine_migrations.yaml
 create mode 100644 config/packages/framework.yaml
 create mode 100644 config/packages/prod/doctrine.yaml
 create mode 100644 config/packages/prod/monolog.yaml
 create mode 100644 config/packages/routing.yaml
 create mode 100644 config/packages/security.yaml
 create mode 100644 config/packages/sensio_framework_extra.yaml
 create mode 100644 config/packages/swiftmailer.yaml
 create mode 100644 config/packages/test/framework.yaml
 create mode 100644 config/packages/test/monolog.yaml
 create mode 100644 config/packages/test/routing.yaml
 create mode 100644 config/packages/test/swiftmailer.yaml
 create mode 100644 config/packages/test/web_profiler.yaml
 create mode 100644 config/packages/translation.yaml
 create mode 100644 config/packages/twig.yaml
 create mode 100644 config/packages/validator.yaml
 create mode 100644 config/routes.yaml
 create mode 100644 config/routes/annotations.yaml
 create mode 100644 config/routes/dev/twig.yaml
 create mode 100644 config/routes/dev/web_profiler.yaml
 create mode 100644 config/services.yaml
 create mode 100644 phpunit.xml.dist
 create mode 100644 public/index.php
 create mode 100644 src/Controller/.gitignore
 create mode 100644 src/Entity/.gitignore
 create mode 100644 src/Kernel.php
 create mode 100644 src/Migrations/.gitignore
 create mode 100644 src/Repository/.gitignore
 create mode 100644 symfony.lock
 create mode 100644 templates/base.html.twig
 create mode 100644 tests/.gitignore
 create mode 100644 translations/.gitignore

Step 2 - Starting the development server

We do not need to configure a webserver during development. PHP and Symfony bring everything needed. PHP can be used to run a development server with the CLI option -S. Symfony provides a wrapper, specialized for Symfony's needs. With the file bin/console Symfony provides a simple interface to run different commands.

$ php bin/console server:run


 [OK] Server listening on http://127.0.0.1:8000                                                                         


 // Quit the server with CONTROL-C.

PHP 7.2.15-0ubuntu0.18.04.1 Development Server started at Fri Mar  8 22:23:14 2019
Listening on http://127.0.0.1:8000
Document root is /path/to/a-basic-guide-to-php-symfony/public
Press Ctrl-C to quit.

Please note, the address:port part ([0.0.0.0:8080]) is optional and is the address to listen to.

To keep the development server running in the background, the terminal multiplexer tmux is a good option.

Assuming you have not used a custom address port, we can now visit http://localhost:8000/. There we are greeted by the "Welcome to Symfony 4.2.3" page containing a few information about the application. On the bottom we find the profiler, a tool that is useful for debugging later. For now, it can safely be minimized by clicking the small X on the bottom right.

Step 3 - Exploring the file system

Before we start creating our first "real" content, we explore the directory structure of Symfony a bit. The directory structure is like this:

a-basic-guide-to-php-symfony
├── bin
├── config
├── public
├── src
├── templates
├── tests
├── translations
├── var
└── vendor
  • In the bin folder there are files meant to be used from the console. Here is also our bin/console file used to start our development server
  • As the name indicates several configuration files for everything from security to routing (matching the requested URL to the PHP Code) are located in the config folder
  • In the public folder are files located that do not need to be generated dynamically. CSS and JS files may be located here. When you deploy a Symfony application the public folder must be set as webroot.
  • In the src folder, which stands for source, all of our infamous PHP code is located.
  • templates keep the twig templates as mentioned earlier.
  • Symfony has a translations engine built in; the translation files are held in this directory.
  • The var and the vendor folder can be safely ignored but shall not be deleted!

Having done that, we are set and ready to learn something about Routes, Templates and Controllers in the next part of this tutorial.

Conclusion

By now we have setup Symfony and started the development server. This is essential in order to follow along with the next parts.

Want to contribute?

Get Rewarded: Get up to €50 in credit! Be a part of the community and contribute. Do it for the money. Do it for the bragging rights. And do it to teach others!

Report Issue

Discover our

Dedicated Servers

Configure your dream server. Top performance with an excellent connection at an unbeatable price!

Want to contribute?

Get Rewarded: Get up to €50 credit on your account for every tutorial you write and we publish!

Find out more