Let’s make a Basic CRUD App in Symfony.
Symfony is a powerful PHP framework well-suited for building complex applications with clean code and modern architecture. In this tutorial, we’ll walk through how to create a simple CRUD (Create, Read, Update, Delete) application using Symfony 6 or 7, featuring a Job
entity.
Prerequisites
- PHP >= 8.1
- Composer
- Symfony CLI
- A database (e.g., MySQL or SQLite)
composer create-project symfony/skeleton job-crud
cd job-crud
composer require webapp doctrine annotations maker
Step 1: Create the Job Entity
Use Symfony Maker to generate your entity.
php bin/console make:entity Job
Fill in the fields:
- title (string)
- description (text)
- company (string)
- location (string)
- createdAt (datetime)
Once the entity is created, run the migration commands:
php bin/console make:migration
php bin/console doctrine:migrations:migrate
Step 2: Generate the CRUD for Job
Use Symfony Maker again to scaffold the CRUD operations.
php bin/console make:crud Job
This command will generate:
- A controller:
JobController.php
- A Twig template directory:
templates/job/
- A form type class:
JobType.php
Step 3: Test Your Routes
After the CRUD is generated, you can access your app in the browser (e.g., http://localhost:8000/job) to:
- List all jobs
- Add a new job
- Edit an existing job
- Delete a job
Start your Symfony server if you haven’t already:
symfony server:start
Step 4: Linking to Another Entity (e.g., Category)
Let’s say we want to assign each Job to a Category
. First, create the Category
entity:
php bin/console make:entity Category
Fields:
- name (string)
Add the relation to Job
:
In Job
entity:
#[ORM\ManyToOne(inversedBy: 'jobs')]
#[ORM\JoinColumn(nullable: false)]
private ?Category $category = null;
In Category
entity:
#[ORM\OneToMany(mappedBy: 'category', targetEntity: Job::class)]
private Collection $jobs;
public function __construct()
{
$this->jobs = new ArrayCollection();
}
Run migrations again:
php bin/console make:migration
php bin/console doctrine:migrations:migrate
Update the form:
In JobType.php
, add the category field:
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
->add('category', EntityType::class, [
'class' => Category::class,
'choice_label' => 'name',
])
Step 5: Customize the Templates (Optional)
You can now tweak the templates in templates/job/
to make the UI more user-friendly. For example, update index.html.twig
to include links to edit/delete, and show related categories.
Example:
{% for job in jobs %}
<tr>
<td>{{ job.title }}</td>
<td>{{ job.category.name }}</td>
<td>{{ job.company }}</td>
<td>
<a href="{{ path('app_job_edit', {'id': job.id}) }}">Edit</a>
<form method="post" action="{{ path('app_job_delete', {'id': job.id}) }}" onsubmit="return confirm('Are you sure?');">
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ job.id) }}">
<button class="btn btn-danger">Delete</button>
</form>
</td>
</tr>
{% endfor %}
Step 6: Validate and Secure
You can add validation rules in the Job
entity using PHP attributes:
use Symfony\Component\Validator\Constraints as Assert;
#[Assert\NotBlank]
#[Assert\Length(min: 3)]
private ?string $title = null;
Then, enable validation in your controller (already done if you use Symfony’s generated forms).
You may also want to restrict access using Symfony Security Bundle (optional for beginners).
Summary
You now have a basic Symfony application that:
- Defines a
Job
entity - Implements full CRUD for
Job
- Links jobs to categories with a relationship
- Uses forms, Doctrine ORM, and Twig templates
Symfony’s Maker bundle and structured architecture make these tasks straightforward and clean. This foundation can be extended into a real-world job board, admin panel, or any business app.
Leave a Reply