This document discusses various tips and tricks for optimizing Symfony projects. It covers caching with Doctrine, using the Sentry error monitoring service, queueing emails with Swiftmailer, implementing custom voters for access control, and using process managers like PHP-PM and PHPFastCGI to improve performance by keeping the framework bootstrapped across requests. The document provides code examples and benchmarks to demonstrate how these techniques can enhance a Symfony application.
20. CACHING MODE
READ_ONLY (DEFAULT)
■ Can do reads,
inserts and
deletes, cannot
perform updates
or employ any
locks.
■ Useful for data
that is read
frequently but
never updated.
■ Best performer.
■ It is Simple.
NONSTRICT_READ_WRITE
■ Read Write Cache
doesn t employ
any locks but can
do reads, inserts,
updates and
deletes.
■ Good if the
application needs
to update data
rarely.
READ_WRITE
■ Read Write cache
employs locks
before
update/delete.
■ Use if data needs
to be updated.
■ Slowest strategy.
■ To use it a the
cache region
implementation
must support
locking.
21. <?php
/**
* @Entity
*
* @Cache(usage="READ_ONLY", region="my_entity_region")
*
*/
class Country
{
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
protected $id;
/**
* @Column(unique=true)
*/
protected $name;
// other properties and methods
}
#ENTITY
22. <?php
/**
* @Entity
* @Cache("NONSTRICT_READ_WRITE")
*/
class State
{
/**
* @Id
* @GeneratedValue
* @Column(type="integer")
*/
protected $id;
/**
* @Column(unique=true)
*/
protected $name;
#CACHE ASSOCIATION
/**
* @Cache("NONSTRICT_READ_WRITE")
* @ManyToOne(targetEntity="Country")
* @JoinColumn(name="country_id",
referencedColumnName="id")
*/
protected $country;
/**
* @Cache("NONSTRICT_READ_WRITE")
* @OneToMany(targetEntity="City", mappedBy="state")
*/
protected $cities;
// other properties and methods
}
The most common use case is to cache entities. But we can also cache relationships. It caches the primary keys of association and
cache each element will be cached into its region.
25. #BEST FEATURES
◇ KNOW
IMMEDIATELY IF
SOMETHING GOES
WRONG
◇ SNOZE TIL NEXT
VERSION
◇ SEE THE IMPACT
OF EACH RELEASE
IN REAL-TIME
◇ COLLECT AND
GROUP ERRORS
◇ DIAGNOSE AND FIX
ISSUES FASTER
THAN EVER
◇ NOTIFICATIONS
AND EXTRA
READABLE LOGS
40. PHP-PM
...is a process manager, supercharger and load balancer for
PHP applications.
It's based on ReactPHP and works best with applications that
use request-response frameworks like Symfony's HTTPKernel.
The approach of this is to kill the expensive bootstrap of PHP
(declaring symbols, loading/parsing files) and the bootstrap of
feature-rich frameworks. See Performance section for a quick
hint. PHP-PM basically spawns several PHP instances as
worker bootstraping your application (eg. the whole Symfony
Kernel) and hold it in the memory to be prepared for every
incoming request: This is why PHP-PM makes your application
so fast.
41. # change minimum-stability to dev in your composer.json (until
we have a version tagged): "minimum-stability": "dev"
composer require php-pm/php-pm:dev-master
composer require php-pm/httpkernel-adapter:
dev-master #if you have httpkernel (laravel,
symfony)
./vendor/bin/ppm config --bootstrap=symfony
#places a ppm.json in your directory
./vendor/bin/ppm start
#reads ppm.json and starts the server like
you want
#INSTALLATION
42. There will be a memory leak !
Fabpot is working on it.
45. Server Software:
Server Hostname: localhost
Server Port: 8001
Document Path: /
Document Length: 26037 bytes
Concurrency Level: 10
Time taken for tests: 133.327 seconds
Complete requests: 5000
Failed requests: 0
Total transferred: 131720000 bytes
HTML transferred: 130185000 bytes
Requests per second: 37.50 [#/sec] (mean)
Time per request: 266.654 [ms] (mean)
Time per request: 26.665 [ms] (mean, across all concurrent requests)
Transfer rate: 964.79 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 1
Processing: 235 266 7.2 265 469
Waiting: 219 260 7.2 259 463
Total: 236 266 7.2 265 469
dev s:start localhost:8001
46. Server Software:
Server Hostname: localhost
Server Port: 8001
Document Path: /
Document Length: 26050 bytes
Concurrency Level: 10
Time taken for tests: 12.233 seconds
Complete requests: 5000
Failed requests: 0
Total transferred: 131255000 bytes
HTML transferred: 130250000 bytes
Requests per second: 408.72 [#/sec] (mean)
Time per request: 24.466 [ms] (mean)
Time per request: 2.447 [ms] (mean, across all concurrent requests)
Transfer rate: 10477.97 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 10 24 15.1 23 524
Waiting: 7 22 14.9 20 519
Total: 10 24 15.1 23 524
./vendor/bin/ppm start
50. PHPFastCGI
…is a collection of libraries that can be used to build FastCGI
applications in PHP. Unlike normal PHP applications, these
applications can stay alive between request cycles - improving
speed and lowering resource use. is a process manager,
supercharger and load balancer for PHP applications
Speedfony Bundle.
A symfony2 bundle which allows applications to reduce
overheads by exposing symfony's Request-Response structure
to a FastCGI daemon.
51. BUT
STILL NOT STABLE
composer require "phpfastcgi/speedfony-bundle:^0.8"
// app/AppKernel.php
// ...
new PHPFastCGISpeedfonyBundlePHPFastCGISpeedfonyBundle(),
php app/console speedfony:run --port 5000 --env="prod"
52. Conclusion
There is lots to be gained and lots to be
lost by daemonizing your PHP
applications. It is very important that
you are aware of the potential issues
you could face and how to mitigate
these. However, with a properly
designed and carefully considered
application - you can reach response
speeds well beyond the dreaming limits
of conventional PHP applications.