Development

Documentation/pt_BR/book/1.0/02-Exploring-Symfony-s-Code (diff)

You must first sign up to be able to contribute.

Changes from Version 1 of Documentation/pt_BR/book/1.0/02-Exploring-Symfony-s-Code

Show
Ignore:
Author:
Edir.Dumaszak (IP: 189.26.4.62)
Timestamp:
06/17/07 10:06:30 (8 years ago)
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • Documentation/pt_BR/book/1.0/02-Exploring-Symfony-s-Code

    v0 v1  
     1{{{ 
     2#!WikiMarkdown  
     3 
     4Capítulo 2 - Explorando o Código 
     5================================ 
     6 
     7 
     8A primeira vista, o código por de traz de uma aplicação gerenciada pelo Symfony pode parecer assustador. Ele consiste de muitos diretórios e scripts, os arquivos são uma mistura de classes PHP, HTML, ou mesmo uma mistura dos dois. Você também verá referencias para classes que não serão encontradas em lugar algum dentro da pasta da aplicação, e que a profundidade dos  diretórios pode se estender até 6 níveis. Mas uma vez que você compreender a razão por detrás de toda esta complexidade, tudo parecerá tão natural para você que você não trocaria o Symfony por qualquer outras estruturas de aplicação. Este capitulo tenta diminuir esta sensação intimidante. 
     9 
     10O Padrão MVC 
     11------------ 
     12 
     13O Symfony é baseado no clássico padrão de design web conhecido como Arquitetura MVC (MVC Architecture), que consiste de três niveis: 
     14 
     15  * a modelagem (model) representa as informações com que a aplicação opera -- sua lógica de negócio. 
     16  * a visualização (view) renderiza a modelagem em uma página de internet pronta para interação com o usuário. 
     17  * o controlador (controller) responde às ações do usuário e invoca mudanças na modelagem ou visualização conforme necessário. 
     18 
     19A figura 2-1 ilustra o padrão MVC. 
     20 
     21A arquitetura MVC separa a lógica do negócio (model) e a apresentação (view) resultando em grande manutencibilidade. Por exemplo, se sua aplicação deve rodar em tanto padrões voltados à web browsers e dispositivos móveis, você apenas precisa de uma nova visualização; você pode manter o controlador e modelagem original. O controlador ajuda a esconder os detalhes do protocolo utilizado para a requisição (HTTP, console, mail, entre outros) da modelagem e da visualização. E a modelagem abstrai a lógica dos dados, o que faz com que a visualização e a ação independente de, por exemplo, do tipo de banco de dados utilizado pela aplicação. 
     22 
     23Figura 2-1 - O padrão MVC 
     24 
     25![O padrão MVC](http://www.symfony-project.com/images/book/trunk/F0201.png "O padrão MVC") 
     26 
     27### As camadas do MVC 
     28 
     29Para ajudar você a compreender as vantagens do MVC, vamos ver como se converte uma aplicação básica em PHP para uma aplicação que se utilize da arquitetura MVC. Uma lista mensagens para um aplicação de weblog será um exemplo perfeito. 
     30 
     31#### Programação Simples 
     32 
     33Em um simples arquivo PHP, exibir uma lista de entradas de uma base de dados pode parecer com o script apresentado na listagem 2-1. 
     34 
     35Listagem 2-1 - Um script simples 
     36 
     37    [php] 
     38    <?php 
     39 
     40    // Connecting, selecting database 
     41    $link = mysql_connect('localhost', 'myuser', 'mypassword'); 
     42    mysql_select_db('blog_db', $link); 
     43 
     44    // Performing SQL query 
     45    $result = mysql_query('SELECT date, title FROM post', $link); 
     46 
     47    ?> 
     48 
     49    <html> 
     50      <head> 
     51        <title>List of Posts</title> 
     52      </head> 
     53      <body> 
     54       <h1>List of Posts</h1> 
     55       <table> 
     56         <tr><th>Date</th><th>Title</th></tr> 
     57    <?php 
     58    // Printing results in HTML 
     59    while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) 
     60    { 
     61    echo "\t<tr>\n"; 
     62    printf("\t\t<td> %s </td>\n", $row['date']); 
     63    printf("\t\t<td> %s </td>\n", $row['title']); 
     64    echo "\t</tr>\n"; 
     65    } 
     66    ?> 
     67        </table> 
     68      </body> 
     69    </html> 
     70 
     71    <?php 
     72 
     73    // Closing connection 
     74    mysql_close($link); 
     75 
     76    ?> 
     77 
     78 
     79 
     80 
     81Isto é rápido para escrever, rápido para executar e impossível para manter. Os maiores problemas com este código são os seguintes: 
     82 
     83  * Não há verificação de erros (o que acontece se a base de dados falha?) 
     84  * HTML e PHP estão misturados, inclusive entralaçados entre si. 
     85  * O código está amarrado à uma base de dados mySQL. 
     86 
     87#### Isolando a apresentação 
     88 
     89As funções `echo` e `printf` na listagem 2-1 tornam o código difícil de ser lido. Modificar código HTML de modo a melhorar o layout é um problema com a atual sintaxe. Portanto o código pode ser dividido em duas partes. Primeiro, o código PHP puro, com todas as lógicas de negócio, e um script controlador, como exibido na lista 2-2. 
     90 
     91Listagem 2-2 - A parte Controladora, em `index.php` 
     92 
     93    [php] 
     94    <?php 
     95 
     96     // Connecting, selecting database 
     97     $link = mysql_connect('localhost', 'myuser', 'mypassword'); 
     98     mysql_select_db('blog_db', $link); 
     99 
     100     // Performing SQL query 
     101     $result = mysql_query('SELECT date, title FROM post', $link); 
     102 
     103     // Filling up the array for the view 
     104     $posts = array(); 
     105     while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) 
     106     { 
     107        $posts[] = $row; 
     108     } 
     109 
     110     // Closing connection 
     111     mysql_close($link); 
     112 
     113     // Requiring the view 
     114     require('view.php'); 
     115 
     116     ?> 
     117 
     118 
     119 
     120O código HTML, contendo uma modelagem com sintaxes PHP, é armazenado no script de visualização, como exibido na listagem 2-3; 
     121 
     122Listagem 2-3 - A parte de visualização, em `view.php` 
     123 
     124    [php] 
     125    <html> 
     126      <head> 
     127        <title>List of Posts</title> 
     128      </head> 
     129      <body> 
     130        <h1>List of Posts</h1> 
     131        <table> 
     132          <tr><th>Date</th><th>Title</th></tr> 
     133        <?php foreach ($posts as $post): ?> 
     134          <tr> 
     135            <td><?php echo $post['date'] ?></td> 
     136            <td><?php echo $post['title'] ?></td> 
     137          </tr> 
     138        <?php endforeach; ?> 
     139        </table> 
     140      </body> 
     141    </html> 
     142 
     143 
     144Uma boa maneira de determinar se uma visualização esta limpa o suficiente é se esta contem apenas o mínimo de código PHP, de modo que possa ser compreendida por um designer HTML com o mínimo de conhecimento em PHP. Os comandos mais comuns em visualizações são `echo, if/endif, foreach/endforeach` e só! Além disso, não deve haver nenhum código PHP invocando tags HTML. 
     145 
     146Toda a lógica é movida para o script controlador, que contem apenas puro código PHP, sem nenhum HTML. De fato, você deveria imaginar que um mesmo controlador poderia ser reutilizado para uma apresentação completamente diferente, como num arquivo PDF ou numa estrutura XML. 
     147 
     148 
     149#### Isolando a Manipulação de Dados 
     150 
     151Muitos dos scripts de controle são dedicados à manipulação de dados. Mas e se você precisar da lista de mensagens para um outro controlador, um que alimentasse um RSS feed com as mensagens do weblog por exemplo? E se você quiser manter todas os comandos de acesso da base de dados em um lugar, e evitar duplicação de código? E se você decidir mudar a modelagem dos dados de modo a mudar o nome da tabela `post` para `weblog_post`? E se você quiser mudar para uma base de dados PostgreSQL ao invés do MySQL? Para tornar isto possível, você precisa remover todos os códigos que manipulam dados do controlador e pô-los em outro script, chamado de modelo, como ilustrado na listagem 2-4. 
     152 
     153Listagem 2-4 - A parte de modelagem, em `model.php` 
     154    
     155   [php] 
     156    <?php 
     157 
     158    function getAllPosts() 
     159    { 
     160      // Connecting, selecting database 
     161      $link = mysql_connect('localhost', 'myuser', 'mypassword'); 
     162      mysql_select_db('blog_db', $link); 
     163 
     164      // Performing SQL query 
     165      $result = mysql_query('SELECT date, title FROM post', $link); 
     166 
     167      // Filling up the array 
     168      $posts = array(); 
     169      while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) 
     170      { 
     171         $posts[] = $row; 
     172      } 
     173 
     174      // Closing connection 
     175      mysql_close($link); 
     176 
     177      return $posts; 
     178    } 
     179 
     180    ?> 
     181 
     182 
     183A listagem 2-5 ilustra o controlador revisado. 
     184 
     185Listagem 2-5 - A parte de controle, revisada, em `index.php` 
     186 
     187    [php] 
     188    <?php 
     189 
     190    // Requiring the model 
     191    require_once('model.php'); 
     192 
     193    // Retrieving the list of posts 
     194    $posts = getAllPosts(); 
     195 
     196    // Requiring the view 
     197    require('view.php'); 
     198 
     199    ?> 
     200 
     201 
     202O controlador torna se fácil de ler. Sua única tarefa é pegar os dados da modelagem e passá-los para o visualizador. Em aplicações mais complexas, o controlador também trata as requisições, as seções de usuário, as autenticações, entre outros. O uso de nomes explícitos para as funções da modelagem tornam os comentários desnecessários no controlador. 
     203 
     204A modelagem é dedicada ao acesso aos dados, e pode ser organizado de acordo. Todos os parâmetros que não precisam da camada de dados (como parâmetros de requisição) devem ser enviados ao controlador e não acessados diretamente pela modelagem. As funções de modelagem podem ser facilmente reutilizadas em outros controladores. 
     205 
     206### Separando camadas além do MVC 
     207 
     208O princípio da arquitetura MVC é separar o código em três camadas, de acordo com suas naturezas. Códigos voltados aos dados são armazenados na modelagem, a interface na visualização, e a lógica da aplicação no controlador. 
     209 
     210Outros padrões adicionais de design pode tornar a experiência de desenvolver códigos ainda mais simples. As camadas de modelagem, da visualização, e do controlador podem ser subdivididas em mais outras camadas. 
     211 
     212 
     213#### Abstraindo a Base de Dados 
     214 
     215A camada de modelagem pode ser dividida em uma camada de acesso aos dados e uma camada de abstração da base de dados. Deste modo, funções de acesso aos dados não utilizarão comandos dependentes do tipo de base de dados utilizada, mas outras funções que executarão os comandos em seu lugar. se você trocar a base de dados mais tarde, apenas a camada de abstração precisará ser atualizada. 
     216 
     217Um exemplo de uma camada de acesso é exibida na listagem 2-6, seguido de um exemplo de uma camada de abstração na listagem 2-7. 
     218 
     219Listagem 2-6 - A camada de abstração da modelagem 
     220 
     221    [php] 
     222    <?php 
     223 
     224    function open_connection($host, $user, $password) 
     225    { 
     226      return mysql_connect($host, $user, $password); 
     227    } 
     228 
     229    function close_connection($link) 
     230    { 
     231      mysql_close($link); 
     232    } 
     233 
     234    function query_database($query, $database, $link) 
     235    { 
     236      mysql_select_db($database, $link); 
     237 
     238      return mysql_query($query, $link); 
     239    } 
     240 
     241    function fetch_results($result) 
     242    { 
     243      return mysql_fetch_array($result, MYSQL_ASSOC); 
     244    } 
     245 
     246 
     247Listagem 2-7 - A camada de acesso da modelagem 
     248 
     249    [php] 
     250    function getAllPosts() 
     251    { 
     252      // Connecting to database 
     253      $link = open_connection('localhost', 'myuser', 'mypassword'); 
     254 
     255      // Performing SQL query 
     256      $result = query_database('SELECT date, title FROM post', 'blog_db', $link); 
     257 
     258      // Filling up the array 
     259      $posts = array(); 
     260      while ($row = fetch_results($result)) 
     261      { 
     262         $posts[] = $row; 
     263      } 
     264 
     265      // Closing connection 
     266      close_connection($link); 
     267 
     268      return $posts; 
     269    } 
     270 
     271    ?> 
     272 
     273 
     274 
     275Como você pode ver, nenhuma função dependente de uma base de dados específica é encontrada na camada de acesso, tornando-a independente de base de dados. Além disto, as funções criadas na camada de abstração podem ser reutilizadas em muitos outras funções que acessam à base de dados. 
     276 
     277>**NOTE** 
     278>Os exemplos na listagem 2-6 e 2-7 podem não ser muitos satisfatórios, e há muito trabalho para se obter uma abstração completa de uma base de dados (abstrair o código SQL através de um construtor independente de base de dados, movendo todas as funções para uma classe, entre outros). Mas o objetivo deste livro não é mostrar como escrever todo o código, e você irá perceber no Capítulo 8 que o symfony faz nativamente muito bem toda a abstração. 
     279 
     280 
     281#### Elementos de Vizualização 
     282 
     283A camada de visualização pode também se beneficiar com alguma separação de códigos. Págins web de uma mesma aplicação geralmente contem elementos comuns entre si: os cabeçalhos, o layout gráfico, o rodapé, e o modo de navegar. Apenas o conteúdo da página muda. Por isto que a visualização é separada em uma camada de layout e uma camada de modelo. O layout geralmente é global para a aplicação, ou a um grupo de páginas. O modelo apenas da forma ao modo como as variáveis são disponibilizadas pelo controlador. Um pouco de lógica é necessária para fazer com que estes componentes trabalhem em conjunto, e a camada lógica da visualização irá servir para esta função. De acordo com estes principios, a camada de visualização exibida na Listagem 2-3 pode ser separada em três partes, como exibido nas Listagems 2-8, 2-9 e 2-10. 
     284 
     285 
     286Listagem 2-8 - A camada de modelo da visualização, em mytemplate.php 
     287 
     288    [php] 
     289    <h1>List of Posts</h1> 
     290    <table> 
     291    <tr><th>Date</th><th>Title</th></tr> 
     292    <?php foreach ($posts as $post): ?> 
     293      <tr> 
     294        <td><?php echo $post['date'] ?></td> 
     295        <td><?php echo $post['title'] ?></td> 
     296      </tr> 
     297    <?php endforeach; ?> 
     298    </table> 
     299 
     300 
     301Listagem 2-9 - A camada lógica da visualização 
     302 
     303 
     304    [php] 
     305    <?php 
     306 
     307    $title = 'List of Posts'; 
     308    $content = include('mytemplate.php'); 
     309 
     310    ?> 
     311 
     312 
     313Listagem 2-10 - A camada de layout da visualização 
     314 
     315    [php] 
     316    <html> 
     317      <head> 
     318        <title><?php echo $title ?></title> 
     319      </head> 
     320      <body> 
     321        <?php echo $content ?> 
     322      </body> 
     323    </html> 
     324 
     325 
     326#### Ações e o Controlador Principal 
     327 
     328O controlador não faz muito no exemplo anterior, mas em aplicações reais o controlador tem muito trabalho por fazer. Uma importante parte deste trabalho geralmente é comum à todos os controladores de uma aplicação. As comuns tarefas de tratar requisições, garantir a segurança da aplicação, carregar as configurações da aplicação, entre outras atividades semelhantes. É por isto que que o controlador geralmente é dividido em uma camada principal, que é única para toda a aplicação, e uma camada de ações, que contem apenas os códigos específicos de controle de uma única página. 
     329 
     330 
     331Uma das grandes vantagens do controlador principal é a de que ele oferece um modo único de acessar a aplicação inteira. Se você decidir fechar o acesso à aplicação, você precisa apenas editar o script do controlador principal. Em uma aplicação sem um controlador principal, cada controlador individual teria de ser desligado. 
     332 
     333 
     334#### Orientação à Objeto 
     335 
     336Todos os exemplos citados anteriormente utilizando uma programação procedural. A capacidade de programar orientado a objetos nas linguagens atuais fazem a tarefa de programar ainda mais fácil, uma vez que objetos pode encapsular código, herdar de outros, e permitir uma simples convenção de nomes. 
     337 
     338Implementando uma arquitetura MVC em uma linguagem não-orientada à objetos gera problemas com a nomenclatura de variáveis e duplicação de código, e o código resultante tende a ser difícil de ler. 
     339 
     340Orientação à objetos permite desenvolvedores à lidar com tais coisas como objetos de visualização, objetos de controle, e classes de modelagem, e transformar todas as funções dos exemplos anteriores em métodos. É um dos pontos altos das arquiteturas MVC. 
     341 
     342 
     343>**TIP** 
     344>Se você deseja aprender mais sobre padrões de design para aplicações web utilizando orientação à objetos, leia ''Patterns of Enterprise Application Architecture'', de Martin Fowler (Addison-Wesley, ISBN: 0-32112-742-0). Exemplos de códigos nos livros de Fowler são em java ou C#, mas ambas as linguagens são de fácil compreensão para um desenvolvedor PHP 
     345 
     346 
     347### Implementação MVC no Symfony 
     348 
     349Só um pouco! Para apenas uma página listando mensagens de um weblog, quantos componentes são necessários ? Como ilustrado na figura 2-2, nós temos as seguintes partes: 
     350 
     351  * Camada de Modelagen 
     352    * Abstração 
     353    * Acesso 
     354  * Camada de Visualização 
     355    * Lógica 
     356    * Modelo 
     357    * Layout 
     358  * Camada de Controle 
     359    * Controle Principal 
     360    * Ações 
     361 
     362Sete scripts -- um monte de arquivos para abrir e modificar cada vez que você criar uma nova página! Entretanto, Symfony torna as coisas mais fáceis. Tirando o melhor da arquitetura MVC, Symfony as implementa de modo a tornar o desenvolvimento de aplicações uma atividade rápida e simples. 
     363 
     364Primeiro, o controlador principal e o layout são comuns à todas as atividades da aplicação. Você pode ter diversos controladores e layouts, mas precisa apenas de um. O controlador principal é um componente com apenas lógica MVC pura, e você nunca irá precisar escrever um pois Symfony irá gerá-lo para você. 
     365 
     366A outra boa notícia é que as classes da camada de modelagem também são geradas automaticamente, baseados na sua estrutura de dados. Este é um trabalho para a biblioteca Propel, que fornece esqueletos de classes e geração de código. Se o Propel encontrar atributos Foreign Key ou campos de dados, ele irá criar acessos especiais e métodos diferenciados que tornarão a manipulação dos dados algo simples como café da manhã. E a abstração da base de dados é algo completamente invisível para você, porque é tratada por outro componente, chamado Creole. Portanto se você decidir trocar o tipo de base de dados a ser usada na sua aplicação, você não terá de re-escrever nenhuma linha de código. Você apenas precisará trocar um parâmetro de configuração. 
     367 
     368E a última coisa é que a camada de visualização pode ser facilmente traduzida com um simples arquivo de configuração, necessitando nenhuma programação adicional. 
     369 
     370Figura 2-2 - Diagrama de fluxo do Symfony  
     371 
     372![Diagrama de fluxo do Symfony ](http://www.symfony-project.com/images/book/trunk/F0202.png "Diagrama de fluxo do Symfony") 
     373 
     374Isso significa que a lista de mensagens descrita em nosso exemplo irá precisar apenas três arquivos para trabalhar com o Symfony, como exibido nas listas 2-11, 2-12 e 2-13. 
     375 
     376Listagem 2-11 - ''Ações'', na camada de controle, em `myproject/apps/myapp/modules/weblog/actions/actions.class.php` 
     377 
     378    [php] 
     379    <?php 
     380    class weblogActions extends sfActions 
     381    { 
     382      public function executeList() 
     383      { 
     384        $this->posts = PostPeer::doSelect(new Criteria()); 
     385      } 
     386    } 
     387 
     388    ?> 
     389 
     390Listagem 2-12 - ''Modelo'', na camada de visualização, em `myproject/apps/myapp/modules/weblog/templates/listSuccess.php` 
     391 
     392    [php] 
     393    <h1>List of Posts</h1> 
     394    <table> 
     395    <tr><th>Date</th><th>Title</th></tr> 
     396    <?php foreach ($posts as $post): ?> 
     397      <tr> 
     398        <td><?php echo $post->getDate() ?></td> 
     399        <td><?php echo $post->getTitle() ?></td> 
     400      </tr> 
     401    <?php endforeach; ?> 
     402    </table> 
     403 
     404Listagem 2-13 - ''Lógica'', em `myproject/apps/myapp/modules/weblog/config/view.yml` 
     405 
     406    listSuccess: 
     407      metas: { title: List of Posts } 
     408 
     409Você ainda terá de definir um layout, mas uma vez definido este poderá ser reutilizado por todas as demais janelas da aplicação. 
     410 
     411Listagem 2-14 - ''Layout'', em `myproject/apps/myapp/modules/weblog/layout/layout.php` 
     412 
     413    [php] 
     414    <html> 
     415      <head> 
     416        <?php echo include_title() ?> 
     417      </head> 
     418      <body> 
     419        <?php echo $sf_data->getRaw('sf_content') ?> 
     420      </body> 
     421    </html> 
     422 
     423 
     424E é apenas isso que você precisa. Este é o código necessário para exibir a mesma página do simples script exibido na Listagem 2-1. O resto (fazer todos os componentes trabalharem juntos) é gerenciado pelo Symfony. Se você contar as linhas, você verá que criar a lista utilizando a arquitetura MVC com o Symfony não requer muito mais tempo ou código que escrevendo um arquivo simples. Entretanto, ele lhe fornece grandes vantagens: organização clara do código, reusabilidade, flexibilidade, e muito mais. Como um bônus, você possui conformidade XHTML, capacidades de debug, facilidade de configuração, abstração da base de dados, redirecionamento inteligente de URLs, múltiplos ambientes, e muitas ferramentas de desenvolvimento a mais. 
     425 
     426### Classes Principais do Symfony 
     427 
     428A implementação do MVC no symfony utiliza diversas classes que você irá encontrar com alguma freqüência neste livro: 
     429 
     430  * `sfController` é a classe de controle. Ela decodifica as requisições e as entrega às Ações 
     431  * `sfRequest` armazena todas os elementos de requisição (parâmetros, cookies, cabeçalhos, entre outros) 
     432  * `sfResponde` contém os cabeçalhos de resposta e conteúdo. Este é o objeto que irá eventualmente ser convertido nos códigos HTML que serão enviados ao usuários. 
     433  * O contexto singleton (recebido de `sfContext::getInstance()`) armazena a referência para todos os objetos principais e configurações correntes, sendo acessível de qualquer lugar. 
     434 
     435Você aprenderá mais sobre estes objetos no Capítulo 6. 
     436 
     437Como você pode ver, todas as classes do Symfony utilizam o prefixo `sf`, assim como as variáveis principais nos modelos do Symfony. Isto deve ajudar a evitar colisão de nomes com suas classes e variáveis, e tornar as classes do framework faceis de serem reconhecidas. 
     438 
     439>**NOTE** 
     440>Entre os padrões de códigos utilizados pelo Symfony, o padrão utilizado para nomenclatura de variáveis e classes é o `UpperCamelCase`. Duas exceções existem: as classes do Symfony iniciam com sf, o que é minúsculo, e as variáveis encontrados nos modelos utilizam a sintaxe separada com underscore (_). 
     441 
     442 
     443Organização de Código 
     444--------------------- 
     445 
     446Agora que você conhece os diferentes componentes de uma aplicação Symfony, você provavelmente deve estar se perguntando como estes são organizados. Symfony organiza o código em uma estrutura de projeto e põe os arquivos deste em uma estrutura em árvore padrão. 
     447 
     448 
     449### Estrutura de Pojeto: Aplicações (Applications), Módulos (Modules) e Ações (Actions) 
     450 
     451No symfony, um projeto é um conjunto de serviços e operações disponíveis em um dado domínio, compartilhando o mesmo modelo de objetos. 
     452 
     453Dentro de um projeto, as operações são agrupadas logicamente em aplicações. As aplicações podem ser executadas independentemente das outras aplicações de um mesmo projeto. Em muitos casos, um projeto irá conter duas aplicações: uma para aplicações `front-office` e outras para aplicações `back-office`, compartilhando uma mesma base de dados. Mas você também pode ter projetos contendo diversos pequenos sites, cada um como uma aplicação diferente. Perceba que os hyperlinks entre aplicações devem estar todos em forma absoluta.  
     454 
     455cada aplicação é um conjunto de um ou mais módulos. Um módulo geralmente representa uma página ou um grupo de páginas com um propósito similar. Por exemplo você pode ter os módulos `Home`, `artigos`, `ajuda`, `carrinhoDeCompras`, `conta`, entre outros. 
     456 
     457Módulos guardam ações, que representam as várias ações que podem ser feitas em um módulo. Por exemplo, um módulo `carrinhoDeCompras` pode possuir ações do tipo `adicionar`, `exibir` e  `atualizar`. Geralmente, ações podem ser descritas com um verbo. Trabalhar com ações é quase o mesmo que trabalhar com páginas de uma aplicação web clássica, apesar de que duas mesmas ações acabem resultando na mesma página (adicionar um comentário num weblog irá exibir a janela de comentários com o novo comentário) 
     458 
     459>**TIP** 
     460>Se isto representa muitos níveis para um projeto inicial, é muito fácil agrupar todas as ações em um único módulo, de modo a manter a estrutura de arquivos simples. A medida que a aplicação se torna mais complexa, será necessário separar as ações em módulos separados. Como mencionado no Capítulo 1, reescrever código de modo a melhorar sua estrutura ou facilitar sua leitura (mas preservando seu comportamento) é chamado `refactoring`, e você irá fazer isso um monte quando aplicando os princípios RAD. 
     461 
     462 
     463A figura 2-3 ilustra uma amostra da organização de um projeto para um weblog, com uma estrutura projeto/aplicaçao/módulo/ação. Mas esteja ciente de que a real estrutura em arvore do projeto será diferente da ilustrada na figura. 
     464 
     465Figura 2-3 - Exemplo de organização de código 
     466 
     467![Exemplo de organização de código](http://www.symfony-project.com/images/book/trunk/F0203.png "Exemplo de organização de código") 
     468 
     469### Estrutura de Arquivos 
     470 
     471Todos os projetos geralmente compartilham o mesmo tipo de conteúdo, como os seguintes: 
     472 
     473  * uma base de dados, como MySQL ou PostgreSQL 
     474  * arquivos estáticos (HTML, imagens, códigos javascript, planilhas, entre outros) 
     475  * arquivos enviados pelos uusários e administradores do site 
     476  * classes e bilbliotecas PHP 
     477  * bibliotecas adicionais (scripts desenvolvidos por terceiros) 
     478  * arquivos de batch (scripts que serão executados por uma linha de comando) 
     479  * arquivos de log (registrados pelo aplicativo e/ou servidor) 
     480  * arquivos de configuração 
     481 
     482Symfony oferece uma estrutura padrão de arquivos em árvore para organizar todo este conteúdo de uma maneira lógica, consistente com as escolhas de arquitetura (padrões MVC e agrupamentos projeto/aplicação/módulo). Esta é a estrutura em árvores que será automaticamente criada quando inicializado um projeto, aplicação ou módulo. É claro, você pode personalizar isto completamente, para reorganizar os arquivos e diretórios de acordo com sua conveniência ou para atender às necessidades dos clientes. 
     483 
     484 
     485#### Raiz da Estrutura de Árvore 
     486 
     487Estes são os diretórios encontrados na raiz de um projeto symfony. A tabela 2-1 descreve o conteúdo destes diretórios. 
     488 
     489   apps/ 
     490     frontend/ 
     491     backend/ 
     492   batch/ 
     493   cache/ 
     494   config/ 
     495   data/ 
     496     sql/ 
     497   doc/ 
     498   lib/ 
     499     model/ 
     500   log/ 
     501   plugins/ 
     502   test/ 
     503     unit/ 
     504     functional/ 
     505   web/ 
     506     css/ 
     507     images/ 
     508     js/ 
     509     uploads/ 
     510 
     511Tabela 2-1 - Diretório Raiz 
     512 
     513Diretório | Descrição 
     514----------|---------- 
     515`apps/`   | Contém um diretório para cada aplicação do projeto (geralmente, `frontend` e `backend` para o Front Office e Back Office. 
     516`batch/`  | Contém os scripts PHP chamados por uma linha de comando ou despertador, de modo a executar processos em `batch`. 
     517`cache/`  | Contém as versões armazenadas de configuração, e (se você o ativar) a versão do armazenador de ações e modelos do projeto. O mecanismo armazenador (detalhado no Capítulo 12 usa estes arquivos para acelerar o tempo de respostas às requisições da web. Cada aplicação possuirá um subdiretório aqui, contendo arquivos PHP e HTML pré-processados. 
     518`config/` | Armazena as configurações geral do projeto. 
     519`data/`   | Aqui você pode armazenar arquivos de dados do projeto, como um esquema de uma base de dados, comandos SQL que criam tabelas, ou mesmo o arquivo de uma base de dados SQLite. 
     520`doc/`    | Armazena a documentação do projeto, incluindo os seus documentos e os gerados pelo PHPdoc. 
     521`lib/`    | Dedicado às bibliotecas e classes adicionais, geradas por terceiros. Aqui você pode adicionar códigos que devem ser compartilhados entre suas aplicações.  `model/` Subdiretório que armazena o modelo de objetos do projeto. (ver Capítulo 8). 
     522`log/`    | Armazena os arquivos de log gerados diretamente pelo symfony. Pode conter arquivos de log dos servidores web, ou logs das bases de dados de qualquer parte do projeto. Symfony cria um arquivo de log para cada aplicação e ambiente (arquivos de log são discutidos no Capítulo 16. 
     523`plugins/`| Armazena os plug-ins instalados na aplicação (plug-ins são discutidos no Capítulo 17). 
     524`test/`   | Contém testes de unidade e de função escritor em PHP e compatível com o framework de testes do Symfony (discutidos no Capítulo 15). Durante a configuração do projeto, symfony automaticamente adiciona alguns modelos com alguns testes básicos. 
     525`web/`    | A raiz para o servidor web. Os únicos arquivos acessíveis pela Internet se encontram neste diretório.  
     526 
     527 
     528#### Estrutura em Árvore da Aplicação 
     529 
     530A estrutura em árvore dos diretórios de todas as aplicações  é sempre a mesma. A tabela 2-2 descreve o conteúdo dos subdiretórios: 
     531 
     532   apps/ 
     533     [nome da aplicação]/ 
     534       config/ 
     535       i18n/ 
     536       lib/ 
     537       modules/ 
     538       templates/ 
     539         layout.php 
     540         error.php 
     541         error.txt 
     542 
     543Tabela 2-2 - Subdiretórios das Aplicações 
     544 
     545Diretório   | Descrição 
     546------------|---------- 
     547`config/`   | Armazena um grande conjunto de arquivos de configuração YAML. Aqui é onde se encontram a maior parte das configurações da aplicação, separado dos parâmetros padrões que podem ser encontrados no próprio framework. Repare que os parâmetros padrões podem ser sobrescritos aqui se necessário. Você irá aprender mais sobre como configurar uma aplicação no Capitulo 5. 
     548`i18n/`     | contêm os arquivos de internacionalização da aplicação -- geralmente arquivos de tradução da interface (Capítulo 13 lida com a internacionalização). Você pode ignorar este diretório se utilizar a base de dados para internacionalizar a aplicação. 
     549`lib/`      | Contém classes e bibliotecas específicas para esta aplicação. 
     550`modules/`  | armazena todos os módulos que contém as funcionalidades da aplicação. 
     551`templates/`| lista os modelos globais da aplicação -- os compartilhados por todos os módulos. Por default, ele contém o arquivo layout.php, que é o layout principal onde o módulo de modelos é insiderido. 
     552 
     553 
     554>**NOTE** 
     555>Os diretórios `i18n/`, `i18n` e  `modules/` se encontram vazios para cada nova aplicação. 
     556 
     557 
     558As classes de uma aplicação não são capazes de acessar métodos e atributos de outras aplicações de um mesmo projeto. Perceba também que os hyperlinks entre duas aplicações de um mesmo projetos devem se encontrar no modo absoluto. Você tem de manter isto em mente durante as etapas iniciais, onde você decide em quantas aplicações o projeto será dividido. 
     559 
     560 
     561#### Estrutura em Árvores dos Módulos 
     562 
     563Cada aplicação possui um ou mais módulos. Cada módulo possui seu próprio subdiretório na pasta `modules/`. 
     564 
     565Abaixo segue uma estrutura em árvore típica de um módulo. A tabela 2-3 descreve o conteúdo de cada diretório. 
     566 
     567   apps/ 
     568     [aplication name]/ 
     569       modules/ 
     570         [module name]/ 
     571           actions/ 
     572             actions.class.php 
     573           config/ 
     574           lib/ 
     575           templates/ 
     576             indexSuccess.php 
     577           validate/ 
     578 
     579Tabela 2-3 - Subdiretórios dos Módulos 
     580 
     581Diretório    | Descrição 
     582-------------|---------- 
     583`actions/`   | geralmente contém um único arquivo de classe chamado `actions.class.php`, no qual você pode armazenar todas as ações do modulo. Você também pode escrever diferentes ações para um módulo em arquivos separados. 
     584`config/`    | Pode conter arquivos de configuração personalizados com os parâmetros locais de cada módulo. 
     585`lib/`       | Armazena classes e bibliotecas específicas do módulo. 
     586`templates/` | Contém o modelo correspondente às ações do módulo. Um modelo padrão, chamado `indexSucess.php`, é criado durante a criação do módulo. 
     587`validate/`  | Dedicado à arquivos de configuração utilizados para validação de formulários (discutido no Capítulo 10). 
     588 
     589 
     590>**NOTE** 
     591>Os diretórios `config/`, `lib/` e `validate/` se encontram vazios para cada novo módulo. 
     592 
     593 
     594#### Estrutura em Árvore da Web 
     595 
     596Existem poucas particularidades quanto ao diretório web, que é o diretório com as arquivos acessíveis publicamente. Seguindo umas poucas convenções de nomenclatura, é possível criar comportamentos padrões e atalhos úteis para os modelos. Abaixo segue um exemplo da estrutura de um diretório web. Por convenção, os arquivos estáticos são distribuídos nos diretórios listados na tabela 2-4. 
     597 
     598  web/ 
     599    css/ 
     600    images/ 
     601    js/ 
     602    uploads/ 
     603 
     604Tabela 2-4 - Subdiretórios Web 
     605 
     606Diretório    | Descrição 
     607-------------|---------- 
     608`css/`       | Contém as planilhas de estilo com extensão `.css` 
     609`images/`    | Contém as imagens com extensão `.jpg`, `.png` ou `.gif`. 
     610`js/`        | Armazena os arquivos JavaScript com extensão `.js` 
     611`uploads/`   | Armazena os arquivos enviados pelos usuários. Apesar do diretório geralmente conter imagens, ele se distingue do diretório de imagens de modo que a sincronização dos servidores de desenvolvimento e produção não afetem as imagens enviadas. 
     612 
     613 
     614>**NOTE** 
     615>Mesmo sendo extremamente recomendado que você mantenha a estrutura em árvore padrão, é possível modificar esta de modo a antender suas necessidades, como permitir que um projeto rode em um servidor com diferentes regras para estruturas e convenções de código. Leia o Capítulo 19 para maiores informações sobre modificar a estrutura de arquivos. 
     616 
     617 
     618## Instrumentos Comuns 
     619 
     620Algumas técnicas são utilizadas repetidamente no symfony, e você as encontrará com certa freqüência neste livro e em seus próprios projetos. Isto inclui os parâmetros, constantes, e carregadores automáticos de classes. 
     621 
     622### Parâmetros 
     623 
     624Muitas das classes do symfony contém um parâmetro. É um modo conveniente de encapsular atributos com métodos de busca e atribuição. Por exemplo, a classe `sfResponse` armazena os parâmetros que você pode recuperar chamando o método `getParameterHolder()`. Cara parâmetro armazena informação do mesmo modo, como ilustrado na Listagem 2-15. 
     625 
     626Listagem 2-15 - Usando `sfResponse` 
     627 
     628    [php] 
     629    $response->getParameterHolder()->set('foo', 'bar'); 
     630    echo $response->getParameterHolder()->get('foo'); 
     631     => 'bar' 
     632 
     633 
     634Muitas das classes utilizando um parâmetro disponibilizam métodos  alternativos para encurtar o código necessário para operações `get/set`. Para isto se usa o objeto `sfResponse`, de modo que você consegue fazer o mesmo apresentando em Listagem 2-15 com o código da Listagem 2-16. 
     635 
     636Listagem 2-16 - Utilizando métodos alternativos do `SfResponse` de acesso à parametros 
     637 
     638    [php] 
     639    $response->setParameter('foo', 'bar'); 
     640    echo $response->getParameter('foo'); 
     641     => 'bar' 
     642 
     643 
     644A função `get` do parâmetro aceita valores default como segundo argumento. Isso oferece um útil mecanismo à prova de erros muito mais simples que o obtido com verificações condicionais. Veja a Listagem 2-17 para um exemplo. 
     645 
     646Listagem 2-17 - Utilizando o valor default do `get` de um parâmetro. 
     647 
     648    [php] 
     649    // The 'foobar' parameter is not defined, so the getter returns an empty value 
     650    echo $response->getParameter('foobar'); 
     651     => null 
     652 
     653    // A default value can be used by putting the getter in a condition 
     654    if ($response->hasParameter('foobar')) 
     655    { 
     656      echo $response->getParameter('foobar'); 
     657    } 
     658    else 
     659    { 
     660      echo 'default'; 
     661    } 
     662     => default 
     663 
     664    // But it is much faster to use the second getter argument for that 
     665    echo $response->getParameter('foobar', 'default'); 
     666     => default 
     667 
     668 
     669Parâmetros suportam inclusive `namespaces`. Se você especificar um terceiro argumento para uma função `set` ou `get`, este é utilizado como namespace, e o parêmetro será definido apenas dentro deste. Veja a Listagem 2-18 para um exemplo. 
     670 
     671Listagem 2-18 - Utilizando namespaces de um parâmetro `sfResponse` 
     672 
     673    [php] 
     674    $response->setParameter('foo', 'bar1'); 
     675    $response->setParameter('foo', 'bar2', 'my/name/space'); 
     676    echo $response->getParameter('foo'); 
     677     => 'bar1' 
     678    echo $response->getParameter('foo', null, 'my/name/space'); 
     679     => 'bar2' 
     680 
     681 
     682 
     683É claro, você pode adicionar um parâmetro às suas classes de modo a tirar vantagem de suas facilidades de sintaxe. A Listagem 2-19 mostra como definir uma classe com um parâmetro. 
     684 
     685Listagem 2-19 - Adicionando um parâmetro à uma classe 
     686 
     687    [php] 
     688    class MyClass 
     689    { 
     690      protected $parameter_holder = null; 
     691 
     692      public function initialize ($parameters = array()) 
     693      { 
     694        $this->parameter_holder = new sfParameterHolder(); 
     695        $this->parameter_holder->add($parameters); 
     696      } 
     697 
     698      public function getParameterHolder() 
     699      { 
     700        return $this->parameter_holder; 
     701      } 
     702    } 
     703 
     704 
     705### Constantes 
     706 
     707Surpreendentemente, você irá encontrar poucas constantes no Symfony. Isto porque constantes possuem um grave problema no PHP: uma vez definidas, você não pode modifica-las.  Portanto o Symfony utiliza seu próprio objeto de configuração, chamado `sfConfig`, que substitui constantes. Ele oferece métodos estáticos para acessar parâmetros de qualquer lugar. A Listagem 2-20 demonstra a utilização de métodos da classe sfConfig. 
     708 
     709Listagem 2-20 - Utilizando métodos da classe `sfConfig` ao invés de constantes. 
     710 
     711    [php] 
     712    // Instead of PHP constants, 
     713    define('SF_FOO', 'bar'); 
     714    echo SF_FOO; 
     715    // Symfony uses the sfConfig object 
     716    sfConfig::set('sf_foo', 'bar'); 
     717    echo sfConfig::get('sf_foo'); 
     718 
     719 
     720Os métodos de `sfConfig` suportam valores default, e você pode invocar o método `sfCondig::set()` diversas vezes para um mesmo parâmetro para alterar seu valor. O Capítulo 5 explica os métodos de `sfConfig` com mais detalhes. 
     721 
     722### Auto carregamento de classes 
     723 
     724Classicamente, quando você usa um método da classe ou cria um objeto em PHP, você necessita incluir primeiramente a definição da classe 
     725 
     726  [php] 
     727  include 'classes/MyClass.php'; 
     728  $myObject = new MyClass(); 
     729 
     730Mas em projetos grandes, com muitas classes e uma estrutura profunda de diretório, manter-se a par de todo arquivo de classe para incluir, demanda muito tempo. Fornecendo uma função `__autoload()` (ou uma função `spl_autoload_register()`), symfony torna os `includes` desnecessários, e você pode escrever diretamente: 
     731 
     732  [php] 
     733  $myObject = new MyClass(); 
     734 
     735Symfony procura então uma definição de `MyClass` em todos os arquivos que terminam com php em um dos diretórios do `lib/` do projeto. Se a definição da classe for encontrada, estará incluída automaticamente.  
     736         
     737Assim se você armazenar todas suas classes no diretório `lib/`, você não necessita incluir nenhuma classes. Isso porque os projetos symfony geralmente não contêm indicações `include` ou `require`.  
     738 
     739Para o melhor desempenho, o `autoloading` do symfony faz varre uma lista dos diretórios (definidos em um arquivo de configuração) durante o primeiro pedido. Regista então todas as classes que estes diretórios contêm e armazena a correspondência da classe/larquivo em um arquivo PHP como uma array associativa. Dessa maneira, os pedidos futuros não necessita fazer nenhuma a varredura no diretório. É por isso que você necessita limpar o cache todas as vezes que você adiciona ou move um arquivo de classe em seu projeto chamando o comando `symfony clear-cache command`. Você aprenderá mais sobre o cache no capítulo 12, e sobre a configuração `autoloading` no capítulo 19.  
     740 
     741Sumário 
     742------- 
     743 
     744Usar uma estrutura MVC força-o a dividir e organizar seu código de acordo com as convenções de estrutura. O código da apresentação para `view`, o código da manipulação de dados para `model`, e a lógica da manipulação do pedido vai para `controller`. Isto faz a aplicação do padrão MVC muito útil e completamente restringindo.  
     745         
     746Symfony é uma estrutura MVC escrita em PHP 5. Sua estrutura é projetada para ter o melhor do padrão MVC, mas com uma grande facilidade de utilização. Graças a sua versatilidade e configurabilidade, symfony é apropriado para todos os projetos  web.  
     747 
     748Agora que você compreende a teoria atrás do symfony, você está quase pronto para desenvolver sua primeira aplicação. Mas antes disso, você necessita uma instalação do symfony rodando e funcionando em seu servidor de desenvolvimento.  
     749 
     750}}}