SlideShare una empresa de Scribd logo
1 de 65
Descargar para leer sin conexión
Symfony2
The Unofficial “Best” Practices
Gerry Vandermaesen
AKA
How Gerry Does Symfony2
About Me
• Developer and trainer at King Foo
• SensioLabs Certified Symfony Developer
• We develop tailor-made PHP applications
• @gerryvdm / gerry@king-foo.be
The Official Best Practices
• Excellent guidelines for beginning Symfony
developers
• Use a single bundle for application specific
code
• Use the app/Resources/views/ directory for
all application specific templates
• Use YAML for application configuration
Keep your Business Logic
Outside Bundles
• Your business logic hopefully outlives
Symfony2
• Keep your model agnostic / decoupled from
the framework (and ORM)
Keep Mapping and Validation Configuration

Outside Entity Classes
=
Do Not Use Annotations
# config.yml 

doctrine:

orm:

auto_mapping: false

mappings:

model:

type: yml

prefix: KingFooPresentationModel

dir: %kernel.root_dir%/config/doctrine

alias: Model
Tip:

Defining Constraints in

app/config/validation.yml
use SymfonyComponentDependencyInjectionCompilerCompilerPassInterface;

use SymfonyComponentDependencyInjectionContainerBuilder;



class RegisterValidationMappingsPass implements CompilerPassInterface

{

public function process(ContainerBuilder $container)

{

if ($container->hasDefinition('validator.builder')) {

$file = $container->getParameter('kernel.root_dir') .

'/config/validation.yml';



$container->getDefinition('validator.builder')

->addMethodCall('addYamlMappings', [$file]);

}

}

}
Combo-Tip:
Defining Constraints in

app/config/validation/*.yml
use SymfonyComponentDependencyInjectionCompilerCompilerPassInterface;

use SymfonyComponentDependencyInjectionContainerBuilder;

use SymfonyComponentFinderFinder;



class RegisterValidationMappingsPass implements CompilerPassInterface

{

public function process(ContainerBuilder $container)

{

if ($container->hasDefinition('validator.builder')) {

$dir = $container->getParameter('kernel.root_dir') .

'/config/validation';



$finder = new Finder();

$finder->files()->name('*.yml')->in($dir);



$files = [];



foreach ($finder as $file) {

$files[] = $file->getRealPath();

}



if (count($files)) {

$container->getDefinition('validator.builder')

->addMethodCall('addYamlMappings', [$files]);

}

}

}

}
The Front Controller
$kernel = new AppKernel('prod', false);
use SymfonyComponentDebugDebug;
$env = getenv('SYMFONY_ENV') ?: 'prod';

$debug = getenv('SYMFONY_DEBUG') === '1' && $env !== 'prod';
if ($debug) {

Debug::enable();

}
$kernel = new AppKernel($env, $debug);
<VirtualHost *:80>

# ...

SetEnv SYMFONY_ENV dev

SetEnv SYMFONY_DEBUG 1

</VirtualHost>
server {

location /app.php {

# ...

fastcgi_param SYMFONY_ENV dev;

fastcgi_param SYMFONY_DEBUG 1;

}

}
Apache
Nginx
Taking It One Step Further
server {

# ...



location / {

try_files $uri @app;

}



location @app {

fastcgi_pass unix:/var/run/php5-fpm.sock;

include fastcgi_params;



fastcgi_param SCRIPT_FILENAME /path/to/project/app/app.php;

fastcgi_param SCRIPT_NAME /path/to/project/app/app.php;



fastcgi_param SYMFONY_ENV dev;

fastcgi_param SYMFONY_DEBUG 1;

}

}

Use PSR-4 for
the `src/` Directory
{

"autoload": {

"psr-4": { "KingFooPresentation": "src/" }

}

}
💫
Prevent Autoloading of

Tests in Production
{

"autoload": {

"psr-4": { "KingFooPresentation": "src/" }

},

"autoload-dev": {

"psr-4": { “KingFooPresentationTests”: "tests/" }

}

}

Add Requirements to
your Routes
# routing.yml

homepage:

path: /{_locale}



ticket_index:

path: /{_locale}/tickets



tickets_detail:

path: /{_locale}/tickets/{id}



tickets_create:

path: /{_locale}/tickets/create



login:

path: /login
# routing.yml

homepage:

path: /{_locale}

requirements: { _locale: "(nl|fr|en)" }



ticket_index:

path: /{_locale}/tickets

requirements: { _locale: "(nl|fr|en)" }



tickets_detail:

path: /{_locale}/tickets/{id}

requirements: { _locale: "(nl|fr|en)", id: "[1-9][0-9]*" }



tickets_create:

path: /{_locale}/tickets/create

requirements: { _locale: "(nl|fr|en)" }



login:

path: /login
Regex 😕
Global “Requirements”
use SymfonyComponentHttpKernelEventGetResponseEvent;

use SymfonyComponentHttpKernelExceptionNotFoundHttpException;



class CheckLocaleListener

{

private $availableLocales;



public function __construct(array $availableLocales)

{

$this->availableLocales = $availableLocales;

}



public function checkLocale(GetResponseEvent $event)

{

$request = $event->getRequest();



if ($locale = $request->attributes->get('_locale')) {

if (!in_array($locale, $this->availableLocales)) {

throw new NotFoundHttpException();

}

}

}

}
# services.yml

parameters:

available_locales: [nl, fr, en]



services:

check_locale_listener:

class: CheckLocaleListener

arguments: [%available_locales%]

tags:

- name: kernel.event_listener

event: kernel.request

method: checkLocale

priority: 24
Bring Order in your
Services Configuration
# services.yml



# 500 lines of service declarations...
# services.yml

imports:

- { resource: services/controllers.yml }

- { resource: services/event_listeners.yml }

- { resource: services/repositories.yml }

Try Defining Your Services
as Private
# services.yml

services:

my_fantastic_service:

class: KingFooPresentationFantasticService

public: false
class DependentService extends ContainerAware

{

public function doSomething()

{

$this->container->get('my_fantastic_service')

->doSomethingElse();

}

}
class DependentService

{

public function __construct(FantasticService $service)

{

$this->service = $service;

}



public function doSomething()

{

$this->service->doSomethingElse();

}

}
Define your Repositories
as Services
# repositories.yml

services:

abstract_repository:

abstract: true

factory_service: doctrine.orm.entity_manager

factory_method: getRepository

public: false

blog_post_repository:

parent: abstract_repository

class: KingFooPresentationRepositoryBlogPostRepository

arguments: [Model:BlogPost]

comment_repository:

parent: abstract_repository

class: KingFooPresentationRepositoryCommentRepository

arguments: [Model:Comment]
Define your Controllers
as Services
# controllers.yml

services:

blog_post_controller:

class: KingFooPresentationControllerBlogPostController

arguments:

- @blog_post_repository

- @doctrine.orm.entity_manager
One Controller One Action
# controllers.yml

services:

blog_post_list_controller:

class: KingFooPresentationControllerBlogPostListController

arguments: [@blog_post_repository]

blog_post_create_controller:

class: KingFooPresentationControllerBlogPostCreateController

arguments: [@doctrine.orm.entity_manager]
<?php



namespace KingFooPresentationControllerBlogPost;



use DoctrineCommonPersistenceObjectManager;

use SymfonyComponentHttpFoundationRequest;



class CreateController

{

public function __construct(ObjectManager $manager)

{

// ...

}



public function __invoke(Request $request)

{

// ...

}

}
Annotate your Controllers
public function __invoke(Request $request)

{

if (!$this->authorizationChecker->isGranted('ROLE_EDITOR')) {

throw new AccessDeniedHttpException();

}



$response = new Response();

$response->setMaxAge(3600);



return $this->templating->renderResponse(

'blog_post/create.html.twig',

array(

// view parameters

),

$response

);

}
use SensioBundleFrameworkExtraBundleConfigurationCache;

use SensioBundleFrameworkExtraBundleConfigurationRoute;

use SensioBundleFrameworkExtraBundleConfigurationSecurity;

use SensioBundleFrameworkExtraBundleConfigurationTemplate;



/**

* @Route(service="blog_post_create_controller")

*/

class CreateController

{

/**

* @Route("/blog/create", name="foo")

* @Cache(maxage=3600)

* @Security("has_role('ROLE_EDITOR')")

* @Template("blog_post/create.html.twig")

*/

public function __invoke(Request $request)

{

return array(

// view parameters

);

}

}
Never Circumvent the
Framework
class BadController

{

public function __invoke()

{

$template = $_GET['template'];

setcookie('lastGeneration', time());



$this->archaicPdfLib->output($template);

exit;

}

}
use SymfonyComponentHttpFoundationCookie;

use SymfonyComponentHttpFoundationRequest;

use SymfonyComponentHttpFoundationStreamedResponse;



class BetterController

{

public function __invoke(Request $request)

{

$template = $request->query->get('template');



$response = new StreamedResponse(

function() use ($template) {

$this->archaicPdfLib->output($template);

}

);



$cookie = new Cookie('lastGeneration', time());

$response->headers->setCookie($cookie);



return $response;

}

}
Securing your Application
Avoid usage of
`access_control` in
security.yml
access_control:

- { path: ^/(nl|fr|en)/admin, roles: ROLE_ADMIN }
Regex 😕
class AdminController

{

/**

* @Route("/{_locale}/admin")

* @Security("has_role('ROLE_ADMIN')")

*/

public function __invoke(Request $request)

{

// if (!$this->authorizationChecker->isGranted('ROLE_ADMIN')) {

// throw new AccessDeniedHttpException();

// }



// ..

}

}
Use Bcrypt
# security.yml

security:

encoders:

KingFooPresentationSecurityUser:

algorithm: bcrypt

cost: 13
# services.yml

services:

password_encoder:

class: SymfonyComponentSecurity...BCryptPasswordEncoder

arguments: [13]



# security.yml

security:

encoders:

KingFooPresentationSecurityUser:

id: password_encoder
Create Your Own Symfony
Framework Edition
• Remove clutter
• Add/remove default dependencies
• Customize default configuration
• Fork symfony/symfony-standard
• Make modifications
• Modify composer.json package name
• Publish on GitHub and Packagist
{

"name": "kingfoo/symfony-project",

"autoload": {

"psr-4": { "": "src/" }

},

"require": {

"php": ">=5.5.0",

"symfony/symfony": "~2.6",

"doctrine/mongodb-odm": "~1.0@dev",

"doctrine/mongodb-odm-bundle": "~3.0@dev",

"symfony/monolog-bundle": "~2.4",

"sensio/distribution-bundle": "~3.0,>=3.0.12",

"sensio/framework-extra-bundle": "~3.0",

"incenteev/composer-parameter-handler": "~2.0"

},

"require-dev": {

"phpunit/phpunit": "~4.4"

}

}
Miscellaneous / Flamebait
• Bundles are for extending the container and
configuring (third-party) libraries that are
reusable across projects in the container.
• Try doing without bundles for project-
specific configuration.
• YAML is the preferred configuration file
format for application-specific config, XML
for configuration of bundles
Develop Your Own

Best Practices
• Do it as a team
• Write them down
• Be consistent
• Learn regex 😉
Next Symfony Training
• Getting Started with Symfony2
• 12-13th February 2015
• Aarschot
• Leave your name + email for a €50 reduction
Questions? 🙉

Más contenido relacionado

Destacado

CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationSamuel ROZE
 
Design pattern in Symfony2 - Nanos gigantium humeris insidentes
Design pattern in Symfony2 - Nanos gigantium humeris insidentesDesign pattern in Symfony2 - Nanos gigantium humeris insidentes
Design pattern in Symfony2 - Nanos gigantium humeris insidentesGiulio De Donato
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages webJean-Pierre Vincent
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsDavey Shafik
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phingRajat Pandit
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)Matthias Noback
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performanceafup Paris
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Marcello Duarte
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!tlrx
 
Writing infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLWriting infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLGabriele Bartolini
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Bruno Boucard
 
L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)Arnauld Loyer
 
Performance serveur et apache
Performance serveur et apachePerformance serveur et apache
Performance serveur et apacheafup Paris
 

Destacado (20)

CQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony applicationCQRS and Event Sourcing in a Symfony application
CQRS and Event Sourcing in a Symfony application
 
Design pattern in Symfony2 - Nanos gigantium humeris insidentes
Design pattern in Symfony2 - Nanos gigantium humeris insidentesDesign pattern in Symfony2 - Nanos gigantium humeris insidentes
Design pattern in Symfony2 - Nanos gigantium humeris insidentes
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Elastic Searching With PHP
Elastic Searching With PHPElastic Searching With PHP
Elastic Searching With PHP
 
Diving deep into twig
Diving deep into twigDiving deep into twig
Diving deep into twig
 
Techniques d'accélération des pages web
Techniques d'accélération des pages webTechniques d'accélération des pages web
Techniques d'accélération des pages web
 
Get Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP StreamsGet Soaked - An In Depth Look At PHP Streams
Get Soaked - An In Depth Look At PHP Streams
 
PHP5.5 is Here
PHP5.5 is HerePHP5.5 is Here
PHP5.5 is Here
 
Automation using-phing
Automation using-phingAutomation using-phing
Automation using-phing
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)The quest for global design principles (SymfonyLive Berlin 2015)
The quest for global design principles (SymfonyLive Berlin 2015)
 
Top tips my_sql_performance
Top tips my_sql_performanceTop tips my_sql_performance
Top tips my_sql_performance
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015Understanding Craftsmanship SwanseaCon2015
Understanding Craftsmanship SwanseaCon2015
 
Why elasticsearch rocks!
Why elasticsearch rocks!Why elasticsearch rocks!
Why elasticsearch rocks!
 
Writing infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQLWriting infinite scalability web applications with PHP and PostgreSQL
Writing infinite scalability web applications with PHP and PostgreSQL
 
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015Si le tdd est mort alors pratiquons une autopsie mix-it 2015
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
 
L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)L'ABC du BDD (Behavior Driven Development)
L'ABC du BDD (Behavior Driven Development)
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
 
Performance serveur et apache
Performance serveur et apachePerformance serveur et apache
Performance serveur et apache
 

Último

Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...Wes McKinney
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 

Último (20)

Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
The Future Roadmap for the Composable Data Stack - Wes McKinney - Data Counci...
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 

Symfony2 - The Unofficial "Best" Practices