Skip to content

Instantly share code, notes, and snippets.

@jpalala
Last active October 7, 2025 04:50
Show Gist options
  • Save jpalala/e1877ba712c475ba254988ffa8dfff90 to your computer and use it in GitHub Desktop.
Save jpalala/e1877ba712c475ba254988ffa8dfff90 to your computer and use it in GitHub Desktop.
SYMFONY Cheatsheet

A Symfony cheat sheet provides a quick reference for commonly used commands, configurations, and best practices within the Symfony framework. It typically covers various aspects of Symfony development, including:

  1. Console Commands: Project Management. Code
    php bin/console -V # Check Symfony version
    php bin/console list # List all available commands

Database Operations (Doctrine). Code

    php bin/console doctrine:database:drop --force
    php bin/console doctrine:schema:create
    php bin/console doctrine:schema:update --force
    php bin/console make:migration # Generate a migration
    php bin/console doctrine:migrations:migrate # Execute migrations

Code Generation.

    php bin/console make:entity
    php bin/console make:controller
    php bin/console make:form
    php bin/console make:service
    php bin/console make:user

Debugging and Profiling.


    php bin/console debug:container
    php bin/console debug:router
    php bin/console debug:twig
  1. Routing:
  • Defining routes in YAML, XML, or annotations.
  • Accessing route parameters in controllers.
  • Generating URLs from route names.
  1. Controllers:
  • Basic controller structure.
  • Accessing request data.
  • Returning responses (e.g., JSON, HTML).
  • Using services in controllers.
  1. Twig Templating:

Basic syntax for variables, loops, and conditionals.

Extending templates.

Using Twig functions and filters.

  1. Forms:

Creating form types, Handling form submissions, and Validation constraints.

  1. Doctrine ORM:
  • Defining entities and their relationships.
# 1. Create the database (if it doesn't exist)
php bin/console doctrine:database:create
# 2. Apply all schema changes (creates tables from entities)
php bin/console doctrine:migrations:migrate
  • Basic CRUD operations (Create, Read, Update, Delete).

// Example: Creating a new Product / and quick update (find using repository)

use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;

// Assuming $entityManager is injected (EntityManagerInterface $entityManager)

public function createProduct(EntityManagerInterface $entityManager, string $name, float $price): Product
{
    // 1. Create a new entity object
    $product = new Product();
    $product->setName($name);
    $product->setPrice($price);

    // 2. Tell the Entity Manager to track the new entity (prepare for INSERT)
    $entityManager->persist($product);
    // In then do setX wjem doing update (find the entity  $product = $repository->find($productId);)


    // 3. Execute the pending changes (runs the INSERT query on the database)
    $entityManager->flush();

    return $product;
}

Deleting

/ Example: Deleting a Product

use Doctrine\ORM\EntityManagerInterface;
use App\Repository\ProductRepository;

// Assuming $entityManager and $productRepository are injected

public function deleteProduct(EntityManagerInterface $entityManager, ProductRepository $repository, int $productId): bool
{
    // 1. Fetch the existing entity
    $product = $repository->find($productId);

    if (!$product) {
        return false; // Product not found, nothing to delete
    }

    // 2. Tell the Entity Manager to remove the entity (prepare for DELETE)
    $entityManager->remove($product);

    // 3. Execute the pending changes (runs the DELETE query)
    $entityManager->flush();

    return true;
}
  • Using the Entity Manager
// Deleting example
use App\Entity\Product;
use App\Repository\ProductRepository; // Used to fetch the entity
use Doctrine\ORM\EntityManagerInterface;

/**
 * Deletes a Product entity by its ID.
 */
public function deleteProduct(
    EntityManagerInterface $entityManager, 
    ProductRepository $productRepository, 
    int $productId
): bool {
    // 1. READ: Fetch the entity to be deleted
    // The entity manager now "manages" this object.
    $product = $productRepository->find($productId);

    if (!$product) {
        // Handle the case where the product doesn't exist
        return false;
    }

    // 2. MARK FOR REMOVAL: Tell the Entity Manager to remove this entity
    // This prepares a DELETE query but doesn't execute it yet.
    $entityManager->remove($product);

    // 3. SYNC TO DATABASE: Execute all pending changes (including the DELETE)
    $entityManager->flush();

    return true;
}
  1. Security:

Authentication and authorization, User management, and Firewalls and access control.

  1. Services and Dependency Injection:

a. Defining services in services.yaml and Injecting services into other services or controllers

    namespace App\Service;

    class Calculator
    {
        public function add(int $a, int $b): int
        {
            return $a + $b;
        }
    }

b. Testing

    // src/Service/Calculator.php
    namespace App\Service;

    class Calculator
    {
        public function add(int $a, int $b): int
        {
            return $a + $b;
        }
    }

    // tests/Service/CalculatorTest.php
    namespace App\Tests\Service;

    use App\Service\Calculator;
    use PHPUnit\Framework\TestCase;

    class CalculatorTest extends TestCase
    {
        public function testAddNumbers(): void
        {
            $calculator = new Calculator();
            $result = $calculator->add(5, 7);

            // Assert the result is the expected value (12)
            $this->assertEquals(12, $result, 'The addition result should be 12.');
        }
    }
  1. Best Practices and Tips:

Environment variables, Caching, and Error handling.

Symfony Configuration in Code: Environment Variables, Caching, and Error Handling

In a modern Symfony application (version 4.x and higher), these three aspects are primarily configured through a combination of YAML/PHP configuration files and environment variables.

Here is how the basic setup looks, using the typical Symfony directory structure:


1. Environment Variables (.env & Services)

Symfony uses dotenv files to manage environment variables, and these are then used to configure services and other application settings.

.env and .env.local

The main configuration file where you define variables.

# .env (default values for development)

# Symfony's built-in way to manage environments (dev, prod, test)
APP_ENV=dev

# A secret key used by Symfony for things like session encryption
APP_SECRET=2f229c3272d73315a67f13b194a28753

# Database configuration (used in config/packages/doctrine.yaml)
DATABASE_URL="mysql://app:[email protected]:3306/app_db?serverVersion=8.0.35&charset=utf8mb4"

# Example: External API Key
EXTERNAL_API_KEY="dev_api_key_12345"

Accessing Environment Variables in Code

You typically access these variables by injecting them into your services via configuration, not directly in your PHP code.

// config/services.yaml (Using the %env()% syntax)
services:
    # ...
    App\Service\ApiConnector:
        arguments:
            # The environment variable is automatically injected as a string argument
            $apiKey: '%env(EXTERNAL_API_KEY)%'
// src/Service/ApiConnector.php (The service receiving the key)
namespace App\Service;

class ApiConnector
{
    private string $apiKey;

    public function __construct(string $apiKey)
    {
        $this->apiKey = $apiKey;
    }

    // ... service logic
}

2. Caching (config/packages/cache.yaml)

Caching is configured to use different adapters based on the environment. The framework uses the Cache component and often relies on a high-performance solution like Redis or Memcached in production.

// config/packages/cache.yaml (Example showing different settings per environment)

framework:
    cache:
        # Default cache settings for the application
        app: cache.adapter.filesystem # Use file system caching by default

        # Configure the 'cache.pool.redis' service only for 'prod' environment
when@prod:
    framework:
        cache:
            app: cache.adapter.redis
            pools:
                # Defines the connection to Redis using an environment variable
                redis.pool:
                    adapter: cache.adapter.redis
                    provider: '%env(REDIS_DSN)%'

# .env (for production)
# REDIS_DSN="redis://localhost:6379"

3. Error Handling (config/packages/framework.yaml)

Error handling is primarily configured via the framework.yaml file, specifically the error_controller setting, and is heavily influenced by the APP_ENV variable (Debug mode).

Configuration

// config/packages/framework.yaml

framework:
    # ... other settings

    # The error handler configuration
    error_controller: 'App\Controller\ErrorController::show' # Custom controller (optional)

when@dev:
    framework:
        # Debug is TRUE in development, which shows the detailed stack trace (Whoops/Tracy)
        templating:
            engines: ['twig']
        assets: ~
        php_errors: { log: true }

when@prod:
    framework:
        # Debug is FALSE in production, which shows a generic error page
        # This is the environment where error handling is most critical
        php_errors: { log: true, throw: false }

Custom Error Controller (Optional)

If you use a custom controller to render error pages, it would look something like this:

// src/Controller/ErrorController.php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\ErrorHandler\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Response;

class ErrorController extends AbstractController
{
    public function show(FlattenException $exception): Response
    {
        // Get the HTTP status code (e.g., 404, 500)
        $statusCode = $exception->getStatusCode();

        // Log the error for production environment
        // ... (logging logic here)

        return $this->render('bundles/TwigBundle/Exception/error.html.twig', [
            'status_code' => $statusCode,
            'message' => 'Something went wrong.', // Generic message for public
            'exception' => $exception,
        ], new Response($exception->getMessage(), $statusCode));
    }
}

Symfony Security via Firewall

Implementing firewall authentication with HTTP Basic in a Symfony application involves configuring the security system to use this authentication method within a specific firewall.

1. Configure the security.yaml file:

The core of this setup lies in defining a firewall and enabling http_basic within it.

### config/packages/security.yaml

security:
    # ... other security configurations

    firewalls:
        dev:
            pattern: ^/(_profiler|_wdt|css|images|js)/
            security: false

        main:
            pattern: ^/
            http_basic: ~
            provider: app_user_provider # Replace with your user provider
            # ... other firewall configurations~
  • main: This is the name of your firewall. You can name it appropriately for your application.
  • pattern: ^/: This regular expression indicates that this firewall applies to all URLs. You can adjust this pattern to secure specific paths if needed.
  • http_basic: ~: This enables HTTP Basic authentication for this firewall. Symfony will automatically handle the browser's basic authentication dialog and process the credentials. provider:
  • app_user_provider: This specifies the user provider responsible for loading user details (e.g., username, password) based on the credentials provided by the user. You need to define this user provider elsewhere in your security.yaml or create a custom one.

2. Configure your User Provider:

You need a user provider that Symfony can use to load user information. This could be an entity provider if you're storing users in a database, or a custom provider if you have a different user source.

# config/packages/security.yaml
security:
    # ... firewalls configuration

    providers:
        app_user_provider:
            entity:
                class: App\Entity\User # Replace with your User entity class
                property: email        # Replace with the property used for username (e.g., username, email)

3. Ensure User Entity Implements UserInterface:

Your User entity (or whatever class represents your users) must implement Symfony's UserInterface and provide the necessary methods for retrieving the username, password, and roles.

// src/Entity/User.php
namespace App\Entity;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;

class User implements UserInterface, PasswordAuthenticatedUserInterface
{
    // ... other properties and methods

    public function getUserIdentifier(): string
    {
        return (string) $this->email; // Or your username property
    }

    public function getPassword(): string
    {
        return $this->password;
    }

    public function getRoles(): array
    {
        return ['ROLE_USER']; // Or your actual roles
    }

    // ... other required methods from UserInterface
}

With these configurations, when a request hits a URL covered by the main firewall, and no authenticated user is present, the browser will prompt the user for a username and password via the standard HTTP Basic authentication dialog. Symfony will then attempt to authenticate the user using the configured user provider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment