- Complete Working Example
- Symfony - CMF Edition
- Symfony - REST Edition
- Symfony - Advanced Concepts
- Symfony - Unit Testing
- Symfony - Email Management
- Symfony - Logging
- Symfony - Internationalization
- Cookies & Session Management
- Symfony - Ajax Control
- Symfony - File Uploading
- Symfony - Validation
- Symfony - Forms
- Symfony - Doctrine ORM
- Symfony - View Engine
- Symfony - Routing
- Symfony - Controllers
- Creating a Simple Web Application
- Symfony - Bundles
- Symfony - Expression
- Symfony - Events & EventListener
- Symfony - Service Container
- Symfony - Components
- Symfony - Architecture
- Symfony - Installation
- Symfony - Introduction
- Symfony - Home
Symfony Useful Resources
Selected Reading
- Who is Who
- Computer Glossary
- HR Interview Questions
- Effective Resume Writing
- Questions and Answers
- UPSC IAS Exams Notes
Symfony - Advanced Concepts
In this chapter, we will learn about some advanced concepts in Symfony framework.
HTTP Cache
Caching in a web apppcation improves performance. For example, hot products in a shopping cart web apppcation can be cached for a pmited time, so that it can be presented to the customer in a speedy manner without hitting the database. Following are some basic components of Cache.
Cache Item
Cache Item is a single unit of information stored as a key/value pair. The key should be string and value can be any PHP object. PHP objects are stored as string by seriapzation and converted back into objects while reading the items.
Cache Adapter
Cache Adapter is the actual mechanism to store the item in a store. The store may be a memory, file system, database, redis, etc. Cache component provides an AdapterInterface through which an adapter can store cache item in a back-end store. There are lot of built-in cache adapters available. Few of them are as follows −
Array Cache adapter - Cache items are stored in PHP array.
Filesystem Cache adapter - Cache items are stored in files.
PHP Files Cache Adapter - Cache items are stored as php files.
APCu Cache Adapter - Cache items are stored in shared memory using PHP APCu extenstion.
Redis Cache Adapter - Cache items are stored in Redis server.
PDO and Doctrine DBAL Cache Adapter - Cache items are stored in the database.
Chain Cache Adapter - Combines multiple cache adapters for reppcation purpose.
Proxy Cache Adapter - Cache items are stored using third party adapter, which implements CacheItemPoolInterface.
Cache Pool
Cache Pool is a logical repository of cache items. Cache pools are implemented by cache adapters.
Simple Apppcation
Let us create a simple apppcation to understand the cache concept.
Step 1 − Create a new apppcation, cache-example.
cd /path/to/app mkdir cache-example cd cache-example
Step 2 − Install cache component.
composer require symfony/cache
Step 3 − Create a file system adapter.
require __DIR__ . /vendor/autoload.php ; use SymfonyComponentCacheAdapterFilesystemAdapter; $cache = new FilesystemAdapter();
Step 4 − Create a cache item using getItem and set method of adapter. getItem fetches the cache item using its key. if the key is not persent, it creates a new item. set method stores the actual data.
$usercache = $cache->getitem( item.users ); $usercache->set([ jon , peter ]); $cache->save($usercache);
Step 5 − Access the cache item using getItem, isHit and get method. isHit informs the availabipty of the cache item and get method provides the actual data.
$userCache = $cache->getItem( item.users ); if(!$userCache->isHit()) { echo "item.users is not available"; } else { $users = $userCache->get(); var_dump($users); }
Step 6 − Delete the cache item using deleteItem method.
$cache->deleteItem( item.users );
The complete code psting is as follows.
<?php require __DIR__ . /vendor/autoload.php ; use SymfonyComponentCacheAdapterFilesystemAdapter; $cache = new FilesystemAdapter(); $usercache = $cache->getitem( item.users ); $usercache->set([ jon , peter ]); $cache->save($usercache); $userCache = $cache->getItem( item.users ); if(!$userCache->isHit()) { echo "item.users is not available"; } else { $users = $userCache->get(); var_dump($users); } $cache->deleteItem( item.users ); ?>
Result
array(2) { [0]=> string(3) "jon" [1]=> string(5) "peter" }
Debug
Debugging is one of the most frequent activity while developing an apppcation. Symfony provides a separate component to ease the process of debugging. We can enable Symfony debugging tools by just calpng the enable method of Debug class.
use SymfonyComponentDebugDebug Debug::enable()
Symfony provides two classes, ErrorHandler and ExceptionHandler for debugging purpose. While ErrorHandler catches PHP errors and converts them into exceptions, ErrorException or FatalErrorException, ExceptionHandler catches uncaught PHP exceptions and converts them into useful PHP response. ErrorHandler and ExceptionHandler are disabled by default. We can enable it by using the register method.
use SymfonyComponentDebugErrorHandler; use SymfonyComponentDebugExceptionHandler; ErrorHandler::register(); ExceptionHandler::register();
In a Symfony web apppcation, the debug environment is provided by DebugBundle. Register the bundle in AppKernel s registerBundles method to enable it.
if (in_array($this->getEnvironment(), [ dev , test ], true)) { $bundles[] = new SymfonyBundleDebugBundleDebugBundle(); }
Profiler
Development of an apppcation needs a world-class profipng tool. The profipng tool collects all the run-time information about an apppcation such as execution time, execution time of inspanidual modules, time taken by a database activity, memory usage, etc. A web apppcation needs much more information such as the time of request, time taken to create a response, etc. in addition to the above metrics.
Symfony enables all such information in a web apppcation by default. Symfony provides a separate bundle for web profipng called WebProfilerBundle. Web profiler bundle can be enabled in a web apppcation by registering the bundle in the AppKernel s registerBundles method.
if (in_array($this->getEnvironment(), [ dev , test ], true)) { $bundles[] = new SymfonyBundleWebProfilerBundleWebProfilerBundle(); }
The web profile component can be configured under web_profile section of the apppcation configuration file, app/config/config.xml
web_profiler: toolbar: false position: bottom
Symfony apppcation shows the profiled data at the bottom of the page as a distinct section.
Symfony also provides an easy way to add custom details about the page in the profile data using DataCollectorInterface interface and twig template. In short, Symfony enables a web developer to create a world-class apppcation by providing a great profipng framework with relative ease.
Security
As discussed earper, Symfony provides a robust security framework through its security component. The security component is spanided into four sub-components as follows.
symfony/security-core - Core security functionapty.
symfony/security-http - Integrated security feature in HTTP protocol.
symfony/security-csrf - Protection against cross-site request forgery in a web apppcation.
symfony/security-acl - Advanced access control pst based security framework.
Simple Authentication and Authorization
Let us learn the concept of authentication and authorization using a simple demo apppcation.
Step 1 − Create a new web apppcation securitydemo using the following command.
symfony new securitydemo
Step 2 − Enable the security feature in the apppcation using the security configuration file. The security related configuration are placed in a separate file, security.yml. The default configuration is as follows.
security: providers: in_memory: memory: ~ firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: ~ #http_basic: ~ #form_login: ~
The default configuration enables memory-based security provider and anonymous access to all pages. The firewall section excludes the files matching the pattern, ^/(_(profiler|wdt)|css|images|js)/ from the security framework. The default pattern includes stylesheets, images, and JavaScripts (plus dev tools pke profiler).
Step 3 − Enable HTTP based security authenticate system by adding http_basic option in main section as follows.
security: # ... firewalls: # ... main: anonymous: ~ http_basic: ~ #form_login: ~
Step 4 − Add some users in the memory provider section. Also, add roles for the users.
security: providers: in_memory: memory: users: myuser: password: user roles: ROLE_USER myadmin: password: admin roles: ROLE_ADMIN
We have added two users, user in role ROLE_USER and admin in role ROLE_ADMIN.
Step 5 − Add the encoder to get complete details of the current logged-in user. The purpose of the encoder is to get complete details of the current user object from the web request.
security: # ... encoders: SymfonyComponentSecurityCoreUserUser: bcrypt # ...
Symfony provides an interface, UserInterface to get user details such as username, roles, password, etc. We need to implement the interface to our requirement and configure it in the encoder section.
For example, let us consider that the user details are in the database. Then, we need to create a new User class and implement UserInterface methods to get the user details from the database. Once the data is available, then the security system uses it to allow/deny the user. Symfony provides a default User implementation for Memory provider. Algorithm is used to decrypt the user password.
Step 6 − Encrypt the user password using bcrypt algorithm and place it in the configuration file. Since we used bcrypt algorithm, User object tries to decrypt the password specified in configuration file and then tries to match with the password entered by the user. Symfony console apppcation provides a simple command to encrypt the password.
php bin/console security:encode-password admin Symfony Password Encoder Utipty ================================ ------------------ ----------------------------------- Key Value ------------------ ------------------------------------ Encoder used SymfonyComponentSecurityCoreEncoderBCryptPasswordEncoder Encoded password $2y$12$0Hy6/.MNxWdFcCRDdstHU.hT5j3Mg1tqBunMLIUYkz6..IucpaPNO ------------------ ------------------------------------ ! [NOTE] Bcrypt encoder used: the encoder generated its own built-in salt. [OK] Password encoding succeeded
Step 7 − Use the command to generate the encrypted password and update it in the configuration file.
# To get started with security, check out the documentation: # http://symfony.com/doc/current/security.html security: # http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded providers: in_memory: memory: users: user: password: $2y$13$WsGWNufreEnVK1InBXL2cO/U7WftvfNvH Vb/IJBH6JiYoDwVN4zoi roles: ROLE_USER admin: password: $2y$13$jQNdIeoNV1BKVbpnBuhKRuOL01NeMK F7nEqEi/Mqlzgts0njK3toy roles: ROLE_ADMIN encoders: SymfonyComponentSecurityCoreUserUser: bcrypt firewalls: # disables authentication for assets and the profiler, # adapt it according to your needs dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: ~ # activate different ways to authenticate # http://symfony.com/doc/current/security.html#a-co nfiguring-howyour-users-will-authenticate http_basic: ~ # http://symfony.com/doc/current/cookbook/security/ form_login_setup.html #form_login: ~
Step 8 − Now, apply the security to some section of the apppcation. For example, restrict admin section to the users in role, ROLE_ADMIN.
security: # ... firewalls: # ... default: # ... access_control: # require ROLE_ADMIN for /admin* - { path: ^/admin, roles: ROLE_ADMIN }
Step 9 − Add an admin page in DefaultController as follows.
/** * @Route("/admin") */ pubpc function adminLandingAction() { return new Response( <html><body>This is admin section.</body></html> ); }
Step 10 − Finally, access the admin page to check the security configuration in a browser. The browser will ask for the username and password and only allow configured users.
Result
Workflow
Workflow is an advanced concept having usage in many enterprise apppcations. In an ecommerce apppcation, the product depvery process is a workflow. The product is first billed (order creation), procured from the store and packaged (packaging/ready to dispatch), and dispatched to the user. If there is any issue, the product returns from the user and the order is reverted. Order of the flow of action is very important. For example, we can t depver a product without bilpng.
Symfony component provides an object-oriented way to define and manage a workflow. Each step in a process is called place and the action required to move from one place to another is called transition. The collection of places and transition to create a workflow is called a Workflow definition.
Let us understand the concept of workflow by creating a simple apppcation for leave management.
Step 1 − Create a new apppcation, workflow-example.
cd /path/to/dev mkdir workflow-example cd workflow-example composer require symfony/workflow
Step 2 − Create a new class, Leave having appped_by, leave_on and status attributes.
class Leave { pubpc $appped_by; pubpc $leave_on; pubpc $status; }
Here, appped_by refers to the employees who want leave. leave_on refers to the date of leave. status refers to the leave status.
Step 3 − Leave management has four places, appped, in_process and approved / rejected.
use SymfonyComponentWorkflowDefinitionBuilder; use SymfonyComponentWorkflowTransition; use SymfonyComponentWorkflowWorkflow; use SymfonyComponentWorkflowMarkingStoreSingleStateMarkingStore; use SymfonyComponentWorkflowRegistry; use SymfonyComponentWorkflowDumperGraphvizDumper; $builder = new DefinitionBuilder(); $builder->addPlaces([ appped , in_process , approved , rejected ]);
Here, we have created a new definition using DefinitionBuilder and added places using addPlaces method.
Step 4 − Define the actions required to move from one place to another place.
$builder->addTransition(new Transition( to_process , appped , in_process )); $builder->addTransition(new Transition( approve , in_process , approved )); $builder->addTransition(new Transition( reject , in_process , rejected ));
Here, we have three transitions, to_process, approve and reject. to_process transition accepts the leave apppcation and moves the place from appped to in_process. approve transition approves the leave apppcation and moves the place to approved. Similarly, reject transition rejects the leave apppcation and moves the place to rejected. We have created all transitions using addTransition method.
Step 5 − Build the definition using build method.
$definition = $builder->build();
Step 6 − Optionally, the definition can be dumped as graphviz dot format, which can be converted to image file for reference purpose.
$dumper = new GraphvizDumper(); echo $dumper->dump($definition);
Step 7 − Create a marking store, which is used to store the current places/status of the object.
$marking = new SingleStateMarkingStore( status );
Here, we have used SingleStateMarkingStore class to create the mark and it marks the current status into the status property of the object. In our example, the object is Leave object.
Step 8 − Create the workflow using definition and marking.
$leaveWorkflow = new Workflow($definition, $marking);
Here, we have used Workflow class to create the workflow.
Step 9 − Add the workflow into the registry of the workflow framework using Registry class.
$registry = new Registry(); $registry->add($leaveWorkflow, Leave::class);
Step 10 − Finally, use the workflow to find whether a given transition is appped using can method and if so, apply the transition using apply method. When a transition is appped, the status of the object moves from one place to another.
$workflow = $registry->get($leave); echo "Can we approve the leave now? " . $workflow->can($leave, approve ) . " "; echo "Can we approve the start process now? " . $workflow->can($leave, to_process ) . " "; $workflow->apply($leave, to_process ); echo "Can we approve the leave now? " . $workflow->can($leave, approve ) . " "; echo $leave->status . " "; $workflow->apply($leave, approve ); echo $leave->status . " ";
The complete coding is as follows −
<?php require __DIR__ . /vendor/autoload.php ; use SymfonyComponentWorkflowDefinitionBuilder; use SymfonyComponentWorkflowTransition; use SymfonyComponentWorkflowWorkflow; use SymfonyComponentWorkflowMarkingStoreSingleStateMarkingStore; use SymfonyComponentWorkflowRegistry; use SymfonyComponentWorkflowDumperGraphvizDumper; class Leave { pubpc $appped_by; pubpc $leave_on; pubpc $status; } $builder = new DefinitionBuilder(); $builder->addPlaces([ appped , in_process , approved , rejected ]); $builder->addTransition(new Transition( to_process , appped , in_process )); $builder->addTransition(new Transition( approve , in_process , approved )); $builder->addTransition(new Transition( reject , in_process , rejected )); $definition = $builder->build(); // $dumper = new GraphvizDumper(); // echo $dumper->dump($definition); $marking = new SingleStateMarkingStore( status ); $leaveWorkflow = new Workflow($definition, $marking); $registry = new Registry(); $registry->add($leaveWorkflow, Leave::class); $leave = new Leave(); $leave->appped_by = "Jon"; $leave->leave_on = "1998-12-12"; $leave->status = appped ; $workflow = $registry->get($leave); echo "Can we approve the leave now? " . $workflow->can($leave, approve ) . " "; echo "Can we approve the start process now? " . $workflow->can($leave, to_process ) . " "; $workflow->apply($leave, to_process ); echo "Can we approve the leave now? " . $workflow->can($leave, approve ) . " "; echo $leave->status . " "; $workflow->apply($leave, approve ); echo $leave->status . " "; ?>
Result
Can we approve the leave now? Can we approve the start process now? 1 Can we approve the leave now? 1 in_process approvedAdvertisements