DEV Community

Cover image for Getting Started | Building a Shopping Cart with Symfony
Quentin Ferrer
Quentin Ferrer

Posted on • Updated on

Getting Started | Building a Shopping Cart with Symfony


Before coding, we need to set up the working environment and make sure that everything is working well.

Requirements

Setting up the Project

Creating the project

Create a new Symfony project using the Symfony CLI tool:

$ symfony new happy-shop
Enter fullscreen mode Exit fullscreen mode

Launching the Local Web Server

From the project directory, start the web server in the background:

$ cd happy-shop
$ symfony server:start -d
Enter fullscreen mode Exit fullscreen mode

The server started on the port 8000. Open the website http://localhost:8000 in a browser.

1_93VMZOExzO1MDR-dYEMbhg

Installing dependencies

We will need some dependencies for our project. To install these packages, we will use the Symfony CLI:

$ symfony composer req form validator annotations orm twig
Enter fullscreen mode Exit fullscreen mode
  • Form: we will need to build forms for the shopping cart,
  • Validator: it will allow us to validate the data models,
  • Annotations: we will use the annotations format for the configuration of the project,
  • ORM: known as Doctrine, it will help us to persist entities in a database,
  • Twig: all templates will be created using Twig.

Dependencies for developing

The following components will be installed only for developing the project:

$ symfony composer req profiler maker orm-fixtures phpunit browser-kit dama/doctrine-test-bundle --dev
Enter fullscreen mode Exit fullscreen mode
  • Profiler: useful to debug and see details of all requests we will execute,
  • Maker: it helps you to generate a lot of different classes. We will use it all the time during the project,
  • Fixtures: it will be used to load fake products to help us developing the shopping cart,
  • PHPUnit: essential for writing tests,
  • BrowserKit: to test with a Client service that simulates a browser,
  • DoctrineTestBundle: provides a listener to reset the database between tests.

Setting up the Database

We will need to persist entities in permanent storage. We will use the MySQL database.

Adding MySQL to Docker Compose

From the project directory, create a docker-compose.yaml file:

# docker-compose.yaml
version: '3'
services:
  database:
    image: library/mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: happy
      MYSQL_DATABASE: happy_shop
    ports:
      - 3306:3306
Enter fullscreen mode Exit fullscreen mode

This will install the MySQL server at version 8.0 and configure some environment variables that control the database name and credentials. The exposed port will help us access the database from Symfony.

Starting Docker Compose

Start Docker Compose in the background:

$ docker-compose up -d
Enter fullscreen mode Exit fullscreen mode

Changing the Environment Variable

Set up the default DATABASE_URL value to use MySQL:

# .env
###> doctrine/doctrine-bundle ###
DATABASE_URL="mysql://root:happy@127.0.0.1:3306/happy_shop?serverVersion=8.0"
###< doctrine/doctrine-bundle ###
Enter fullscreen mode Exit fullscreen mode

Creating the Database

To create the database, run the following command:

$ bin/console doctrine:database:create --if-not-exists
Enter fullscreen mode Exit fullscreen mode

Creating the Home Page

Creating the Home Controller

Create the HomeController controller via the Maker:

$ symfony console make:controller HomeController
Enter fullscreen mode Exit fullscreen mode

The command creates a HomeController class under the src/Controller/ directory and a template file to templates/home/index.html.twig.

In the HomeController class, define a route to make it match the homepage:

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

class HomeController extends AbstractController
{
    /**
     * @Route("/", name="home")
     */
    public function index(): Response
    {
        return $this->render('home/index.html.twig', [
            'controller_name' => 'HomeController',
        ]);
    }
}
Enter fullscreen mode Exit fullscreen mode

You already can go to the homepage http://localhost:8000. Try it!

Alt Text

Updating the base Layout

All templates will be depending on the base layout to share common elements, like the meta, title, header, and more.

We will use Bootstrap for designing the pages of the project but please note that the design is not the goal of this project so we will just make it functional.

{# templates/base.html.twig #}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>{% block title %}Happy Shop{% endblock %}</title>
    {% block stylesheets %}
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
              integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
              crossorigin="anonymous">
    {% endblock %}
</head>
<body>
{% block header %}
    <nav class="navbar navbar-dark bg-dark sticky-top">
        <a href="{{ path('home') }}" class="navbar-brand">
            Happy Shop
        </a>
    </nav>
{% endblock %}

{% block body %}{% endblock %}
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

This template defines the base HTML skeleton. We've defined the title, header, and body blocks. We also set the viewport to make the app responsive.

To see the result, let's go back to the homepage http://localhost:8000:

Alt Text

We are ready! Let's manage products to the next step.

Discussion (0)