Symfony Internals

Preview:

DESCRIPTION

A sneak peak at symfony's guts

Citation preview

Symfony Internals

diving into symfony's guts

About me

Zend Certified Engineer

Developer at Sensio Labs Vice-President of AFSY (French Symfony User Group) Co-author of "More with symfony"

As you can see, I love bermudas

http://twitter.com/ubermuda (mostly in french sorry)

More with symfony?

Yes, I wrote the Symfony Internals chapter

Don't worry if you read it already

There's new material here

Introduction

The symfony framework

Customizable

Flexible

Extensible

Customizable

Configuration files

settings.yml

factory.yml

Hierarchical configuration

Lots of ways to handle how the framework behaves

Flexible

The framework bows to your needs

Does not enforce an ORM

Does not enforce an user management system

Does not enforce a mailer

Etc.

Extensible

You can easily add capabilities

Using plugins

Hooking up on events

Overriding entire parts of the framework

How is it achieved?

Yes, how?

The bootstrap

Retrieves the application's configuration

Instanciates sfContext

Initiates dispatching

sfContext ?

Implements the Singleton design pattern

Has its pros and cons

Mostly, cons. (testability issues, etc)

Responsible for loading factories

(We'll talk about factories later)

The application configuration

frontendConfiguration

Extends ProjectConfiguration

Shares methods

Also, constructors

Most customization usually happens in ProjectConfiguration

The project configuration

Two very important steps:

Creates an event dispatcher

Loads plugins

The event dispatcher

sfEventDispatcher

Available as a separate component

http://components.symfony-project.org/event-dispatcher/

Implements the Observer pattern

Used throughout the whole framework

The event dispatcher

Available configuration events

autoload.filter_config

Allows to customize the autoloader configuration

More events later

Plugins

Used to extend the framework capabilities

Can contain entire modules

Or just hook on some event

Or provide a specific library

Etc.

Plugins

Have their own configuration file

used to be config/config.php

Now sfMyPluginConfiguration

extends sfPluginConfiguration

sfPluginConfigurationGeneric (if none was found)

Plugins

Find plugins

http://www.symfony-project.org/plugins/

http://www.symplist.net/

More than 900 plugins available!

Write your own plugins

It's easy

Simplifies code re-use

The configuration files

settings.yml

Holds the framework settings

And there are a lot of them

Actions, security strategies, I18N, debug bar, etc

http://www.symfony-project.org/reference/1_4/en/04-Settings

The configuration files

app.yml

Application specific configuration

You decide what's in there

Project wide app.yml (config/app.yml)

Environments

Environment specific configuration

Default envs are prod, dev and test

Configuration fine-tuning

Have a different database

Use a different mailing strategy

It's all handled by a ConfigHandler

Config Handler ?

Not very well known part of symfony

Parse and translate configuration files

Each configuration file has its own handler (kinda)

sfDefineEnvironmentConfigHandler

sfDatabaseConfigHandler

sfFactoryConfigHandler

Etc.

Back to sfContext

Instanciates factories

Components that drive your application

Logger, I18N, mailer, request, response, etc.

Configured through factories.yml

Has its own ConfigHandler too!

The factories configuration

Configured per-application

In your app's config/factory.yml

Gives you control over the whole framework

Handle by sfFactoryConfigHandler

sfFactoryConfigHandler

Translates your factory.yml into executable PHP

It's all in your cache

All config handlers use the config cache

Look in your cache/ directory for more information

The factories

You can override almost every components used by symfony

There is a reference for that, of course

http://www.symfony-project.org/reference/1_4/en/05-Factories

Here be events

Events notified during the factories loading

request.filter_parameters

routing.load_configuration

context.load_factories

context.load_factories

Earliest event where access to all factories is possible

Database access anyone?

The dispatch process

and more

The front controller

sfFrontWebController implements the Front Controller pattern

http://en.wikipedia.org/wiki/Front_Controller_pattern

Grabs module and action from the request

Issues a simple forward()

sfError404Exception

Thrown if no module/action was found

Will stop symfony's workflow

Forces a redirect to configured 404 handler

sf_error_404_module

sf_error_404_action

Can be thrown from anywhere in your application

The admin generator

Well-known symfony feature

generator.yml is consumed just there

Because we need the base action classes

By its own Config Handler, of course

http://www.symfony-project.org/reference/1_4/en/06-Admin-Generator

sfGeneratorConfigHandler

Instanciates a generator

Runs it

There is no step 3

Controllers dir

You can't do much here

Except override getControllersDir()

Gives you huge control over the controllers' location

You can add any directory to the list

Or just plain replace it

The action stack

A FIFO (First In First Out) stack

Holds every action that were or will be executed

Access it through sfContext's getActionStack()

Useful to interact with the action (getActionName(), etc)

Enabling and disabling modules

Two ways of doing this

Through sf_enabled_modules, in settings.yml

Through mod_MyModule_enabled, in module.yml

The difference is how disabled modules are handled

Enabling and disabling modules

Modules disabled through settings.yml

Will cause a sfConfigurationException to be thrown

Should be used for permanently disabled modules

Enabling and disabling modules

Modules disabled through module.yml

Will redirect to the "disabled module" module

sf_module_disabled_module

sf_module_disabled_action

Should be used for temporarily disabled modules

The filter chain

and yet another design pattern

The filter chain

Implements the Chain of Responsibility pattern

http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern

Configurable through filters.yml

It has a Config Handler too (sfFilterConfigHandler) :-)

Default filters configuration

Write your own filters

Extend sfFilter

Everything happens in the execute() method

Adding your own filters

It's just a matter of adding it to the filters.yml

Between security and cache, that is

Also, keep the rendering filter on top of the stack

Adding your own filters

The rendering filter

Does nothing right now

Remember, a filter can execute code

Before the rest of the stack

But also after

The security filter

First filter to actually execute code

Runs a bunch of security checks

Configured through security.yml

Checks for unauthenticated requests

Or requests with insufficient credentials

Unauthenticated requests

Redirected to the "login" page

sf_login_module

sf_login_action

Insufficient credentials

Uses the "secure" page

sf_secure_module

sf_secure_action

The cache filter

Has two bits of logic

Can prevent the rest of the chain to execute

Not very likely, though

Configures the HTTP cache headers

Fills in the cache before rendering

The execution filter

Finally! Let's get some real work done

Checks for cache

If no cache is found, executes the action

Calls the view script

The execution workflow

Quite straightforward

preExecute

execute (via sfActions' execute())

postExecute

A word on the return value

Determines what view gets executed

You already know SUCCESS

You most certainly also know NONE

You might also know ERROR

But there are more builtin types (ALERT and INPUT)

You can actually return anything you want

Handling the view

This is sfView's job

Two ways of getting a view object

Custom sfView object for a specific action

Class name from mod_module_view_class

Default is sfPHPView

sfPHPView

Loads core and standard helpers

Helper, Url, Assets, Tag and Escaping

sf_standard_helpers, in settings.yml

Executes a view script (pure PHP)

Decorates the result

Also handles some caching

sfPartialView

Responsible for rendering partials and components

Has its own logic

Handles cache for partials and components

Custom view examples

sfTwigView

Integrates the Twig template engine

http://github.com/henrikbjorn/sfTwigPlugin

sfTemplatingView

Integrates templating from the symfony components

http://www.symfony-project.org/plugins/sfTemplatingViewPlugin

The return of the rendering filter

Remember the rendering filter ?

Well it's back, and it wants to render.

Sends the response content through sfWebResponse's send method

That's all folks!

We're now ready to handle one more request

Hopefuly faster than we just did ;-)

Thank you

Hope you learned stuff!

Read the book for a more detailed (and boring) approach

http://www.symfony-project.org/more-with-symfony/1_4/en/10-Symfony-Internals

Questions?

speak slowly please

Recommended