por Geoffrey Bachelet
Alguma vez você já se perguntou o que acontece com uma requisição HTTP quando ela chega a uma aplicação symfony? Caso positivo, então você está no lugar certo. Este capítulo irá explicar em detalhes como o symfony processa cada requisição, a fim de criar e retornar a resposta. Claro que, apenas descrever o processo faltaria um pouco de diversão, por isso vamos dar uma olhada em algumas coisas interessantes que você pode fazer e onde você pode interagir neste processo.
A Inicialização
Tudo começa no controlador de sua aplicação. Digamos que você tenha um controlador frontend
com um ambiente dev
(um início clássico para qualquer projeto symfony)
. Neste caso, você terá um front controller localizado em
web/frontend_dev.php
.
O que acontece exatamente nesse arquivo? Em apenas algumas linhas de código, o symfony
obtêm a configuração da aplicação e cria uma instância do
sfContext
, que é responsável por despachar a requisição. A configuração da
aplicação é necessária para criar o objeto sfContext
, que é
o motor por trás do symfony e que depende da aplicação.
tip
O symfony já lhe concede um pouco de controle no que acontece aqui permitindo
passar um diretório raiz personalizado para sua aplicação como o quarto
argumento de ProjectConfiguration::getApplicationConfiguration()
, bem como
uma classe de contexto personalizada como o terceiro (e último) argumento de
sfContext::createInstance()
(mas lembre-se que ela tem de estender sfContext
).
Obter a configuração da aplicação é um passo muito importante. Primeiro,
o sfProjectConfiguration
é responsável por descobrir
a classe de configuração da aplicação, geralmente ${application}Configuration
, localizada em
apps/${application}/config/${application}Configuration.class.php
.
sfApplicationConfiguration
na verdade estende ProjectConfiguration
, significando
que qualquer método em ProjectConfiguration
pode ser compartilhado entre todas as aplicações.
Isto significa também que sfApplicationConfiguration
compartilha seu construtor
com ambos ProjectConfiguration
e sfProjectConfiguration
. Isto é
ótimo, já que grande parte da configuração do projeto é realizada dentro
do construtor de sfProjectConfiguration
. Primeiro, vários valores úteis são
calculados e armazenados, como, o diretório raiz do projeto e o diretório da biblioteca do
symfony. O sfProjectConfiguration
também cria um novo distribuidor de eventos (event dispatcher)
do tipo sfEventDispatcher
, a menos que um tenha sido passado como o quinto
argumento de ProjectConfiguration::getApplicationConfiguration()
no
front controller.
Só depois disso, você terá a oportunidade de interagir com o processo de configuração
sobrescrevendo o método setup()
do ProjectConfiguration
. Este
geralmente é o melhor local para ativar / desativar plugins (usando
sfProjectConfiguration::setPlugins()
,
sfProjectConfiguration::enablePlugins()
,
sfProjectConfiguration::disablePlugins()
ou
sfProjectConfiguration::enableAllPluginsExcept()
).
Em seguida, os plugins são carregados por sfProjectConfiguration::loadPlugins()
e o desenvolvedor tem uma chance de interagir com este processo através do
sfProjectConfiguration::setupPlugins()
que pode ser sobrescrito.
A inicialização de um plugin é bastante simples. Para cada plugin,
o symfony procura por uma classe ${plugin}Configuration
(por exemplo: sfGuardPluginConfiguration
)
e, se for encontrado, cria uma instância dela. Caso contrário, a classe sfPluginConfigurationGeneric
é
utilizada. Os seguintes métodos permitem modificar a configuração de um plugin:
${plugin}Configuration::configure()
, antes do carregamento automático (autoloading)${plugin}Configuration::initialize()
, após o carregamento automático
Em seguida, sfApplicationConfiguration
executa seu método configure()
,
que pode ser usado para personalizar a configuração de cada aplicação antes
que comece o processo de inicialização da configuração interna em
sfApplicationConfiguration::initConfiguration()
.
Esta parte do processo de configuração do symfony é responsável por muitas coisas
e existem diversos pontos de entrada caso você queira interagir nesse processo.
Por exemplo, você pode interagir com a configuração do carregamento automático (autoloader)
conectando-se ao evento autoload.filter_config
. Em seguida, vários
arquivos de configuração importantes são carregados, incluindo o settings.yml
e o
app.yml
. Finalmente, um último pedaço da configuração do plugin está disponível através do
arquivo config/config.php
de cada plugin ou do método da classe de configuração initialize()
.
Se o sf_check_lock
estiver ativado, o symfony irá buscar por um arquivo de bloqueio (
criado pela tarefa project:disable
, por exemplo). Se o bloqueio for encontrado,
os seguintes arquivos são verificados e o primeiro disponível é incluído, seguido
imediatamente pela finalização do script:
apps/${application}/config/unavailable.php
,config/unavailable.php
,web/errors/unavailable.php
,vendor/lib/symfony/lib/exception/data/unavailable.php
,
Por último, o desenvolvedor tem uma última chance de personalizar a inicialização da
aplicação através do método sfApplicationConfiguration::initialize()
.
Resumo da inicialização e configuração
- Recuperação da configuração da aplicação
ProjectConfiguration::setup()
(definir seus plugins aqui)- Plugins são carregados
${plugin}Configuration::configure()
${plugin}Configuration::initialize()
ProjectConfiguration::setupPlugins()
(configurar seus plugins aqui)${application}Configuration::configure()
autoload.filter_config
é notificado- Carregamento do
settings.yml
eapp.yml
${application}Configuration::initialize()
- Criação de uma instância
sfContext
sfContext
e Factories
Antes de mergulhar no processo de execução, vamos falar sobre uma parte vital do workflow do symfony: as factories.
No symfony, as factories são um conjunto de componentes ou classes que a sua
aplicação depende. Exemplos de factories são logger
, i18n
, etc.
Cada factory é configurada via factories.yml
, que é compilada por um
manipulador de configuração (config handler) (veremos sobre manipuladores de configuração mais tarde) e convertidos em código PHP
que realmente instancia os objetos factory (você pode ver este
código em seu cache no
arquivo cache/frontend/dev/config/config_factories.yml.php
).
note
O Carregamento da Factory acontece após a inicialização do sfContext
. Veja:
sfContext::initialize()
e sfContext::loadFactories()
para mais informações.
Neste ponto, você já pode personalizar uma grande parte do comportamento do symfony
apenas editando a configuração no factories.yml
. Você pode até substituir as classes
factory internas do symfony pelas suas próprias!
note
Se você estiver interessado em saber mais sobre as factories,
O Livro de Referência do symfony
bem como o arquivo
factories.yml
são recursos inestimáveis.
Se você olhou o arquivo config_factories.yml.php
gerado, você pode ter
notado que as factories são instanciadas em uma determinada ordem. Essa ordem é
importante, pois algumas factories são dependentes de outras (por exemplo, o
componente routing
necessita, obviamente, do request
para recuperar as informações que
ele precisa).
Vamos falar em maiores detalhes sobre o request
. Por padrão, a
classe sfWebRequest
representa o request
. Após a criação da instância,
sfWebRequest::initialize()
é chamado, que reúne informações relevantes como os parâmetros GET / POST
bem como o método HTTP. Você então tem a oportunidade de adicionar o seu próprio
processamento do pedido através do evento request.filter_parameters
.
Usando o evento request.filter_parameter
Imagine que o seu website disponibiliza uma API pública aos seus usuários. A API
está disponível através de HTTP, e cada usuário que deseja utilizá-la deve fornecer uma chave de API
válida através de um cabeçalho de solicitação (por exemplo X_API_KEY
) que será validada pela
sua aplicação. Isso pode ser facilmente obtido utilizando o
evento request.filter_parameter
:
class apiConfiguration extends sfApplicationConfiguration { public function configure() { // ... $this->dispatcher->connect('request.filter_parameters', array( $this, 'requestFilterParameters' )); } public function requestFilterParameters(sfEvent $event, $parameters) { $request = $event->getSubject(); $api_key = $request->getHttpHeader('X_API_KEY'); if (null === $api_key || false === $api_user = Doctrine_Core::getTable('ApiUser')->findOneByToken($api_key)) { throw new RuntimeException(sprintf('Invalid api key "%s"', $api_key)); } $request->setParameter('api_user', $api_user); return $parameters; } }
Você poderá então acessar seu usuário da API a partir do pedido (request):
public function executeFoobar(sfWebRequest $request) { $api_user = $request->getParameter('api_user'); }
Esta técnica pode ser usada, por exemplo, para validar chamadas à webservices.
note
O evento request.filter_parameters
vem com muitas informações sobre
o pedido (request), consulte o método
sfWebRequest::getRequestContext()
para obter mais informações.
A próxima factory muito importante é o roteamento (routing). A inicialização de roteamento é
bastante simples e consiste principalmente de coletar e configurar opções específicas
. Você pode, no entanto, interagir neste processo através do
evento routing.load_configuration
.
note
O evento routing.load_configuration
lhe fornece acesso a instância do
objeto de roteamento atual (por padrão,
sfPatternRouting
).
Você pode então manipular rotas registradas através de uma variedade de métodos.
Exemplo de uso do evento routing.load_configuration
Por exemplo, você pode facilmente adicionar uma rota:
public function setup() { // ... $this->dispatcher->connect('routing.load_configuration', array( $this, 'listenToRoutingLoadConfiguration' )); } public function listenToRoutingLoadConfiguration(sfEvent $event) { $routing = $event->getSubject(); if (!$routing->hasRouteName('my_route')) { $routing->prependRoute('my_route', new sfRoute( '/my_route', array('module' => 'default', 'action' => 'foo') )); } }
O processamento da URL ocorre logo após a inicialização, através do método
sfPatternRouting::parse()
.
Existem alguns métodos envolvidos, mas tudo o que você precisa saber
é que, quando chegamos ao final do método parse()
, a rota correta foi encontrada,
instanciada e vinculada aos parâmetros relevantes.
note
Para mais informações sobre roteamento, consulte o capítulo Roteamento Avançado
deste
livro.
Uma vez que todas as factories tenham sido carregadas e configuradas corretamente, o
evento context.load_factories
é disparado. Este evento é importante, pois
é o primeiro evento no framework onde o desenvolvedor tem acesso a todos
os objetos factory do núcleo do symfony (request, response, user, logging, database,
etc.).
Este é também o momento para se conectar a um outro evento muito útil:
template.filter_parameters
. Este evento ocorre sempre que um arquivo é processado pelo
sfPHPView
e permite ao desenvolvedor controlar os parâmetros atualmente passados ao template.
sfContext
aproveita este evento para adicionar alguns parâmetros úteis para cada
template (ou seja, $sf_context
, $sf_request
, $sf_params
, $sf_response
e $sf_user
).
Você pode se conectar ao evento template.filter_parameters
a fim de acrescentar
parâmetros globais personalizados para todos os templates.
Aproveitando o evento template.filter_parameters
Digamos que você decidiu que cada template utilizado deve ter acesso à um
determinado objeto, digamos, um objeto helper. Neste caso, você pode adicionar o seguinte
código no ProjectConfiguration
:
public function setup() { // ... $this->dispatcher->connect('template.filter_parameters', array( $this, 'templateFilterParameters' )); } public function templateFilterParameters(sfEvent $event, $parameters) { $parameters['my_helper_object'] = new MyHelperObject(); return $parameters; }
Agora, cada template tem acesso a uma instância do MyHelperObject
através da variável
$my_helper_object
.
Resumo do sfContext
- Inicialização do
sfContext
- Carregamento da Factory
- Eventos notificados:
- request.filter_parameters
- routing.load_configuration
- context.load_factories
- Parâmetros globais dos templates adicionados
Uma palavra sobre Manipuladores de Configuração (Config Handlers)
Os manipuladores de configuração são o coração do sistema de configuração do symfony. Um manipulador
de configuração é encarregado de entender o significado por trás de um arquivo de
configuração. Cada manipulador de configuração é simplesmente uma classe que é usada para traduzir um conjunto de
arquivos de configuração yaml em um bloco de código PHP que pode ser executado quando
necessário. Cada arquivo de configuração é atribuído à um manipulador de configuração específico através do
arquivo config_handlers.yml
.
Para deixar claro, o trabalho de um manipulador de configuração não é de fazer o processamento (parse) dos arquivos YAML
(isto é realizado pelo sfYaml
). Na verdade, o que os manipuladores de configuração fazem é criar um conjunto
de instruções PHP com base nas informações YAML e salvar as instruções
em um arquivo PHP, que poderá ser eficientemente incluído posteriormente. A versão compilada
de cada arquivo de configuração YAML pode ser encontrada no diretório cache.
O manipulador de configuração mais comumente utilizado é certamente o
sfDefineEnvironmentConfigHandler
,
que permite configurações específicas por ambiente.
Esse manipulador de configuração tem o cuidado de buscar apenas as definições de configuração
do ambiente atual.
Ainda não está convencido? Vamos explorar o
sfFactoryConfigHandler
.
Este manipulador de configuração é usado para compilar o factories.yml
, que é um dos
mais importantes arquivos de configuração do symfony. Esse manipulador de configuração é muito
especial, pois converte um arquivo de configuração YAML em código PHP que
finalmente instancia as factories (todos os componentes importantes que falamos
anterioremente). Este manipulador é muito mais avançado que os outros, não é?
Despachando e Executando o Pedido (Request)
Já falamos o suficiente sobre factories, vamos voltar a explicação do processo de despacho (dispatch) do pedido.
Após o sfContext
terminar a inicialização, o último passo é chamar o
método dispatch()
do controlador,
sfFrontWebController::dispatch()
.
O processo de despacho (dispatch) no symfony é muito simples. Na verdade,
o sfFrontWebController::dispatch()
simplesmente obtêm os nomes do módulo e da ação
dos parâmetros do pedido (request) e encaminha a aplicação através do
sfController::forward()
.
note
Neste ponto, se o roteamento não pôde processar qualquer nome de módulo ou ação
a partir da URL atual, um
sfError404Exception
é
originado, que irá encaminhar o pedido para o módulo de manipulação do erro 404 (ver
sf_error_404_module
e
sf_error_404_action
).
Note que você pode originar uma exceção em qualquer lugar na sua aplicação para
atingir esse efeito.
O método forward
é responsável por uma série de verificações prévias à execução
bem como preparar a configuração e dados para a ação a ser executada.
Primeiro, o controlador verifica a presença de um arquivo
generator.yml
para o módulo atual. Esta verificação é realizada primeiro (depois de limpeza básica no
nome do módulo e da ação), pois o arquivo de configuração generator.yml
(se
existir) é responsável por gerar a classe base das ações para o módulo
(através da seu
manipulador de configuração, sfGeneratorConfigHandler
).
Isso é necessário para a próxima etapa, que verifica se o módulo e a ação
existem. Isto é delegado ao controlador, através de
sfController::actionExists()
,
que, por sua vez, chama o método
sfController::controllerExists()
. Aqui, novamente, se o método actionExists()
falhar, um sfError404Exception
é gerado.
note
O
sfGeneratorConfigHandler
é
um manipulador de configuração especial que cuida de instanciar a classe correta do gerador (generator)
para o seu módulo e executá-lo. Para mais informações sobre manipuladores de configuração
, ver Uma palavra sobre manipuladores de configuração neste capítulo.
Além disso, para obter mais informações sobre o generator.yml
, veja o
capítulo 6 do Livro de Referência do symfony.
Não há muito que você pode fazer aqui além de sobrescrever o método
sfApplicationConfiguration::getControllerDirs()
na classe de configuração da aplicação. Esse método retorna um array
de diretórios onde os arquivos dos controladores residem, com um parâmetro adicional
para dizer ao symfony se ele deve verificar se os controladores em cada diretório estão
ativados através da opção de configuração sf_enabled_modules
no settings.yml
.
Por exemplo, getControllerDirs()
poderia parecer com o seguinte código:
/** * Controladores em /tmp/myControllers não precisam ser ativados *para serem detectados */ public function getControllerDirs($moduleName) { return array_merge(parent::getControllerDirs($moduleName), array( '/tmp/myControllers/'.$moduleName => false )); }
note
Se a ação não existe, um sfError404Exception
é acionado.
O próximo passo é recuperar uma instância do controlador que contém a ação.
Isso é tratado através do método
sfController::getAction()
que, como o actionExists()
, é uma fachada para o método
sfController::getController()
.
Finalmente, a instância do controlador é adicionada na action stack.
note
A action stack é uma pilha do estilo FIFO (First In First Out) que contém todas as
ações executadas durante o pedido. Cada item dentro da pilha é representado com
um objeto sfActionStackEntry
. Você sempre pode acessar a pilha com
sfContext::getInstance()->getActionStack()
ou
$this->getController()->getActionStack()
a partir de uma ação.
Após carregar mais um pouco de configuração, nós estaremos prontos para executar a nossa ação.
A configuração específica para o módulo ainda precisa ser carregada, ela pode ser
encontrada em dois locais distintos. Primeiro, o symfony procura o arquivo module.yml
(normalmente localizado em apps/frontend/modules/yourModule/config/module.yml
)
que, por ser um arquivo de configuração YAML, usa o cache de configuração. Além disso,
este arquivo de configuração pode declarar o módulo como interno, utilizando a
configuração mod_yourModule_is_internal
que fará o pedido falhar neste
ponto já que um módulo interno não pode ser chamado publicamente.
note
Módulos internos são utilizados para gerar conteúdo de e-mail (através do
getPresentationFor()
, por exemplo). Agora você deve usar outras técnicas,
tais como o processamento parcial ($this->renderPartial()
) em seu lugar.
Agora que o module.yml
foi carregado, é hora de verificar uma segunda vez se o
módulo atual está habilitado. Na verdade, você pode definir a configuração mod_$moduleName_enabled
para false
, se você deseja desativar o módulo neste momento.
note
Como mencionado, existem duas maneiras de ativar ou desativar um módulo.
A diferença é o que acontece quando o módulo é desativado. No primeiro caso,
quando a configuração sf_enabled_modules
é verificada, um módulo desabilitado fará
uma
sfConfigurationException
ser acionada. Deve ser usado quando deseja-se desativar um módulo de forma permanente. No
segundo caso, através da configuração mod_$moduleName_enabled
, um módulo desativado
irá fazer a aplicação redirecionar para o módulo desabilitado (ver as configurações
sf_module_disabled_module
e
sf_module_disabled_action
). Você deve usar este quando deseja desativar um módulo temporariamente.
A última oportunidade para configurar um módulo se encontra no arquivo config.php
(apps/frontend/modules/yourModule/config/config.php
) onde você pode adicionar
código PHP arbitrário que será executado no contexto do método
sfController::forward()
(ou seja, você tem acesso à instância sfController
através da variável $this
,
pois o código é literalmente executado dentro da classe sfController
).
Resumo do Processo de Despacho do Pedido
sfFrontWebController::dispatch()
é chamadosfController::forward()
é chamado- Verifica se há um 'generator.yml'
- Verifica se o módulo / ação existe
- Recupera uma lista dos diretórios dos controladores
- Obtêm uma instância da ação
- Carrega a configuração do módulo através do
module.yml
e/ouconfig.php
A Cadeia de Filtros
Agora que toda a configuração foi realizada, é hora de iniciar o trabalho real. Trabalho real, neste caso específico, é a execução da cadeia de filtros.
note
A cadeia de filtros do symfony implementa um padrão de design conhecido como chain of responsibility. É um padrão simples, mas poderoso, que permite ações encadeadas, onde cada parte da cadeia é capaz de decidir se deve ou não continuar a execução. Cada parte da cadeia também é capaz de executar tanto antes como depois do resto das partes da cadeia.
A configuração da cadeia de filtro é obtida a partir do arquivo
filters.yml
do módulo atual,
razão pela qual a instância da ação é necessária. Esta é sua chance de modificar o
conjunto de filtros executados pela cadeia. Basta lembrar que o filtro rendering
deve ser sempre o primeiro na lista (veremos porque mais tarde). A configuração padrão
dos filtros é a seguinte:
note
É altamente recomendável adicionar seus próprios filtros entre o filtro
security
e o cache
O Filtro security
Uma vez que o filtro rendering
espera por todos os outros filtros terminarem antes de fazer qualquer coisa, o
primeiro filtro que realmente executa é o filtro security
. Este filtro
garante que tudo está certo de acordo com o arquivo de configuração
security.yml
. Especificamente, o filtro encaminha um usuário não autenticado
ao módulo e ação login
e um usuário com credenciais insuficientes para
o módulo / ação secure
. Note que este filtro só é executado se
a segurança está habilitada para a determinada ação.
O Filtro cache
Em seguida vem o filtro cache
. Este filtro tira vantagem da sua capacidade de
evitar que filtros adicionais sejam executados. Na verdade, se o cache estiver ativado,
e se a página solicitada pelo usuário estiver no cache, a ação não é executada. Evidentemente, isso
irá funcionar apenas para uma página totalmente em cache, que não é o caso da maioria
das páginas.
Mas esse filtro tem um segundo pedaço de lógica que é executado após o
filtro execution
, e pouco antes do filtro rendering
. Este código é
responsável pela criação dos cabeçalhos HTTP de cache corretos, e de adicionar a página
no cache, se necessário, graças ao método
sfViewCacheManager::setPageCache()
.
O Filtro execution
O último filtro, mas não menos importante, é o filtro execution
que irá, finalmente, cuidar de
executar a sua lógica de negócio e a manipulação da visão associada.
Tudo começa quando o filtro verifica o cache para a ação atual.
Naturalmente, se temos algo no cache, a execução da ação atual é
ignorada e a visão Success
é então executada.
Se a ação não for encontrada no cache, então é hora de executar a
lógica do controlador preExecute()
, e, finalmente, executar a ação
. Isto é realizado pela instância da ação através da chamada do
sfActions::execute()
.
Este método não faz muito: ele simplesmente verifica se é possível executar a ação, e, então,
a executa. Voltando ao filtro, a lógica da ação postExecute()
é agora executada.
note
O valor de retorno de sua ação é muito importante, uma vez que irá determinar
que visão será executada. Por padrão, se nenhum valor de retorno é encontrado,
é assumido o sfView::SUCCESS
(que se traduz, você adivinhou, em Success
, como em
indexSuccess.php
).
Seguindo com o processo, agora está na hora da visão. O filtro verifica por dois valores de retorno especiais
que a sua ação pode ter retornado, sfView::HEADER_ONLY
e sfView::NONE
. Cada um faz exatamente o que o seu nome sugere: envia apenas cabeçalhos HTTP
(internamente tratado através do
sfWebResponse::setHeaderOnly()
)
e não exibe nenhuma página.
note
Os nomes internos disponíveis para a visão são: ALERT
, ERROR
, INPUT
, NONE
e SUCCESS
. Mas você pode
basicamente retornar o que quiser.
Uma vez que sabemos que vamos exibir alguma coisa, nós estamos prontos para entrar na etapa final do filtro: a execução de visão atual.
A primeira coisa que fazemos é recuperar um objeto sfView
através do método sfController::getView()
. Este objeto pode vir de
dois lugares diferentes. Primeiro, você poderia ter um objeto de exibição personalizado para esta ação específica
(assumindo que o módulo/ação atual é, vamos manter simples,
módulo/ação) actionSuccessView
ou module_actionSuccessView
em um arquivo
chamado apps/frontend/modules/module/view/actionSuccessView.class.php
.
Caso contrário, a classe definida na configuração mod_module_view_class
será usada. O valor padrão desta opção é sfPHPView
.
tip
Usando a sua própria classe de visão você tem a oportunidade de executar alguma lógica de visão específica,
através do método sfView::execute()
. Por exemplo, você pode instanciar a sua própria template engine.
Existem três modos de renderização possível para executar a visão:
sfView::RENDER_NONE
: equivalente asfView::NONE
, anula qualquer renderização de ser executada.sfView::RENDER_VAR
: preenche a apresentação da ação, que depois pode ser acessada através do métodosfActionStackEntry::getPresentation()
.sfView::RENDER_CLIENT
, o modo padrão, irá processar a visão e incluir o conteúdo da resposta.
note
Na verdade, o modo de processamento é utilizado apenas através do método
sfController::getPresentationFor()
que retorna o processamento para um
determinado módulo/ação.
O Filtro rendering
Estamos quase terminando agora, apenas um último passo. A cadeia de filtro quase
terminou a execução, mas você se lembra do filtro rendering
? Ele está aguardando
desde o início da cadeia, que todos os filtros concluam o seu trabalho para que ele possa
fazer o seu próprio. Ou seja, o filtro rendering
envia o conteúdo da resposta para o navegador, usando
sfWebResponse::send()
.
Resumo da execução da cadeida de filtros
- A cadeia de filtros é instanciada com a configuração do arquivo
filters.yml
- O filtro
security
verifica as autorizações e credenciais - O filtro
cache
manipula o cache para a página atual - O filtro
execution
executa a ação - O filtro
rendering
envia a resposta através dosfWebResponse
Resumo Global
- Obtenção da configuração da aplicação
- Criação de uma instância do
sfContext
- Inicialização do
sfContext
- Carregamento das Factories
- Eventos notificados:
request.filter_parameters
routing.load_configuration
context.load_factories
- Adicionados os parâmetros dos templates globais
sfFrontWebController::dispatch()
é chamadosfController::forward()
é chamado- Verifica se existe um
generator.yml
- Verifique se o módulo/ação existe
- Recupera uma lista de diretórios dos controladores
- Obtêm uma instância da ação
- Carrega a configuração do módulo através do
module.yml
e/ouconfig.php
- A cadeia de filtros é instanciada com a configuração do arquivo
filters.yml
- O filtro
security
verifica as autorizações e credenciais - O filtro
cache
manipula o cache para a página atual - O filtro
execution
executa a ação - O filtro
rendering
envia a resposta através dosfWebResponse
Reflexões finais
É isto! A requisição (request) foi tratada e agora estamos prontos para processar a próxima. Naturalmente, poderíamos escrever um livro inteiro sobre os processos internos do symfony, então este capítulo serve apenas como uma visão geral. Você é mais do que bem-vindo para explorar os códigos-fonte você mesmo - que é, e sempre será, a melhor maneira de aprender o funcionamento interno de qualquer framework ou biblioteca.
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.