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:
- 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
- Routing:
- Defining routes in YAML, XML, or annotations.
- Accessing route parameters in controllers.
- Generating URLs from route names.
- Controllers:
- Basic controller structure.
- Accessing request data.
- Returning responses (e.g., JSON, HTML).
- Using services in controllers.
- Twig Templating:
Basic syntax for variables, loops, and conditionals.
Extending templates.
Using Twig functions and filters.
- Forms:
Creating form types, Handling form submissions, and Validation constraints.
- 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;
}
/ 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;
}
- Security:
Authentication and authorization, User management, and Firewalls and access control.
- 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.');
}
}
- Best Practices and Tips:
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:
Symfony uses dotenv files to manage environment variables, and these are then used to configure services and other application settings.
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"
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
}
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"
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).
// 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 }
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));
}
}