/ TOOLSSYMFONY
 / 10.59350/pzbtf-ppc17

A Simple CRUD Application with Symfony

By Payton Chung from DCA, USA (crud Uploaded by AlbertHerring) CC BY 2.0 https://creativecommons.org/licenses/by/2.0, via Wikimedia Commons

Create Read Update Delete — these operations describe the most common tasks a relational database is used for.

A common task on top of that, is to build interfaces for users, to execute these operations in a nice way and create a frontend for these task.

Imagine a quite simple application, with two entities, let’s call them Product and Category. A product has some properties, such as title, description and (drum roll) categories. A Product may be categorized in one or more categories. A category only has a title property.

Using my favourite PHP Framework Symfony and the latest convenience tool Symfony Flex make that a straight-forward approach.

First, we need to create a new project with composer create-project symfony/skeleton products and add an admin tool with composer req admin to the project. The last command is responsible for adding the bundle easycorp/easyadmin-bundle to the composer.json file of the project. composer req --dev maker-bundle migrations adds some convenience tools, as you may read later.

Parts of the Symfony 4 configuration parameters rely on environment variables, that in the development process of a project may be set in a .env file. We add our database url to that DATABASE_URL=sqlite:///%kernel.project_dir%/var/data.db. Note: Locally and for quick testing I use sqlite in that case, because we don’t need more sophisticated tools, such as MySQL or Postgres.

Next we create our entities Product and Category: ./bin/console make:entity Product ./bin/console make:entity Category

and add our desired properties in the dialogue. It will create something like:

<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\CategoryRepository")
 */
class Category
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $title;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Product", inversedBy="categories")
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id")
     */
    private $product;

    public function __construct()
    {
        $this->product = new ArrayCollection();
    }
}
<?php

namespace App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
 */
class Product
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $title;

    /**
     * @ORM\Column(type="text")
     */
    private $description;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Category", mappedBy="product")
     */
    private $categories;

    public function __construct()
    {
        $this->categories = new ArrayCollection();
    }
}

For being able to use the CRUD operations on these entities, the schema needs to be applied to the database with ./bin/console doctrine:schema:create and these entities have to be defined in the config/packages/easy_admin.yaml file:

easy_admin:
    entities:
        - App\Entity\Product
        - App\Entity\Category

Et voilà: Our basic admin interface at http://localhost:8000/admin: first admin interface

See our demo dummy application at github.com/subugoe/symfony-crud