Symfony - Guia Rápido
Uma estrutura da web PHP é uma coleção de classes que ajuda a desenvolver um aplicativo da web. Symfony é uma estrutura MVC de código aberto para o desenvolvimento rápido de aplicativos da web modernos. Symfony é um framework web full stack. Ele contém um conjunto de componentes PHP reutilizáveis. Você pode usar qualquer componente Symfony em aplicativos, independentemente do framework.
Symfony tem uma grande quantidade de funcionalidades e comunidade ativa. Ele tem uma configuração flexível usando YAML, XML ou anotações. Symfony se integra com uma biblioteca independente e unidade PHP. Symfony é inspirado principalmente nas estruturas de aplicativos da web Ruby on Rails, Django e Spring. Os componentes do Symfony estão sendo usados por muitos projetos de código aberto que incluem Composer, Drupal e phpBB.
O framework Symfony consiste em vários componentes, como o componente HttpFoundation que entende HTTP e oferece um bom objeto de solicitação e resposta usado por outros componentes. Outros são apenas componentes auxiliares, como o Validator, que ajuda a validar os dados. O componente do kernel é o coração do sistema. Kernel é basicamente a 'classe principal' que gerencia o ambiente e tem a responsabilidade de lidar com uma solicitação http.
A estrutura bem organizada do Symfony, o código limpo e as boas práticas de programação tornam o desenvolvimento web mais fácil. Symfony é muito flexível, usado para construir micro-sites e lidar com aplicativos corporativos com bilhões de conexões.
Symfony Framework - Recursos
Symfony é projetado para otimizar o desenvolvimento de aplicativos da web e aumenta em recursos a cada lançamento.
Alguns dos recursos mais importantes do Symfony Framework são os seguintes -
- Sistema baseado em Model-View-Controller
- Estrutura de PHP de alto desempenho
- Roteamento URI flexível
- Código reutilizável e mais fácil de manter
- Gerenciamento de sessão
- Erro ao registrar
- Classes de banco de dados com recursos completos e suporte para várias plataformas
- Oferece suporte a uma comunidade enorme e ativa
- Conjunto de componentes desacoplados e reutilizáveis
- Padronização e interoperabilidade de aplicativos
- Segurança contra falsificação de solicitação entre sites e outros ataques
- Mecanismo de template Twig
Symfony oferece muita flexibilidade para desenvolvedores. Possui excelentes recursos para depuração, legibilidade de código e desenvolvimento de programas extensíveis.
Symfony é um framework web full-stack; é uma ferramenta muito eficaz para criar aplicativos da web. Inúmeras empresas oferecem serviços Symfony aos clientes.
A seguir estão alguns dos benefícios que você obtém ao usar o Symfony Framework.
Microframework- Symfony pode ser usado para desenvolver uma funcionalidade específica. Você não precisa desenvolver ou instalar todo o framework.
Reduz a sobrecarga do tempo de desenvolvimento.
Motor de modelagem extremamente maduro e entrega rápida de conteúdo aos usuários.
Compatible and extensible - Os programadores podem estender facilmente todas as classes do framework.
Symfony Framework - Aplicativos
Os componentes do Symfony podem ser usados como parte de outros aplicativos, como Drupal, Laravel, phpBB, Behat, Doctrine e Joomla.
Drupal 8- Drupal é uma estrutura PHP de gerenciamento de conteúdo de código aberto. O Drupal 8 usa camadas centrais do Symfony e o estende para fornecer suporte para os módulos Drupal.
Thelia- Thelia é uma solução de e-commerce baseada em Symfony. Inicialmente, Thelia foi escrito em código PHP e MySQL, no entanto, estava demorando para produzir aplicativos mais rápidos. Para superar essa desvantagem, Thelia se integrou ao Symfony para desenvolver os aplicativos de forma personalizável.
Dailymotion- Dailymotion é um dos maiores sites de entretenimento de vídeo independente do mundo, com sede na França. Assim que decidiram migrar o framework de código aberto com uma grande comunidade, os desenvolvedores do Dailymotion decidiram usar os recursos dos componentes Symfony para sua flexibilidade.
Este capítulo explica como instalar o framework Symfony em sua máquina. A instalação do framework Symfony é muito simples e fácil. Você tem dois métodos para criar aplicativos no framework Symfony. O primeiro método é usar o instalador Symfony, um aplicativo para criar um projeto no framework Symfony. O segundo método é a instalação baseada no compositor. Vamos examinar cada um dos métodos, um por um, em detalhes nas seções a seguir.
Requisitos de sistema
Antes de passar para a instalação, você precisa dos seguintes requisitos de sistema.
- Servidor da Web (qualquer um dos seguintes)
- WAMP (Windows)
- LAMP (Linux)
- XAMP (multiplataforma)
- MAMP (Macintosh)
- Nginx (multiplataforma)
- Microsoft IIS (Windows)
- Servidor da web de desenvolvimento integrado em PHP (multiplataforma)
- Sistema operacional: plataforma cruzada
- Suporte do navegador: IE (Internet Explorer 8+), Firefox, Google Chrome, Safari, Opera
- Compatibilidade com PHP: PHP 5.4 ou posterior. Para obter o máximo benefício, use a versão mais recente.
Usaremos o servidor de desenvolvimento da web embutido em PHP para este tutorial.
Symfony Installer
Symfony Installer é usado para criar aplicativos da web no framework Symfony. Agora, vamos configurar o instalador Symfony usando o seguinte comando.
$ sudo mkdir -p /usr/local/bin $ sudo curl -LsS https://symfony.com/installer -o /usr/local/bin/symfony
$ sudo chmod a+x /usr/local/bin/symfony
Agora, você instalou o instalador Symfony em sua máquina.
Crie seu primeiro aplicativo Symfony
A seguinte sintaxe é usada para criar um aplicativo Symfony na versão mais recente.
Sintaxe
symfony new app_name
Aqui, app_name é o seu novo nome de aplicativo. Você pode especificar qualquer nome que desejar.
Exemplo
symfony new HelloWorld
Depois de executar o comando acima, você verá a seguinte resposta.
Downloading Symfony...
0 B/5.5 MiB ░░░░░░░░░░░
……………………………………………………………
……………………………………………………………
Preparing project...
✔ Symfony 3.2.7 was successfully installed. Now you can:
* Change your current directory to /Users/../workspace/firstapp
* Configure your application in app/config/parameters.yml file.
* Run your application:
1. Execute the php bin/console server:run command.
2. Browse to the http://localhost:8000 URL.
* Read the documentation at http://symfony.com/doc
Este comando cria um novo diretório chamado “firstapp /“ que contém um projeto vazio da última versão do framework Symfony.
Instale a versão específica
Se você precisar instalar uma versão específica do Symfony, use o seguinte comando.
symfony new app_name 2.8
symfony new app_name 3.1
Instalação baseada no Composer
Você pode criar aplicativos Symfony usando o Composer. Com sorte, você instalou o composer em sua máquina. Se o compositor não estiver instalado, baixe e instale-o.
O seguinte comando é usado para criar um projeto usando o composer.
$ composer create-project symfony/framework-standard-edition app_name
Se você precisa especificar uma versão específica, você pode especificar no comando acima.
Executando o aplicativo
Mova para o diretório do projeto e execute o aplicativo usando o seguinte comando.
cd HelloWorld
php bin/console server:run
Depois de executar o comando acima, abra seu navegador e solicite o url http://localhost:8000/. Ele produz o seguinte resultado.
Resultado
Symfony é basicamente uma coleção de componentes e pacotes de alta qualidade. Os componentes são conjuntos de classes que fornecem uma única funcionalidade central. Por exemplo,Cache componentfornece funcionalidade de cache, que pode ser adicionada a qualquer aplicativo. Os componentes são blocos de construção de um aplicativo Symfony. Symfony tem mais de 30 componentes de alta qualidade, que são usados em muitos frameworks PHP, como Laravel, Silex, etc.
Os pacotes são semelhantes ao plug-in, mas fáceis de criar e usar. Na verdade, um aplicativo Symfony é um pacote composto de outros pacotes. Um único pacote pode usar qualquer número de componentes Symfony e também componentes de terceiros para fornecer recursos como Webframework, acesso a banco de dados, etc. Symfony core web-framework é um pacote chamado FrameworkBundle e há um pacote chamado FrameworkExtraBundle, que oferece mais sofisticação opções para escrever um aplicativo da web.
O relacionamento entre os componentes, pacotes e aplicativos Symfony é especificado no diagrama a seguir.
Web Framework
Symfony é projetado principalmente para escrever aplicativos da web de alta qualidade com relativa facilidade. Ele fornece várias opções para escrever diferentes tipos de aplicativos da web, desde um simples site até serviços avançados baseados em REST. Symfony fornece estrutura web como pacotes separados. Os pacotes comuns usados na estrutura da web Symfony são os seguintes -
- FrameworkBundle
- FrameworkExtraBundle
- DoctrineBundle
O framework web Symfony é baseado na arquitetura Model-View-Controller (MVC). Model representa a estrutura de nossas entidades empresariais. View mostra os modelos ao usuário da melhor maneira possível dependendo da situação. Controller lida com todas as solicitações do usuário, faz o trabalho real interagindo com o Modelo e, finalmente, fornece à Visualização os dados necessários para mostrá-la ao usuário.
A estrutura da Web Symfony fornece todos os recursos de alto nível necessários para um aplicativo empresarial. A seguir está um fluxo de trabalho simples do aplicativo da web Symfony.
O fluxo de trabalho consiste nas etapas a seguir.
Step 1 - O usuário envia uma solicitação ao aplicativo por meio do navegador, digamos http://www.symfonyexample.com/index.
Step 2 - O navegador enviará uma solicitação ao servidor da web, digamos servidor da web Apache.
Step 3 - O servidor web encaminhará a solicitação para o PHP subjacente, que por sua vez a enviará para o framework web Symfony.
Step 4- HttpKernel é o componente principal do framework web Symfony. HttpKernel resolve o controlador da solicitação fornecida usando o componente de roteamento e encaminha a solicitação ao controlador de destino.
Step 5 - Toda a lógica de negócios ocorre no controlador de destino.
Step 6 - O controlador irá interagir com o Model, que por sua vez interage com o Datasource através do Doctrine ORM.
Step 7 - Depois que o controlador conclui o processo, ele gera a própria resposta ou por meio do View Engine e a envia de volta ao servidor da web.
Step 8 - Por fim, a resposta será enviada ao navegador solicitado pelo servidor web.
Conforme discutido anteriormente, os componentes do Symfony são uma biblioteca PHP autônoma que fornece um recurso específico, que pode ser usado em qualquer aplicativo PHP. Novos componentes úteis estão sendo introduzidos em cada versão do Symfony. Atualmente, existem mais de 30 componentes de alta qualidade no framework Symfony. Vamos aprender sobre o uso de componentes Symfony neste capítulo.
Instalando um componente Symfony
Os componentes do Symfony podem ser instalados facilmente usando o comando composer. O seguinte comando genérico pode ser usado para instalar qualquer componente Symfony.
cd /path/to/project/dir
composer require symfony/<component_name>
Vamos criar um aplicativo php simples e tentar instalar Filesystem componente.
Step 1 - Crie uma pasta para o aplicativo, filesystem-example
cd /path/to/dev/folder
mdkir filesystem-example
cd filesystem-example
Step 2 - Instale o componente Filesystem usando o seguinte comando.
composer require symfony/filesystem
Step 3 - Crie um arquivo main.php e digite o seguinte código.
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Filesystem\Exception\IOExceptionInterface;
$fs = new Filesystem(); try { $fs->mkdir('./sample-dir');
$fs->touch('./sample-dir/text.txt'); } catch (IOExceptionInterface $e) {
echo $e;
}
?>
A primeira linha é muito importante, pois carrega todas as classes necessárias de todos os componentes instalados usando o comando Composer. As próximas linhas usam a classe Filesystem.
Step 4 - Execute o aplicativo usando o seguinte comando e ele criará uma nova pasta sample-dir e um arquivo test.txt sob ele.
php main.php
Detalhes dos componentes Symfony
Symfony fornece componentes que variam de recursos simples, como sistema de arquivos, a recursos avançados, como eventos, tecnologia de contêiner e injeção de dependência. Informe-nos sobre todos os componentes, um por um, nas seções a seguir.
Sistema de arquivo
O componente do sistema de arquivos fornece um comando básico do sistema relacionado a arquivos e diretórios, como criação de arquivos, criação de pastas, existência de arquivos, etc. O componente do sistema de arquivos pode ser instalado usando o seguinte comando.
composer require symfony/filesystem
Localizador
O componente Finder fornece classes fluentes para localizar arquivos e diretórios em um caminho especificado. Ele fornece uma maneira fácil de iterar os arquivos em um caminho. O componente Finder pode ser instalado usando o seguinte comando.
composer require symfony/finder
Console
O componente Console oferece várias opções para criar comandos facilmente, que podem ser executados em um terminal. Symfony usa oCommand componente extensivamente para fornecer várias funcionalidades, como a criação de um novo aplicativo, a criação de um pacote, etc. Até mesmo o PHP construído no servidor web pode ser invocado usando o comando Symfony, php bin/console server:runcomo visto na seção de instalação. oConsole componente pode ser instalado usando o seguinte comando.
composer require symfony/console
Vamos criar um aplicativo simples e criar um comando, HelloCommand usando o Console componente e invocá-lo.
Step 1 - Crie um projeto usando o seguinte comando.
cd /path/to/project
composer require symfony/console
Step 2 - Crie um arquivo main.php e inclua o código a seguir.
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Console\Application;
$app = new Application();
$app->run();
?>
Application classe configura a funcionalidade necessária de um aplicativo de console básico.
Step 3 - Execute o aplicativo, php main.php, que produzirá o seguinte resultado.
Console Tool
Usage:
command [options] [arguments]
Options:
-h, --help Display this help message
-q, --quiet Do not output any message
-V, --version Display this application version
--ansi Force ANSI output
--no-ansi Disable ANSI output
-n, --no-interaction Do not ask any interactive question
-v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output,
2 for more verbose output and 3 for debug
Available commands:
help Displays help for a command
list Lists commands
Step 4 - Crie uma classe chamada HelloCommand estendendo Command classe no main.php em si.
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
class HelloCommand extends Command {
}
O aplicativo usa as seguintes quatro classes disponíveis em Command componente.
Command - Usado para criar um novo comando
InputInterface - Usado para definir as entradas do usuário
InputArgument - Usado para obter entradas do usuário
OutputInterface - Usado para imprimir a saída para o console
step 5 - Crie uma função configure() e defina o nome, a descrição e o texto de ajuda.
protected function configure() {
$this
->setName('app:hello')
->setDescription('Sample command, hello')
->setHelp('This command is a sample command')
}
step 6 - Crie um argumento de entrada, user para o comando e definido como obrigatório.
protected function configure() {
$this
->setName('app:hello')
->setDescription('Sample command, hello')
->setHelp('This command is a sample command')
->addArgument('name', InputArgument::REQUIRED, 'name of the user');
}
step 7 - Crie uma função execute() com dois argumentos InputArgument e OutputArgument.
protected function execute(InputInterface $input, OutputInterface $output) {
}
step 8 - Use InputArgument para obter os detalhes do usuário inseridos pelo usuário e imprimi-los no console usando OutputArgument.
protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument('name'); $output->writeln('Hello, ' . $name);
}
step 9 - Cadastre o HelloCommand no aplicativo usando o add método de Application classe.
$app->add(new HelloCommand());
O aplicativo completo é o seguinte.
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Input\InputArgument;
class HelloCommand extends Command {
protected function configure() {
$this ->setName('app:hello') ->setDescription('Sample command, hello') ->setHelp('This command is a sample command') ->addArgument('name', InputArgument::REQUIRED, 'name of the user'); } protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument('name'); $output->writeln('Hello, ' . $name); } $app = new Application();
$app->add(new HelloCommand()); $app->run();
}
?>
Step 10 - Agora, execute o aplicativo usando o seguinte comando e o resultado será Olá, Jon como o esperado.
php main.php app:hello Jon
Symfony vem com um binário pré-construído chamado console no diretório bin de qualquer aplicativo da web Symfony, que pode ser usado para invocar os comandos em um aplicativo.
Processo
O componente de processo fornece opções para executar qualquer comando do sistema em um subprocesso, de maneira segura e eficiente. O componente do processo pode ser instalado usando o seguinte comando.
composer require symfony/process
ClassLoader
O componente ClassLoader fornece implementação para ambos PSR-0 e PSR-4padrão do carregador de classes. Ele pode ser usado para carregar automaticamente as classes. Ele será depreciado em um futuro próximo. O carregador de classes baseado no Composer é preferível a este componente. O componente ClassLoader pode ser instalado usando o seguinte comando.
composer require symfony/class-loader
PropertyAccess
O componente PropertyAccess fornece várias opções para ler e gravar um objeto e detalhes do array usando a notação de string. Por exemplo, um arrayProduct com chave price pode ser acessado dinamicamente usando [price] corda.
$product = array( 'name' => 'Cake' 'price' => 10 ); var priceObj = $propertyAccesserObj->getValue($product, '[price]');
O componente PropertyAccess pode ser instalado usando o seguinte comando.
composer require symfony/property-access
PropertyInfo
O componente PropertyInfo é semelhante ao componente PropertyAccess, mas funciona apenas com objetos PHP e oferece muito mais funcionalidade.
class Product {
private $name = 'Cake';
private $price = 10; public function getName() { return $this->name;
}
public function getPrice() {
return $this->price; } } $class = Product::class;
$properties = $propertyInfoObj->getProperties($class);
/*
Example Result
--------------
array(2) {
[0] => string(4) "name"
[1] => string(5) "price"
}
*/
O componente PropertyInfo pode ser instalado usando o seguinte comando.
composer require symfony/property-info
EventDispatcher
O componente EventDispatcher fornece uma programação baseada em eventos em PHP. Ele permite que os objetos se comuniquem entre si despachando eventos e ouvindo-os. Aprenderemos como criar eventos e ouvi-los no capítulo Eventos e Listener de eventos.
O componente EventDispatcher pode ser instalado usando o seguinte comando.
composer require symfony/event-dispatcher
Injeção de dependência
O componente DependencyInjection fornece um mecanismo fácil e eficiente para criar um objeto com sua dependência. Quando um projeto cresce, ele apresenta muitas classes com dependência profunda, que precisam ser tratadas corretamente. Caso contrário, o projeto falha. DependencyInjection fornece um contêiner simples e robusto para lidar com a dependência. Aprenderemos sobre os containers e o conceito de injeção de dependência no capítulo Service Container.
O componente DependencyInjection pode ser instalado usando o seguinte comando.
composer require symfony/dependency-injection
Serializador
O componente Serializer fornece uma opção para converter um objeto PHP em um formato específico, como XML, JSON, Binary, etc., e então permite convertê-lo de volta em um objeto original sem qualquer perda de dados.
O componente serializador pode ser instalado usando o seguinte comando.
composer require symfony/serializer
Config
O componente Config fornece opções para carregar, analisar, ler e validar configurações do tipo XML, YAML, PHP e ini. Ele fornece várias opções para carregar detalhes de configuração do banco de dados também. Este é um dos componentes importantes úteis na configuração de aplicativos da web de maneira clara e concisa. O componente de configuração pode ser instalado usando o seguinte comando.
composer require symfony/config
ExpressionLanguage
O componente ExpessionLanguage fornece um mecanismo de expressão completo. As expressões são de uma linha com o objetivo de retornar um valor. O mecanismo de expressão permite compilar, analisar e obter facilmente o valor de uma expressão. Ele permite que uma ou mais expressões sejam usadas em um ambiente de configuração (arquivo) por um programador não PHP, digamos um administrador de sistema. O componente ExpressionLanguage pode ser instalado usando o seguinte comando.
composer require symfony/expression-language
OptionsResolver
O componente OptionsResolver fornece uma maneira de validar o sistema de opções usado em nosso sistema. Por exemplo, a configuração do banco de dados é colocada em uma matriz, dboption com host, nome de usuário, senha, etc., como chaves. Você precisa validar as entradas antes de usá-lo para se conectar a um banco de dados. OptionsResolver simplifica essa tarefa fornecendo uma classe simples OptionsResolver e um resolvedor de método, que resolve a configuração do banco de dados e, se houver algum problema de validação, ele o relatará.
$options = array(
'host' => '<db_host>',
'username' => '<db_user>',
'password' => '<db_password>',
);
$resolver = new OptionsResolver(); $resolver->setDefaults(array(
'host' => '<default_db_host>',
'username' => '<default_db_user>',
'password' => '<default_db_password>',
));
$resolved_options = $resolver->resolve($options);
O componente OptionsResolver pode ser instalado usando o seguinte comando.
composer require symfony/options-resolver
Dotenv
O componente Dotenv oferece várias opções para analisar arquivos .env e a variável definida neles para serem acessíveis via getenv(), $_ENV, ou $_SERVER. O componente Dotenv pode ser instalado usando o seguinte comando.
composer require symfony/dotenv
Cache
O componente de cache fornece uma extensão PSR-6implementação. Ele pode ser usado para adicionar funcionalidade de cache ao nosso aplicativo da web. Uma vez que seguePSR-6, é fácil de começar e pode ser facilmente usado no lugar de outro componente de cache baseado em PSR-6. O componente de cache pode ser instalado usando o seguinte comando.
composer require symfony/cache
Internacional
O componente Intl é a biblioteca de substituição para a extensão C Intl. O componente internacional pode ser instalado usando o seguinte comando.
composer require symfony/intl
Tradução
O componente de tradução oferece várias opções para internacionalizar nosso aplicativo. Normalmente, os detalhes da tradução de diferentes idiomas serão armazenados em um arquivo, um arquivo por idioma, e será carregado dinamicamente durante o tempo de execução do aplicativo. Existem diferentes formatos para escrever um arquivo de tradução. O componente de tradução oferece várias opções para carregar qualquer tipo de formato, como arquivo PHP simples, CSV, ini, Json, Yaml, arquivo de recursos ICU, etc. O componente de tradução pode ser instalado usando o seguinte comando.
composer require symfony/translation
Fluxo de Trabalho
O componente de fluxo de trabalho fornece ferramentas avançadas para processar uma máquina de estado finito. Ao fornecer essa funcionalidade de uma maneira simples e orientada a objetos, o componente Workflow permite a programação avançada em PHP com relativa facilidade. Aprenderemos sobre isso em detalhes no capítulo Conceito Avançado.
O componente de fluxo de trabalho pode ser instalado usando o seguinte comando.
composer require symfony/workflow
Yaml
O componente Yaml fornece uma opção que analisa o formato de arquivo YAML e o converte em matrizes PHP. Ele também é capaz de escrever arquivos YAML a partir de um array php simples. O componente Yaml pode ser instalado usando o seguinte comando.
composer require symfony/yaml
Ldap
O componente Ldap fornece classes PHP para se conectar a um servidor LDAP ou Active Directory e autenticar o usuário nele. Ele fornece uma opção para se conectar a um controlador de domínio do Windows. O componente Ldap pode ser instalado usando o seguinte comando.
composer require symfony/ldap
Depurar
O componente de depuração oferece várias opções para habilitar a depuração no ambiente PHP. Normalmente, a depuração do código PHP é difícil, mas o componente de depuração fornece classes simples para facilitar o processo de depuração e torná-lo limpo e estruturado. O componente de depuração pode ser instalado usando o seguinte comando.
composer require symfony/debug
Cronômetro
O componente Stopwatch fornece a classe Stopwatch para criar o perfil de nosso código PHP. Um uso simples é o seguinte.
use Symfony\Component\Stopwatch\Stopwatch;
$stopwatch = new Stopwatch();
$stopwatch->start('somename'); // our code to profile $profiled_data = $stopwatch->stop('somename'); echo $profiled_data->getPeriods()
O componente do cronômetro pode ser instalado usando o seguinte comando.
composer require symfony/stopwatch
VarDumper
O componente VarDumper fornece melhor dump()função. Basta incluir o componente VarDumper e usar a função de despejo para obter a funcionalidade aprimorada. O componente VarDumper pode ser instalado usando o seguinte comando.
composer require symfony/var-dumper
BrowserKit
O componente BrowserKit fornece uma interface de cliente de navegador abstrata. Ele pode ser usado para testar o aplicativo da web programaticamente. Por exemplo, ele pode solicitar um formulário, inserir os dados de amostra e enviá-los para localizar qualquer problema no formulário de forma programática. O componente BrowserKit pode ser instalado usando o seguinte comando.
composer require symfony/browser-kit
Ponte PHPUnit
O componente PHPUnit Bridge oferece muitas opções para melhorar o ambiente de teste do PHPUnit. O componente PHPUnit Bridge pode ser instalado usando o seguinte comando.
composer require symfony/phpunit-bridge
De ativos
O componente de ativos fornece uma manipulação de ativos genérica em um aplicativo da web. Ele gera URL para os ativos como CSS, HTML, JavaScript e também realiza manutenção de versão. Verificaremos o componente do ativo em detalhes no capítulo View Engine. O componente ativo pode ser instalado usando o seguinte comando.
composer require symfony/asset
CssSelector
O componente CssSelector fornece uma opção para converter seletores baseados em CSS em expressão XPath. Um desenvolvedor da web conhece a expressão Seletores baseada em CSS mais do que a expressão XPath, mas a expressão mais eficiente para encontrar um elemento em um documento HTML e XML éXPath Expression.
CssSelector permite que o desenvolvedor escreva a expressão em Seletores CSS , no entanto, o componente a converte em expressão XPath antes de executá-la. Assim, o desenvolvedor tem como vantagem a simplicidade dos seletores CSS e a eficiência da expressão XPath.
O componente CssSelector pode ser instalado usando o seguinte comando.
composer require symfony/css-selector
DomCrawler
O componente DomCrawler oferece várias opções para localizar o elemento em um documento HTML e XML usando o conceito DOM. Ele também fornece a opção de usar a expressão XPath para localizar um elemento. O componente DomCrawler pode ser usado junto com o componente CssSelector para usar seletores CSS em vez da expressão XPath. O componente DomCrawler pode ser instalado usando o seguinte comando.
composer require symfony/dom-crawler
Formato
O componente Form permite a fácil criação de formulários em um aplicativo da web. Aprenderemos a programação de formulários em detalhes no capítulo Formulários. O componente de formulário pode ser instalado usando o seguinte comando.
composer require symfony/form
HttpFoundation
O componente HttpFoundation fornece uma camada orientada a objetos para a especificação HTTP. Por padrão, o PHP fornece detalhes de solicitação e resposta HTTP como objeto baseado em array, como$_GET, $_POST, $_FILES, $_SESSION, etc. A funcionalidade baseada em HTTP, como a configuração de um cookie, pode ser feita usando uma função simples e antiga setCookie(). HttpFoundation fornece todas as funcionalidades relacionadas ao HTTP em um pequeno conjunto de classes, como Request, Response, RedirectResponse, etc., aprenderemos sobre essas classes nos capítulos posteriores.
O componente HttpFoundation pode ser instalado usando o seguinte comando.
composer require symfony/http-foundation
HttpKernel
O componente HttpKernel é o componente principal na configuração da Web do Symfony. Ele fornece todas as funcionalidades necessárias para uma aplicação web - desde o recebimento doRequest objeto de enviar de volta o Responseobjeto. A arquitetura completa do aplicativo da web Symfony é fornecida pelo HttpKernel conforme discutido na arquitetura de um framework da web Symfony.
O componente HttpKernel pode ser instalado usando o seguinte comando.
composer require symfony/http-kernel
Encaminhamento
O componente de roteamento mapeia a solicitação HTTP para um conjunto predefinido de variáveis de configuração. O roteamento decide qual parte de nosso aplicativo deve lidar com uma solicitação. Aprenderemos mais sobre o roteamento no capítulo Roteamento.
O componente de roteamento pode ser instalado usando o seguinte comando.
composer require symfony/filesystem
Templating
O componente de modelagem fornece a infraestrutura necessária para construir um sistema de template eficiente. Symfony usa o componente Templating para sua implementação do View engine. Aprenderemos mais sobre o componente Templating no capítulo View engine.
O componente de modelagem pode ser instalado usando o seguinte comando.
composer require symfony/templating
Validador
O componente Validator fornece uma implementação de JSR-303 Bean Validation Specification. Ele pode ser usado para validar um formulário em um ambiente web. Aprenderemos mais sobre o Validador no capítulo Validação.
O componente validador pode ser instalado usando o seguinte comando.
composer require symfony/validator
Segurança
O componente de segurança fornece um sistema de segurança completo para nosso aplicativo da web, seja autenticação HTTP básica, autenticação HTTP digest, autenticação baseada em formulário interativo, login de certificação X.509, etc. Ele também fornece mecanismo de autorização baseado na função do usuário através do sistema ACL embutido . Aprenderemos mais detalhes no capítulo Conceito avançado.
O componente de segurança pode ser instalado usando o seguinte comando.
composer require symfony/security
Em qualquer aplicativo, os objetos tendem a aumentar conforme o aplicativo cresce. Conforme os objetos aumentam, a dependência entre os objetos também aumenta. A dependência do objeto precisa ser tratada adequadamente para um aplicativo bem-sucedido.
Conforme discutido no capítulo Componentes, Symfony fornece um componente fácil e eficiente, DependencyInjectionpara lidar com a dependência do objeto. Um contêiner de serviço é um contêiner de objetos com dependência resolvida adequadamente entre eles. Vamos aprender como usar o componente DependencyInjection neste capítulo.
Vamos criar um Greeterclasse. O objetivo da classe Greeter é cumprimentar o usuário conforme mostrado no exemplo a seguir.
$greeter = new Greeter('Hi'); $greeter->greet('Jon'); // print "Hi, Jon"
O código completo da classe Greeter é o seguinte.
class Greeter {
private $greetingText; public function __construct($greetingText) {
$this->greetingText = $greetingText;
}
public function greet($name) { echo $this->greetingText . ", " . $name . "\r\n";
}
}
Agora, vamos adicionar a classe Greeter ao contêiner de serviço. Symfony forneceContainerBuilderpara criar um novo contêiner. Uma vez que o contêiner é criado, a classe Greeter pode ser registrada nele usando o método de registro do contêiner.
use Symfony\Component\DependencyInjection\ContainerBuilder;
$container = new ContainerBuilder();
$container
->register('greeter', 'Greeter')
->addArgument('Hi');
Aqui, usamos o argumento estático para especificar o texto de saudação, Hi. Symfony também fornece uma configuração dinâmica de parâmetro. Para usar um parâmetro dinâmico, precisamos escolher um nome e especificá-lo entre% e o parâmetro pode ser definido usando o contêinersetParameter método.
$container = new ContainerBuilder();
$container ->register('greeter', 'Greeter') ->addArgument('%greeter.text%'); $container->setParameter('greeter.text', 'Hi');
Registramos uma classe Greeter com configuração adequada. Agora, podemos pedir ao contêiner para fornecer um objeto Greeter configurado corretamente usando o contêinerget método.
$greeter = $container->get('greeter');
$greeter->greet('Jon'); // prints "Hi, Jon"
Registramos com sucesso uma classe, Greeter no container, buscamos no container e a usamos. Agora, vamos criar outra classeUser, que usa a classe Greeter e vê como registrá-la.
class User {
private $greeter;
public $name; public $age;
public function setGreeter(\Greeter $greeter) { $this->greeter = $greeter; } public function greet() { $this->greeter->greet($this->name);
}
}
A classe User obtém a classe Greeter usando um de seus métodos setter,setGreeter. Para este cenário, Symfony fornece um método,addMethodCall e uma aula, Reference para se referir a outra classe, conforme mostrado no código a seguir.
use Symfony\Component\DependencyInjection\Reference;
$container
->register('user', 'User')
->addMethodCall('setGreeter', array(new Reference('greeter')));
Finalmente, registramos duas classes, Greeter e Usertendo uma forte relação entre eles. Agora, podemos buscar com segurança o objeto User com a classe Greeter configurada corretamente no contêiner, conforme mostrado no código a seguir.
$container->setParameter('greeter.text', 'Hi'); $user = $container->get('user'); $user->name = "Jon";
$user->age = 20; $user->greet(); // Prints "Hi, Jon"
Vimos como configurar um objeto em um contêiner usando o próprio PHP. Symfony também oferece outros mecanismos. Eles são arquivos de configuração XML e YAML. Vamos ver como configurar um contêiner usando YAML. Para isso, instalesymfony/config e symfony/yaml componentes junto com symfony/dependency-injection componentes.
cd /path/to/dir
mkdir dependency-injection-example
cd dependency-injection-example
composer require symfony/dependency-injection
composer require symfony/config
composer require symfony/yaml
A configuração YAML será escrita em um arquivo separado, services.yml. A configuração YAML consiste em duas seções,parameters e services. A seção de parâmetros define todos os parâmetros necessários. A seção de serviços define todos os objetos. A seção de serviços é dividida em várias seções, a saber,class, arguments, e calls. Classe especifica a classe real. Argumentos especifica os argumentos do construtor. Finalmente, as chamadas especificam os métodos setter. Outra classe pode ser referenciada usando o símbolo @, @greeter.
parameters:
greeter.text: 'Hello'
services:
greeter:
class: Greeter
arguments: ['%greeter.text%']
user:
class: User
calls:
- [setGreeter, ['@greeter']]
Agora, services.yml pode ser carregado e configurado usando FileLoader e YamlFileLoader conforme mostrado no código a seguir.
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
$yamlContainer = new ContainerBuilder(); $loader = new YamlFileLoader($yamlContainer, new FileLocator(__DIR__)); $loader->load('services.yml');
$yamlUser = $yamlContainer->get('user');
$yamlUser->name = "Jon"; $yamlUser->age = 25;
$yamlUser->greet();
A lista de códigos completa é a seguinte.
main.php
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
class Greeter {
private $greetingText;
public function __construct($greetingText) { $this->greetingText = $greetingText; } public function greet($name) {
echo $this->greetingText . ", " . $name . "\r\n";
}
}
class User {
private $greeter; public $name;
public $age; public function setGreeter(\Greeter $greeter) {
$this->greeter = $greeter;
}
public function greet() {
$this->greeter->greet($this->name);
}
}
$container = new ContainerBuilder(); $container
->register('greeter', 'Greeter')
->addArgument('%greeter.text%');
$container ->register('user', 'User') ->addMethodCall('setGreeter', array(new Reference('greeter'))); $container->setParameter('greeter.text', 'Hi');
$greeter = $container->get('greeter');
$greeter->greet('Jon'); $user = $container->get('user'); $user->name = "Jon";
$user->age = 20; $user->greet();
$yamlContainer = new ContainerBuilder(); $loader = new YamlFileLoader($yamlContainer, new FileLocator(__DIR__)); $loader->load('services.yml');
$yamlHello = $yamlContainer->get('greeter');
$yamlHello->greet('Jon'); $yamlUser = $yamlContainer->get('user'); $yamlUser->name = "Jon";
$yamlUser->age = 25; $yamlUser->greet();
?>
services.yml
parameters:
greeter.text: 'Hello'
services:
greeter:
class: Greeter
arguments: ['%greeter.text%']
user:
class: User
calls:
- [setGreeter, ['@greeter']]
O framework web Symfony usa o componente de injeção de dependência extensivamente. Todos os componentes são vinculados ao contêiner de serviço centralizado. O framework da Web Symfony expõe o contêiner em todos os seusController através containerpropriedade. Podemos obter todos os objetos registrados nele, digamos logger, mailer, etc., por meio dele.
$logger = $this->container->get('logger');
$logger->info('Hi');
Para encontrar o objeto registrado no container, use o seguinte comando.
cd /path/to/app
php bin/console debug:container
Existem cerca de 200 + objetos no hello aplicativo da web criado no capítulo de instalação.
Symfony fornece programação baseada em eventos por meio de seu EventDispatchercomponente. Qualquer aplicativo corporativo precisa de programação baseada em eventos para criar um aplicativo altamente personalizável. Os eventos são uma das principais ferramentas para os objetos interagirem entre si. Sem eventos, um objeto não interage de forma eficiente.
O processo de programação baseada em eventos pode ser resumido como - Um objeto, chamado Event sourcepede ao objeto central dispatcher para registrar um evento, digamos user.registered. Um ou mais objetos, chamados de ouvinte, perguntam ao objeto do despachante central que deseja ouvir um evento específico, digamos usuário.registrado. Em algum ponto do tempo, o objeto de origem do Evento pede ao objeto do despachante central para despachar o evento, digamos user.registered junto com um objeto Event com as informações necessárias. O despachante central informa todos os objetos ouvintes sobre o evento, digamos user.registered e seu objeto Event *.
Na programação baseada em eventos, temos quatro tipos de objetos: Event Source, Event Listener, Even Dispatcher e o próprio Event.
Vamos escrever um aplicativo simples para entender o conceito.
Step 1 - Crie um projeto, event-dispatcher-example.
cd /path/to/dir
mkdir event-dispatcher-example
cd event-dispatcher-example
composer require symfony/event-dispatcher
Step 2 - Crie uma classe, .User.
class User {
public $name;
public $age; } $user = new User();
$user->name = "Jon"; $user->age = 25
Step 3 - Crie um evento, UserRegisteredEvent.
use Symfony\Component\EventDispatcher\Event;
class UserRegisteredEvent extends Event {
const NAME = 'user.registered';
protected $user; public function __construct(User $user) {
$this-<user = $user;
}
public function getUser() {
return $this-<user; } } $event = new UserRegisteredEvent($user);
Aqui, UserRegisteredEvent tem acesso a Userobjeto. O nome do evento éuser.registered.
Step 4 - Crie um ouvinte, UserListener.
class UserListener {
public function onUserRegistrationAction(Event $event) {
$user = $event->getUser();
echo $user->name . "\r\n"; echo $user->age . "\r\n";
}
}
$listener = new UserListener();
Step 5 - Crie um objeto dispatcher de evento.
use Symfony\Component\EventDispatcher\EventDispatcher;
$dispatcher = new EventDispatcher();
Step 6 - Conecte o ouvinte e o evento usando o objeto do distribuidor e seu método, addListener.
$dispatcher ->addListener( UserRegisteredEvent::NAME, array($listener, 'onUserRegistrationAction'));
Também podemos adicionar uma função anônima como ouvinte de evento, conforme mostrado no código a seguir.
$dispatcher ->addListener( UserRegisteredEvent::NAME, function(Event $event) {
$user = $event->getUser();
echo $user->name . "\r\n";
});
Step 7 - Por fim, dispare / despache o evento usando o método do despachante de eventos, dispatch.
$dispatcher->dispatch(UserRegisteredEvent::NAME, $event);
A lista de códigos completa é a seguinte.
main.php
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
class User {
public $name;
public $age; } class UserRegisteredEvent extends Event { const NAME = 'user.registered'; protected $user;
public function __construct(User $user) { $this->user = $user; } public function getUser() { return $this->user;
}
}
class UserListener {
public function onUserRegistrationAction(Event $event) { $user = $event->getUser(); echo $user->name . "\r\n";
echo $user->age . "\r\n"; } } $user = new User();
$user->name = "Jon"; $user->age = 25;
$event = new UserRegisteredEvent($user);
$listener = new UserListener(); $dispatcher = new EventDispatcher();
$dispatcher ->addListener( UserRegisteredEvent::NAME, function(Event $event) {
$user = $event->getUser();
echo $user->name . "\r\n"; }); $dispatcher
->addListener(
UserRegisteredEvent::NAME, array($listener, 'onUserRegistrationAction')); $dispatcher->dispatch(UserRegisteredEvent::NAME, $event);
?>
Resultado
Jon
Jon
25
O framework da web Symfony tem muitos eventos e pode-se registrar o ouvinte para esses eventos e programá-lo de acordo. Um dos eventos de amostra é kernel.exception e o evento correspondente éGetResponseForExceptionEvent, que contém o objeto de resposta (a saída de uma solicitação da web). Isso é usado para capturar a exceção e modificar a resposta com informações de erro genéricas, em vez de mostrar o erro de tempo de execução aos usuários.
Como discutimos anteriormente, a linguagem de expressão é um dos recursos mais importantes do aplicativo Symfony. A expressão Symfony é criada principalmente para ser usada em um ambiente de configuração. Ele permite que um não-programador configure o aplicativo da web com pouco esforço. Vamos criar um aplicativo simples para testar uma expressão.
Step 1 - Crie um projeto, expression-language-example.
cd /path/to/dir
mkdir expression-language-example
cd expression-language-example
composer require symfony/expression-language
Step 2 - Crie um objeto de expressão.
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
$language = new ExpressionLanguage();
Step 3 - Teste uma expressão simples.
echo "Evaluated Value: " . $language->evaluate('10 + 12') . "\r\n" ; echo "Compiled Code: " . $language->compile('130 % 34') . "\r\n" ;
Step 4 - A expressão Symfony é poderosa de forma que pode interceptar um objeto PHP e sua propriedade também na linguagem de expressão.
class Product {
public $name; public $price;
}
$product = new Product(); $product->name = 'Cake';
$product->price = 10; echo "Product price is " . $language
->evaluate('product.price', array('product' => $product,)) . "\r\n"; echo "Is Product price higher than 5: " . $language
->evaluate('product.price > 5', array('product' => $product,)) . "\r\n";
Aqui, a expressão product.price e product.price > 5 interceptar $product propriedade do objeto price e avaliar o resultado.
A codificação completa é a seguinte.
main.php
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
$language = new ExpressionLanguage(); echo "Evaluated Value: " . $language->evaluate('10 + 12') . "\r\n" ;
echo "Compiled Code: " . $language->compile('130 % 34') . "\r\n" ; class Product { public $name;
public $price; } $product = new Product();
$product->name = 'Cake'; $product->price = 10;
echo "Product price is " . $language ->evaluate('product.price', array('product' => $product,)) . "\r\n";
echo "Is Product price higher than 5: " . $language ->evaluate('product.price > 5', array('product' => $product,)) . "\r\n";
?>
Resultado
Evaluated Value: 22
Compiled Code: (130 % 34)
Product price is 10
Is Product price higher than 5: 1
Um pacote Symfony é uma coleção de arquivos e pastas organizados em uma estrutura específica. Os pacotes são modelados de forma que possam ser reutilizados em vários aplicativos. O próprio aplicativo principal é empacotado como um pacote e geralmente é chamadoAppBundle.
Um pacote pode ser empacotado específico para um aplicativo, como AdminBundle (seção de administração), BlogBundle (blog do site), etc. Esses pacotes não podem ser compartilhados entre um aplicativo. Em vez disso, podemos modelar uma determinada parte do aplicativo, como blogs, como pacote genérico para que possamos simplesmente copiar o pacote de um aplicativo para outro aplicativo para reutilizar a funcionalidade de blog.
Estrutura de um pacote
A estrutura básica de um pacote é a seguinte.
Controller - Todos os controladores precisam ser colocados aqui.
DependencyInjection - Todos os códigos e configurações relacionados à injeção de dependência precisam ser colocados aqui.
Resources/config - As configurações relacionadas ao pacote são colocadas aqui.
Resources/view - Os modelos de visualização relacionados ao pacote são colocados aqui.
Resources/public - Folhas de estilo relacionadas ao pacote, JavaScripts, imagens, etc., são colocados aqui.
Tests - Arquivos de teste de unidade relacionados ao pacote são colocados aqui.
Criação de um pacote
Vamos criar um pacote simples, TutorialspointDemoBundle na nossa HelloWorld inscrição.
Step 1- Escolha um namespace. O namespace de um pacote deve incluir o nome do fornecedor e o nome do pacote. No nosso caso, éTutorialspoint\DemoBundle.
Step 2 - Crie uma classe vazia, TutorialspointDemoBundle estendendo Bundle classe e colocá-lo sob src/Tutorialspoint/DemoBundle.
namespace Tutorialspoint\DemoBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class TutorialspointDemoBundle extends Bundle {
}
Step 3 - Registre a turma na lista de bundles suportados pelo aplicativo em AppKernel classe.
public function registerBundles() {
$bundles = array( // ... // register your bundle new Tutorialspoint\DemoBundle\TutorialspointDemoBundle(), ); return $bundles;
}
Isso é tudo o que é necessário para criar um pacote vazio e todos os outros conceitos são iguais aos do aplicativo. Symfony também oferece um comando de consolegenerate:bundle para simplificar o processo de criação de um novo pacote, que é o seguinte.
php bin/console generate:bundle --namespace = Tutorialspoint/DemoBundle
Resultado
Welcome to the Symfony bundle generator!
Are you planning on sharing this bundle across multiple applications? [no]: no
Your application code must be written in bundles. This command helps
you generate them easily.
Give your bundle a descriptive name, like BlogBundle.
Bundle name [Tutorialspoint/DemoBundle]:
In your code, a bundle is often referenced by its name. It can be the
concatenation of all namespace parts but it's really up to you to come
up with a unique name (a good practice is to start with the vendor name).
Based on the namespace, we suggest TutorialspointDemoBundle.
Bundle name [TutorialspointDemoBundle]:
Bundles are usually generated into the src/ directory. Unless you're
doing something custom, hit enter to keep this default!
Target Directory [src/]:
What format do you want to use for your generated configuration?
Configuration format (annotation, yml, xml, php) [annotation]:
Bundle generation
> Generating a sample bundle skeleton into app/../src/Tutorialspoint/DemoBundle
created ./app/../src/Tutorialspoint/DemoBundle/
created ./app/../src/Tutorialspoint/DemoBundle/TutorialspointDemoBundle.php
created ./app/../src/Tutorialspoint/DemoBundle/Controller/
created ./app/../src/Tutorialspoint/DemoBundle/Controller/DefaultController.php
created ./app/../tests/TutorialspointDemoBundle/Controller/
created ./app/../tests/TutorialspointDemoBundle/Controller/DefaultControllerTest.php
created ./app/../src/Tutorialspoint/DemoBundle/Resources/views/Default/
created ./app/../src/Tutorialspoint/DemoBundle/Resources/views/Default/index.html.twig
created ./app/../src/Tutorialspoint/DemoBundle/Resources/config/
created ./app/../src/Tutorialspoint/DemoBundle/Resources/config/services.yml
> Checking that the bundle is autoloaded
> Enabling the bundle inside app/AppKernel.php
updated ./app/AppKernel.php
> Importing the bundle's routes from the app/config/routing.yml file
updated ./app/config/routing.yml
> Importing the bundle's services.yml from the app/config/config.yml file
updated ./app/config/config.yml
Everything is OK! Now get to work :).
Este capítulo explica como criar um aplicativo simples no framework Symfony. Conforme discutido anteriormente, você sabe como criar um novo projeto no Symfony.
Podemos dar um exemplo de detalhes do “aluno”. Vamos começar criando um projeto chamado “aluno” usando o seguinte comando.
symfony new student
Após a execução do comando, um projeto vazio é criado.
Controlador
Symfony é baseado no padrão de desenvolvimento Model-View-Controller (MVC). MVC é uma abordagem de software que separa a lógica do aplicativo da apresentação. O controlador desempenha um papel importante no Symfony Framework. Todas as páginas da web em um aplicativo precisam ser gerenciadas por um controlador.
DefaultController classe está localizada em “src/AppBundle/Controller”. Você pode criar sua própria classe Controller lá.
Mover para o local “src/AppBundle/Controller” e criar um novo StudentController classe.
A seguir está a sintaxe básica para StudentController classe.
StudentController.php
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
class StudentController {
}
Agora, você criou um StudentController. No próximo capítulo, discutiremos mais sobre o Controlador em detalhes.
Crie uma rota
Uma vez que o controlador foi criado, precisamos encaminhar para uma página específica. Os mapas de roteamento solicitam o URI para um método de controlador específico.
A seguir está a sintaxe básica para roteamento.
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class StudentController {
/**
* @Route("/student/home")
*/
public function homeAction() {
return new Response('Student details application!');
}
}
Na sintaxe acima, @Route(“/student/home”)é a rota. Ele define o padrão de URL da página.
homeAction() é o método de ação, onde você pode construir a página e retornar um objeto Response.
Abordaremos o roteamento em detalhes no próximo capítulo. Agora, solicite a url “http: // localhost: 8000 / student / home” e produz o seguinte resultado.
Resultado
O controlador é responsável por lidar com cada solicitação que chega ao aplicativo Symfony. O controlador lê uma informação da solicitação. Em seguida, cria e retorna um objeto de resposta ao cliente.
De acordo com Symfony, DefaultController classe está localizada em “src/AppBundle/Controller”. É definido como segue.
DefaultController.php
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller {
}
Aqui o HttpFoundation componente define uma camada orientada a objetos para a especificação HTTP, e o FrameworkBundle contém a maior parte da funcionalidade "base" da estrutura.
Solicitar objeto
A classe Request é uma representação orientada a objetos da mensagem de solicitação HTTP.
Criação de um objeto de solicitação
A solicitação pode ser criada usando createFromGlobals() método.
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
Você pode simular uma solicitação usando Globals. Em vez de criar uma solicitação com base nos globais do PHP, você também pode simular uma solicitação.
$request = Request::create(
'/student',
'GET',
array('name' => 'student1')
);
Aqui o create() método cria uma solicitação com base em um URI, um método e alguns parâmetros.
Substituindo um objeto de solicitação
Você pode substituir as variáveis globais do PHP usando o overrideGlobals()método. É definido como segue.
$request->overrideGlobals();
Acessando um objeto de solicitação
A solicitação de uma página da web pode ser acessada em um controlador (método de ação) usando getRequest() método do controlador de base.
$request = $this->getRequest();
Identificando um objeto de solicitação
Se você quiser identificar uma solicitação em seu aplicativo, “PathInfo"método retornará a identidade única do URL da solicitação. É definido como segue.
$request->getPathInfo();
Objeto de Resposta
O único requisito para um controlador é retornar um objeto Response. Um objeto Response contém todas as informações de uma determinada solicitação e as envia de volta ao cliente.
A seguir está um exemplo simples.
Exemplo
use Symfony\Component\HttpFoundation\Response;
$response = new Response(‘Default'.$name, 10);
Você pode definir o objeto Response em JSON da seguinte maneira.
$response = new Response(json_encode(array('name' => $name)));
$response->headers->set('Content-Type', 'application/json');
Construtor de Resposta
O construtor contém três argumentos -
- O conteúdo da resposta
- O código de status
- Uma matriz de cabeçalhos HTTP
A seguir está a sintaxe básica.
use Symfony\Component\HttpFoundation\Response;
$response = new Response(
'Content',
Response::HTTP_OK,
array('content-type' => 'text/html')
);
Por exemplo, você pode passar o argumento de conteúdo como,
$response->setContent(’Student details’);
Da mesma forma, você pode passar outros argumentos também.
Enviando resposta
Você pode enviar uma resposta ao cliente usando o send()método. É definido como segue.
$response->send();
Para redirecionar o cliente para outro URL, você pode usar o RedirectResponse classe.
É definido como segue.
use Symfony\Component\HttpFoundation\RedirectResponse;
$response = new RedirectResponse('http://tutorialspoint.com/');
FrontController
Um único arquivo PHP que lida com todas as solicitações recebidas em seu aplicativo. O FrontController executa o roteamento de diferentes URLs para diferentes partes internas do aplicativo.
A seguir está a sintaxe básica para FrontController.
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
$request = Request::createFromGlobals();
$path = $request->getPathInfo(); // the URI path being requested
if (in_array($path, array('', '/'))) { $response = new Response(’Student home page.');
} elseif (‘/about’ === $path) { $response = new Response(’Student details page’);
} else {
$response = new Response('Page not found.', Response::HTTP_NOT_FOUND); } $response->send();
Aqui o in_array() função pesquisa um array para um valor específico.
Os mapas de roteamento solicitam o URI para um método de controlador específico. Em geral, qualquer URI tem as três partes a seguir -
- Segmento de nome de host
- Segmento de caminho
- Segmento de consulta
Por exemplo, em URI / URL, http://www.tutorialspoint.com/index?q=data, www.tutorialspoint.comé o segmento do nome do host, índice é o segmento do caminho e q = data é o segmento da consulta. Geralmente, o roteamento verifica o segmento da página em relação a um conjunto de restrições. Se qualquer restrição corresponder, ele retornará um conjunto de valores. Um dos principais valores é o controlador.
Anotações
A anotação desempenha um papel importante na configuração do aplicativo Symfony. A anotação simplifica a configuração, declarando a configuração na própria codificação. A anotação nada mais é do que fornecer metainformações sobre classes, métodos e propriedades. O roteamento usa anotações extensivamente. Mesmo que o roteamento possa ser feito sem anotação, a anotação simplifica o roteamento em grande medida.
A seguir está um exemplo de anotação.
/**
* @Route(“/student/home”)
*/
public function homeAction() {
// ...
}
Conceitos de Roteamento
Considere a classe StudentController criada no projeto “student”.
StudentController.php
// src/AppBundle/Controller/StudentController.php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class StudentController extends Controller {
/**
* @Route(“/student/home”)
*/
public function homeAction() {
// ...
}
/**
* @Route(“/student/about”)
*/
public function aboutAction() {
}
}
Aqui, o roteamento executa duas etapas. Se você vai para/student/home, a primeira rota é correspondida, então homeAction()É executado. Caso contrário, se você for para/student/about, a segunda rota é combinada e então aboutAction() É executado.
Adicionar formatos curinga
Considere, você tem uma lista paginada de registros de alunos com URLs como / student / 2 e / student / 3 para as páginas 2 e 3, correspondentemente. Então, se você quiser mudar o caminho da rota, você pode usar formatos curinga.
Exemplo
// src/AppBundle/Controller/BlogController.php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class StudentController extends Controller {
/**
* @Route(“/student/{page}", name = “student_about”, requirements = {"page": "\d+"})
*/
public function aboutAction($page) {
// ...
}
}
Aqui o \d+ é uma expressão regular que corresponde a um dígito de qualquer comprimento.
Atribuir espaço reservado
Você pode atribuir um valor de espaço reservado no roteamento. É definido como segue.
// src/AppBundle/Controller/BlogController.php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class StudentController extends Controller {
/**
* @Route(“/student/{page}", name = “student_about”, requirements = {"page": "\d+"})
*/
public function aboutAction($page = 1) {
// ...
}
}
Aqui, se você for para / student, o student_about route vai combinar e $page será padronizado para um valor de 1.
Redirecionando para uma página
Se você deseja redirecionar o usuário para outra página, use o redirectToRoute() e redirect() métodos.
public function homeAction() {
// redirect to the "homepage" route
return $this->redirectToRoute('homepage');
// redirect externally
\return $this->redirect('http://example.com/doc');
}
Gerando URLs
Para gerar um URL, considere um nome de rota, student_name e nome curinga, student-namesusado no caminho para essa rota. A lista completa para gerar uma URL é definida a seguir.
class StudentController extends Controller {
public function aboutAction($name) {
// ...
// /student/student-names
$url = $this->generateUrl(
‘student_name’,
array(‘name’ =>
’student-names’)
);
}
}
StudentController
Considere um exemplo simples de roteamento na classe StudentController como segue.
StudentController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class StudentController {
/**
* @Route("/student/home")
*/
public function homeAction() {
$name = 'Student details application'; return new Response( '<html><body>Project: '.$name.'</body></html>'
);
}
}
Agora, solicite o url,”http://localhost:8000/student/home” e produz o seguinte resultado.
Da mesma forma, você pode criar outra rota para aboutAction() também.
Uma camada de visualização é a camada de apresentação do aplicativo MVC. Ele separa a lógica do aplicativo da lógica da apresentação.
Quando um controlador precisa gerar HTML, CSS ou qualquer outro conteúdo, ele encaminha a tarefa para o mecanismo de modelagem.
Modelos
Os modelos são basicamente arquivos de texto usados para gerar qualquer documento baseado em texto, como HTML, XML, etc. Ele é usado para economizar tempo e reduzir erros.
Por padrão, os modelos podem residir em dois locais diferentes -
app/Resources/views/- O diretório de visualizações do aplicativo pode conter os layouts de seu aplicativo e os modelos do pacote do aplicativo. Ele também substitui os modelos de pacote de terceiros.
vendor/path/to/Bundle/Resources/views/ - Cada pacote de terceiros contém seus modelos em seu diretório “Recursos / visualizações /”.
Twig Engine
Symfony usa uma poderosa linguagem de modelos chamada Twig. O Twig permite que você escreva modelos concisos e legíveis de uma maneira muito fácil. Os modelos Twig são simples e não processam tags PHP. Twig executa controle de espaço em branco, sandbox e escape automático de HTML.
Sintaxe
Twig contém três tipos de sintaxe especial -
{{ ... }} - Imprime uma variável ou o resultado de uma expressão no modelo.
{% ... %} - Uma tag que controla a lógica do modelo. É usado principalmente para executar uma função.
{# ... #}- Sintaxe do comentário. É usado para adicionar comentários de uma ou várias linhas.
O modelo da base do galho está localizado em “app/Resources/views/base.html.twig”.
Exemplo
Vamos examinar um exemplo simples usando o mecanismo de galho.
StudentController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class StudentController extends Controller {
/**
* @Route("/student/home")
*/
public function homeAction() {
return $this->render('student/home.html.twig');
}
}
Aqui o render() método renderiza um modelo e coloca esse conteúdo em um objeto Response.
Agora vá para o diretório “views” e crie uma pasta “student” e dentro dessa pasta crie um arquivo “home.html.twig”. Adicione as seguintes alterações no arquivo.
home.html.twig
//app/Resources/views/student/home.html.twig
<h3>Student application!</h3>
Você pode obter o resultado solicitando a url “http: // localhost: 8000 / student / home”.
Por padrão, o Twig vem com uma longa lista de tags, filtros e funções. Vamos examinar um por um em detalhes.
Tag
Twig suporta as seguintes tags importantes -
Faz
o dotag executa funções semelhantes às de expressão regular, com a exceção de que não imprime nada. Sua sintaxe é a seguinte -
{% do 5 + 6 %}
Incluir
A instrução include inclui um modelo e retorna o conteúdo renderizado desse arquivo no namespace atual. Sua sintaxe é a seguinte -
{% include 'template.html' %}
Estende
A tag extends pode ser usada para estender um template de outro. Sua sintaxe é a seguinte -
{% extends "template.html" %}
Quadra
O bloco atua como um espaço reservado e substitui o conteúdo. Os nomes dos blocos consistem em caracteres alfanuméricos e sublinhados. Por exemplo,
<title>{% block title %}{% endblock %}</title>
Embutir
o embedtag executa uma combinação de include e extends. Ele permite que você inclua o conteúdo de outro modelo. Ele também permite que você substitua qualquer bloco definido dentro do modelo incluído, como ao estender um modelo. Sua sintaxe é a seguinte -
{% embed “new_template.twig” %}
{# These blocks are defined in “new_template.twig" #}
{% block center %}
Block content
{% endblock %}
{% endembed %}
Filtro
As seções de filtro permitem que você aplique filtros Twig regulares em um bloco de dados de modelo. Por exemplo,
{% filter upper %}
symfony framework
{% endfilter %}
Aqui, o texto será alterado para maiúsculas.
Para
Forloop busca cada item em uma sequência. Por exemplo,
{% for x in 0..10 %}
{{ x }}
{% endfor %}
E se
o ifdeclaração no Twig é semelhante ao PHP. A expressão é avaliada como verdadeira ou falsa. Por exemplo,
{% if value == true %}
<p>Simple If statement</p>
{% endif %}
Filtros
Twig contém filtros. É usado para modificar o conteúdo antes de ser renderizado. A seguir estão alguns dos filtros notáveis.
comprimento
O filtro de comprimento retorna o comprimento de uma string. Sua sintaxe é a seguinte -
{% if name|length > 5 %}
...
{% endif %}
Mais baixo
O filtro inferior converte um valor em minúsculas. Por exemplo,
{{ 'SYMFONY'|lower }}
Isso produziria o seguinte resultado -
symfony
Da mesma forma, você pode tentar letras maiúsculas.
Substituir
O filtro de substituição formata uma determinada string substituindo os marcadores de posição. Por exemplo,
{{ "tutorials point site %si% and %te%."|replace({'%si%': web, '%te%': "site"}) }}
Isso produzirá o seguinte resultado -
tutorials point website
Título
O filtro de título retorna uma versão titlecase do valor. Por exemplo,
{{ 'symfony framework '|title }}
Isso produzirá o seguinte resultado -
Symfony Framework
Ordenar
O filtro de classificação classifica uma matriz. Sua sintaxe é a seguinte -
{% for user in names|sort %}
...
{% endfor %}
aparar
O filtro de compensação remove os espaços em branco (ou outros caracteres) do início e do final de uma string. Por exemplo,
{{ ' Symfony! '|trim }}
Isso produzirá o seguinte resultado -
Symfony!
Funções
Twig oferece suporte a funções. É usado para obter um determinado resultado. A seguir estão algumas das funções importantes do Twig.
Atributo
o attributefunção pode ser usada para acessar um atributo “dinâmico” de uma variável. Sua sintaxe é a seguinte -
{{ attribute(object, method) }}
{{ attribute(object, method, arguments) }}
{{ attribute(array, item) }}
Por exemplo,
{{ attribute(object, method) is defined ? 'Method exists' : 'Method does not exist' }}
Constante
A função constante retorna o valor constante de uma string especificada. Por exemplo,
{{ constant('Namespace\\Classname::CONSTANT_NAME') }}
Ciclo
A função de ciclo gira em uma matriz de valores. Por exemplo,
{% set months = [‘Jan’, ‘Feb’, ‘Mar’] %}
{% for x in 0..12 %}
{ cycle(months, x) }}
{% endfor %}
Encontro
Converte um argumento em uma data para permitir a comparação de datas. Por exemplo,
<p>Choose your location before {{ 'next Monday'|date('M j, Y') }}</p>
Isso produzirá o seguinte resultado -
Choose your location before May 15, 2017
O argumento deve estar em um dos formatos de data e hora suportados pelo PHP.
Você pode passar um fuso horário como o segundo argumento.
Despejar
A função de despejo despeja informações sobre uma variável de modelo. Por exemplo,
{{ dump(user) }}
Max
A função max retorna o maior valor de uma sequência. Por exemplo,
{{ max(1, 5, 9, 11, 15) }}
Min
A função min retorna o menor valor de uma sequência. Por exemplo,
{{ min(1, 3, 2) }}
Incluir
A função include retorna o conteúdo renderizado de um template. Por exemplo,
{{ include('template.html') }}
Aleatória
A função aleatória gera um valor aleatório. Por exemplo,
{{ random([‘Jan’, ‘Feb’, ‘Mar’, ‘Apr’]) }}
{# example output: Jan #}
Alcance
A função de intervalo retorna uma lista contendo uma progressão aritmética de inteiros. Por exemplo,
{% for x in range(1, 5) %}
{{ x }},
{% endfor %}
Isso produzirá o seguinte resultado -
1,2,3,4,5
Layouts
Um Layout representa as partes comuns de várias visualizações, por exemplo, cabeçalho da página e rodapé.
Herança de modelo
Um modelo pode ser usado por outro. Podemos conseguir isso usando o conceito de herança de template. A herança do modelo permite que você crie um modelo de “layout” básico que contém todos os elementos comuns de um site definidos como blocos.
Vamos dar um exemplo simples para entender mais sobre herança de template.
Exemplo
Considere o modelo base localizado em “app / Resources / views / base.html.twig”. Adicione as seguintes alterações no arquivo.
base.html.twig
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<title>{% block title %}Parent template Layout{% endblock %}</title>
</head>
</html>
Agora vá para o arquivo de modelo de índice localizado em “app / Resources / views / default / index.html.twig“ . Adicione as seguintes alterações nele.
index.html.twig
{% extends 'base.html.twig' %}
{% block title %}Child template Layout{% endblock %}
Aqui o {% extends %}tag informa ao mecanismo de modelagem para avaliar primeiro o template base, que configura o layout e define o bloco. O modelo filho é então renderizado. Um modelo filho pode estender o layout básico e substituir o bloco de título. Agora, solicite a url “http: // localhost: 8000” e poderá obter o seu resultado.
Ativos
O Ativo gerencia a geração de URL e o controle de versão de ativos da web, como folhas de estilo CSS, arquivos JavaScript e arquivos de imagem.
JavaScript
Para incluir arquivos JavaScript, use o javascripts tag em qualquer modelo.
{# Include javascript #}
{% block javascripts %}
{% javascripts '@AppBundle/Resources/public/js/*' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
Folhas de estilo
Para incluir arquivos de folha de estilo, use o stylesheets tag em qualquer modelo
{# include style sheet #}
{% block stylesheets %}
{% stylesheets 'bundles/app/css/*' filter = 'cssrewrite' %}
<link rel = "stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
{% endblock %}
Imagens
Para incluir uma imagem, você pode usar a tag de imagem. É definido como segue.
{% image '@AppBundle/Resources/public/images/example.jpg' %}
<img src = "{{ asset_url }}" alt = "Example" />
{% endimage %}
Ativos Compostos
Você pode combinar muitos arquivos em um. Isso ajuda a reduzir o número de solicitações HTTP e produz maior desempenho de front-end.
{% javascripts
'@AppBundle/Resources/public/js/*'
'@AcmeBarBundle/Resources/public/js/form.js'
'@AcmeBarBundle/Resources/public/js/calendar.js' %}
<script src = "{{ asset_url }}"></script>
{% endjavascripts %}
No framework web Symfony, o modelo desempenha um papel importante. Eles são as entidades empresariais. Eles são fornecidos por clientes ou buscados no banco de dados de back-end, manipulados de acordo com as regras de negócios e persistidos de volta no banco de dados. Eles são os dados apresentados por Views. Vamos aprender sobre os modelos e como eles interagem com o sistema back-end neste capítulo.
Modelo de Banco de Dados
Precisamos mapear nossos modelos para os itens do banco de dados relacional de back-end para buscar e persistir os modelos com segurança e eficiência. Esse mapeamento pode ser feito com uma ferramenta Object Relational Mapping (ORM). Symfony fornece um pacote separado,DoctrineBundle, que integra Symfony com ferramenta ORM de banco de dados PHP de terceiros, Doctrine.
Doutrina ORM
Por padrão, o framework Symfony não fornece nenhum componente para trabalhar com bancos de dados. Mas, ele se integra perfeitamente comDoctrine ORM. Doctrine contém várias bibliotecas PHP usadas para armazenamento de banco de dados e mapeamento de objetos.
O exemplo a seguir irá ajudá-lo a entender como o Doctrine funciona, como configurar um banco de dados e como salvar e recuperar os dados.
Exemplo de Doutrina ORM
Neste exemplo, primeiro configuraremos o banco de dados e criaremos um objeto Aluno e, em seguida, realizaremos algumas operações nele.
Para fazer isso, precisamos seguir as etapas a seguir.
Etapa 1: Crie um aplicativo Symfony
Crie um aplicativo Symfony, dbsample usando o seguinte comando.
symfony new dbsample
Etapa 2: configurar um banco de dados
Geralmente, as informações do banco de dados são configuradas no arquivo “app / config / parameters.yml”.
Abra o arquivo e adicione as seguintes alterações.
parameter.yml
parameters:
database_host: 127.0.0.1
database_port: null
database_name: studentsdb
database_user: <user_name>
database_password: <password>
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: null
mailer_password: null
secret: 037ab82c601c10402408b2b190d5530d602b5809
doctrine:
dbal:
driver: pdo_mysql
host: '%database_host%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: utf8mb4
Agora, Doctrine ORM pode se conectar ao banco de dados.
Etapa 3: Criar um banco de dados
Emita o seguinte comando para gerar o banco de dados “studentsdb”. Esta etapa é usada para ligar o banco de dados no Doctrine ORM.
php bin/console doctrine:database:create
Depois de executar o comando, ele gera automaticamente um banco de dados “studentsdb” vazio. Você pode ver a seguinte resposta na tela.
Created database `studentsdb` for connection named default
Etapa 4: informações do mapa
Mapping information nada mais é do que "metadados". É uma coleção de regras que informa ao Doctrine ORM exatamente como a classe Student e suas propriedades são mapeadas para uma tabela de banco de dados específica.
Bem, esses metadados podem ser especificados em vários formatos diferentes, incluindo YAML, XML ou você pode passar diretamente na aula do aluno usando anotações. É definido como segue.
Student.php
Adicione as seguintes alterações no arquivo.
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name = "students")
*/
class Student {
/**
* @ORM\Column(type = "integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy = "AUTO")
*/
private $id;
/**
* @ORM\Column(type = "string", length = 50)
*/
private $name; /** * @ORM\Column(type = "text") */ private $address;
}
Aqui, o nome da tabela é opcional. Se o nome da tabela não for especificado, ele será determinado automaticamente com base no nome da classe de entidade.
Etapa 5: vincular uma entidade
O Doctrine cria classes de entidade simples para você. Ajuda a construir qualquer entidade.
Emita o seguinte comando para gerar uma entidade.
php bin/console doctrine:generate:entities AppBundle/Entity/Student
Então você verá o seguinte resultado e a entidade será atualizada.
Generating entity "AppBundle\Entity\Student"
> backing up Student.php to Student.php~
> generating AppBundle\Entity\Student
Student.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name="students")
*/
class Student {
/**
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id; /** * @ORM\Column(type = "string", length = 50) */ private $name;
/**
* @ORM\Column(type = "text")
*/
private $address; /** * Get id * * @return integer */ public function getId() { return $this->id;
}
/**
* Set name
*
* @param string $name * * @return Student */ public function setName($name) {
$this->name = $name;
return $this; } /** * Get name * * @return string */ public function getName() { return $this->name;
}
/**
* Set address
*
* @param string $address * * @return Student */ public function setAddress($address) {
$this->address = $address;
return $this; } /** * Get address * * @return string */ public function getAddress() { return $this->address;
}
}
Etapa 6: Validação do mapa
Depois de criar entidades, você deve validar os mapeamentos usando o seguinte comando.
php bin/console doctrine:schema:validate
Isso produzirá o seguinte resultado -
[Mapping] OK - The mapping files are correct.
[Database] FAIL - The database schema is not in sync with the current mapping file
Como não criamos a tabela de alunos, a entidade está fora de sincronia. Vamos criar a tabela de alunos usando o comando Symfony na próxima etapa.
Etapa 7: criar um esquema
O Doctrine pode criar automaticamente todas as tabelas de banco de dados necessárias para a entidade Aluno. Isso pode ser feito usando o seguinte comando.
php bin/console doctrine:schema:update --force
Depois de executar o comando, você pode ver a seguinte resposta.
Updating database schema...
Database schema updated successfully! "1" query was executed
Este comando compara a aparência do banco de dados com a aparência real e executa as instruções SQL necessárias para atualizar o esquema do banco de dados para onde deveria estar.
Agora, valide novamente o esquema usando o seguinte comando.
php bin/console doctrine:schema:validate
Isso produzirá o seguinte resultado -
[Mapping] OK - The mapping files are correct.
[Database] OK - The database schema is in sync with the mapping files
Etapa 8: Getter e setter
Conforme visto na seção Vincular uma entidade, o comando a seguir gera todos os getters e setters para a classe Aluno.
$ php bin/console doctrine:generate:entities AppBundle/Entity/Student
Etapa 9: Persistir Objetos no Banco de Dados
Agora, mapeamos a entidade Student para sua tabela Student correspondente. Agora devemos ser capazes de persistir os objetos de Aluno no banco de dados. Adicione o seguinte método ao StudentController do pacote.
StudentController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Entity\Student;
class StudentController extends Controller {
/**
* @Route("/student/add")
*/
public function addAction() {
$stud = new Student();
$stud->setName('Adam'); $stud->setAddress('12 north street');
$doct = $this->getDoctrine()->getManager();
// tells Doctrine you want to save the Product
$doct->persist($stud);
//executes the queries (i.e. the INSERT query)
$doct->flush(); return new Response('Saved new student with id ' . $stud->getId());
}
}
Aqui, acessamos o gerenciador de doutrina usando o método getManager () através de getDoctrine () do controlador de base e então persistimos o objeto atual usando o método persist () do gerenciador de doutrina. persist() método adiciona o comando à fila, mas o flush() método faz o trabalho real (persistindo o objeto de aluno).
Etapa 10: Buscar objetos do banco de dados
Crie uma função em StudentController que exibirá os detalhes do aluno.
StudentController.php
/**
* @Route("/student/display")
*/
public function displayAction() {
$stud = $this->getDoctrine()
->getRepository('AppBundle:Student')
->findAll();
return $this->render('student/display.html.twig', array('data' => $stud));
}
Etapa 11: criar uma visualização
Vamos criar uma visão que aponta para a ação de exibição. Vá para o diretório de visualizações e crie um arquivo “display.html.twig”. Adicione as seguintes alterações no arquivo.
display.html.twig
<style>
.table { border-collapse: collapse; }
.table th, td {
border-bottom: 1px solid #ddd;
width: 250px;
text-align: left;
align: left;
}
</style>
<h2>Students database application!</h2>
<table class = "table">
<tr>
<th>Name</th>
<th>Address</th>
</tr>
{% for x in data %}
<tr>
<td>{{ x.Name }}</td>
<td>{{ x.Address }}</td>
</tr>
{% endfor %}
</table>
Você pode obter o resultado solicitando a URL “http: // localhost: 8000 / student / display” em um navegador.
Ele produzirá a seguinte saída na tela -
Etapa 12: Atualizar um objeto
Para atualizar um objeto em StudentController, crie uma ação e adicione as seguintes alterações.
/**
* @Route("/student/update/{id}")
*/
public function updateAction($id) { $doct = $this->getDoctrine()->getManager(); $stud = $doct->getRepository('AppBundle:Student')->find($id);
if (!$stud) { throw $this->createNotFoundException(
'No student found for id '.$id ); } $stud->setAddress('7 south street');
$doct->flush();
return new Response('Changes updated!');
}
Agora, solicite a URL “http: // localhost: 8000 / Student / update / 1” e ele produzirá o seguinte resultado.
Ele produzirá a seguinte saída na tela -
Etapa 13: Excluir um objeto
Excluir um objeto é semelhante e requer uma chamada ao método remove () do gerenciador de entidade (doutrina).
Isso pode ser feito usando o seguinte comando.
/**
* @Route("/student/delete/{id}")
*/
public function deleteAction($id) {
$doct = $this->getDoctrine()->getManager();
$stud = $doct->getRepository('AppBundle:Student')->find($id); if (!$stud) {
throw $this->createNotFoundException('No student found for id '.$id);
}
$doct->remove($stud);
$doct->flush();
return new Response('Record deleted!');
}
Symfony fornece várias tags embutidas para lidar com formulários HTML de forma fácil e segura. O componente Form do Symfony executa o processo de criação e validação de formulários. Ele conecta o modelo e a camada de visualização. Ele fornece um conjunto de elementos de formulário para criar um formulário html completo a partir de modelos predefinidos. Este capítulo explica sobre o Formulários em detalhes.
Campos do Formulário
Symfony framework API suporta um grande grupo de tipos de campo. Vamos examinar cada um dos tipos de campo em detalhes.
FormType
É usado para gerar um formulário no framework Symfony. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
// ...
$builder = $this->createFormBuilder($studentinfo);
$builder
->add('title', TextType::class);
Aqui, $studentinfo é uma entidade do tipo Aluno. createFormBuilderé usado para criar um formulário HTML. método add é usado paraadd elementos de entrada dentro do formulário. title refere-se à propriedade do título do aluno. TextType::classrefere-se ao campo de texto html. Symfony fornece classes para todos os elementos html.
Tipo de texto
O campo TextType representa o campo de texto de entrada mais básico. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\TextType;
$builder->add(‘name’, TextType::class);
Aqui, o nome é mapeado com uma entidade.
TextareaType
Renderiza um elemento HTML textarea. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
$builder->add('body', TextareaType::class, array(
'attr' => array('class' => 'tinymce'),
));
EmailType
O campo EmailType é um campo de texto que é processado usando a tag de email HTML5. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\EmailType;
$builder->add('token', EmailType::class, array(
'data' => 'abcdef', ));
PasswordType
O campo PasswordType renderiza uma caixa de texto de senha de entrada. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
$bulder->add('password', PasswordType::class);
RangeType
O campo RangeType é um controle deslizante processado usando a tag de intervalo HTML5. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\RangeType;
// ...
$builder->add('name', RangeType::class, array(
'attr' => array(
'min' => 100,
'max' => 200
)
));
PercentType
O PercentType renderiza um campo de texto de entrada e é especializado em lidar com dados de porcentagem. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\PercentType;
// ...
$builder->add('token', PercentType::class, array(
'data' => 'abcdef',
));
DateType
Renderiza um formato de data. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\DateType;
// ...
$builder->add(‘joined’, DateType::class, array(
'widget' => 'choice',
));
Aqui, Widget é a maneira básica de renderizar um campo.
Ele executa a seguinte função.
choice- Processa três entradas selecionadas. A ordem das seleções é definida na opção de formato.
text - Renderiza uma entrada de três campos do tipo texto (mês, dia, ano).
single_text- Renderiza uma única entrada do tipo data. A entrada do usuário é validada com base na opção de formato.
CheckboxType
Cria uma única caixa de seleção de entrada. Isso sempre deve ser usado para um campo que possui um valor booleano. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
// ...
$builder-<add(‘sports’, CheckboxType::class, array(
'label' =< ‘Are you interested in sports?’,
'required' =< false,
));
RadioType
Cria um único botão de opção. Se o botão de opção for selecionado, o campo será definido com o valor especificado. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\RadioType;
// ...
$builder->add('token', RadioType::class, array(
'data' => 'abcdef',
));
Observe que, os botões de opção não podem ser desmarcados, o valor só muda quando outro botão de opção com o mesmo nome é marcado.
RepeatedType
Este é um campo especial “grupo”, que cria dois campos idênticos cujos valores devem coincidir. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
// ...
$builder->add('password', RepeatedType::class, array(
'type' => PasswordType::class,
'invalid_message' => 'The password fields must match.',
'options' => array('attr' => array('class' => 'password-field')),
'required' => true,
'first_options' => array('label' => 'Password'),
'second_options' => array('label' => 'Repeat Password'),
));
Isso é usado principalmente para verificar a senha ou e-mail do usuário.
ButtonType
Um botão clicável simples. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
// ...
$builder->add('save', ButtonType::class, array(
'attr' => array('class' => 'save'),
));
ResetType
Um botão que redefine todos os campos para seus valores iniciais. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\ResetType;
// ...
$builder->add('save', ResetType::class, array(
'attr' => array('class' => 'save'),
));
ChoiceType
Um campo multifuncional é usado para permitir que o usuário “escolha” uma ou mais opções. Ele pode ser renderizado como uma marca de seleção, botões de rádio ou caixas de seleção. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add(‘gender’, ChoiceType::class, array(
'choices' => array(
‘Male’ => true,
‘Female’ => false,
),
));
SubmitType
Um botão de envio é usado para enviar dados do formulário. Sua sintaxe é a seguinte -
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
// ...
$builder->add('save', SubmitType::class, array(
'attr' => array('class' => 'save'),
))
Função auxiliar de formulário
Funções auxiliares de formulário são funções de ramificação usadas para criar formulários facilmente em modelos.
form_start
Retorna uma tag de formulário HTML que aponta para uma ação, rota ou URL válida. Sua sintaxe é a seguinte -
{{ form_start(form, {'attr': {'id': 'form_person_edit'}}) }}
form_end
Fecha a tag de formulário HTML criada usando form_start. Sua sintaxe é a seguinte -
{{ form_end(form) }}
área de texto
Retorna uma tag textarea, opcionalmente envolvida com um editor de JavaScript rich text embutido.
caixa de seleção
Retorna uma tag de entrada compatível com XHTML com type = “checkbox”. Sua sintaxe é a seguinte -
echo checkbox_tag('choice[]', 1);
echo checkbox_tag('choice[]', 2);
echo checkbox_tag('choice[]', 3);
echo checkbox_tag('choice[]', 4);
input_password_tag
Retorna uma tag de entrada compatível com XHTML com type = “senha”. Sua sintaxe é a seguinte -
echo input_password_tag('password');
echo input_password_tag('password_confirm');
input_tag
Retorna uma tag de entrada compatível com XHTML com type = “text”. Sua sintaxe é a seguinte -
echo input_tag('name');
rótulo
Retorna uma etiqueta de rótulo com o parâmetro especificado.
botao de radio
Retorna uma tag de entrada compatível com XHTML com type = “radio”. Sua sintaxe é a seguinte -
echo ' Yes '.radiobutton_tag(‘true’, 1);
echo ' No '.radiobutton_tag(‘false’, 0);
reset_tag
Retorna uma tag de entrada compatível com XHTML com type = “reset”. Sua sintaxe é a seguinte -
echo reset_tag('Start Over');
selecionar
Retorna uma tag de seleção preenchida com todos os países do mundo. Sua sintaxe é a seguinte -
echo select_tag(
'url', options_for_select($url_list),
array('onChange' => 'Javascript:this.form.submit();'));
enviar
Retorna uma tag de entrada compatível com XHTML com type = “submit”. Sua sintaxe é a seguinte -
echo submit_tag('Update Record');
Na próxima seção, aprenderemos como criar um formulário usando campos de formulário.
Formulário de inscrição do aluno
Vamos criar um formulário simples de detalhes do aluno usando os campos do formulário Symfony. Para fazer isso, devemos seguir as seguintes etapas -
Etapa 1: Crie um aplicativo Symfony
Crie um aplicativo Symfony, formsample, usando o seguinte comando.
symfony new formsample
As entidades geralmente são criadas no diretório “src / AppBundle / Entity /“.
Etapa 2: Criar uma Entidade
Crie o arquivo “StudentForm.php” no diretório “src / AppBundle / Entity /”. Adicione as seguintes alterações no arquivo.
StudentForm.php
<?php
namespace AppBundle\Entity;
class StudentForm {
private $studentName;
private $studentId; public $password;
private $address; public $joined;
public $gender; private $email;
private $marks; public $sports;
public function getStudentName() {
return $this->studentName; } public function setStudentName($studentName) {
$this->studentName = $studentName;
}
public function getStudentId() {
return $this->studentId; } public function setStudentId($studentid) {
$this->studentid = $studentid;
}
public function getAddress() {
return $this->address; } public function setAddress($address) {
$this->address = $address;
}
public function getEmail() {
return $this->email; } public function setEmail($email) {
$this->email = $email;
}
public function getMarks() {
return $this->marks; } public function setMarks($marks) {
$this->marks = $marks;
}
}
Etapa 3: Adicionar um StudentController
Vá para o diretório “src / AppBundle / Controller”, crie o arquivo “StudentController.php” e adicione o seguinte código nele.
StudentController.php
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\StudentForm;
use AppBundle\Form\FormValidationType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RangeType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\PercentType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
class StudentController extends Controller {
/**
* @Route("/student/new")
*/
public function newAction(Request $request) { $stud = new StudentForm();
$form = $this->createFormBuilder($stud) ->add('studentName', TextType::class) ->add('studentId', TextType::class) ->add('password', RepeatedType::class, array( 'type' => PasswordType::class, 'invalid_message' => 'The password fields must match.', 'options' => array('attr' => array('class' => 'password-field')), 'required' => true, 'first_options' => array('label' => 'Password'), 'second_options' => array('label' => 'Re-enter'), )) ->add('address', TextareaType::class) ->add('joined', DateType::class, array( 'widget' => 'choice', )) ->add('gender', ChoiceType::class, array( 'choices' => array( 'Male' => true, 'Female' => false, ), )) ->add('email', EmailType::class) ->add('marks', PercentType::class) ->add('sports', CheckboxType::class, array( 'label' => 'Are you interested in sports?', 'required' => false, )) ->add('save', SubmitType::class, array('label' => 'Submit')) ->getForm(); return $this->render('student/new.html.twig', array(
'form' => $form->createView(),
));
}
}
Etapa 4: renderizar a vista
Vá para o diretório “app / Resources / views / student /“, crie o arquivo “new.html.twig” e adicione as seguintes alterações nele.
{% extends 'base.html.twig' %}
{% block stylesheets %}
<style>
#simpleform {
width:600px;
border:2px solid grey;
padding:14px;
}
#simpleform label {
font-size:14px;
float:left;
width:300px;
text-align:right;
display:block;
}
#simpleform span {
font-size:11px;
color:grey;
width:100px;
text-align:right;
display:block;
}
#simpleform input {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:24px;
width:250px;
margin: 0 0 10px 10px;
}
#simpleform textarea {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:120px;
width:250px;
margin: 0 0 20px 10px;
}
#simpleform select {
margin: 0 0 20px 10px;
}
#simpleform button {
clear:both;
margin-left:250px;
background: grey;
color:#FFFFFF;
border:solid 1px #666666;
font-size:16px;
}
</style>
{% endblock %}
{% block body %}
<h3>Student details:</h3>
<div id="simpleform">
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</div>
{% endblock %}
Agora solicite a url, “http: // localhost: 8000 / student / new” e produz o seguinte resultado.
Resultado
A validação é o aspecto mais importante ao projetar um aplicativo. Ele valida os dados recebidos. Este capítulo explica detalhadamente a validação do formulário.
Restrições de validação
O validador é projetado para validar objetos contra restrições. Se você validar um objeto, simplesmente mapeie uma ou mais restrições para sua classe e, em seguida, passe-o para o serviço de validação. Por padrão, ao validar um objeto, todas as restrições da classe correspondente serão verificadas para ver se elas realmente passam ou não. Symfony suporta as seguintes restrições de validação notáveis.
NotBlank
Valida se uma propriedade não está em branco. Sua sintaxe é a seguinte -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\NotBlank()
*/
protected $studentName;
}
Essa restrição NotBlank garante que a propriedade studentName não fique em branco.
Não nulo
Valida se um valor não é estritamente igual a nulo. Sua sintaxe é a seguinte -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\NotNull()
*/
protected $studentName;
}
O email
Valida se um valor é um endereço de e-mail válido. Sua sintaxe é a seguinte -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\Email(
* message = "The email '{{ value }}' is not a valid email.",
* checkMX = true
* )
*/
protected $email;
}
É nulo
Valida se um valor é exatamente igual a nulo. Sua sintaxe é a seguinte -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\IsNull()
*/
protected $studentName;
}
comprimento
Valida se um determinado comprimento de string está entre algum valor mínimo e máximo. Sua sintaxe é a seguinte -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\Length(
* min = 5,
* max = 25,
* minMessage = "Your first name must be at least {{ limit }} characters long",
* maxMessage = "Your first name cannot be longer than {{ limit }} characters"
* )
*/
protected $studentName;
}
Alcance
Valida se um determinado número está entre algum número mínimo e máximo. Sua sintaxe é a seguinte -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\Range(
* min = 40,
* max = 100,
* minMessage = "You must be at least {{ limit }} marks”,
* maxMessage = "Your maximum {{ limit }} marks”
* )
*/
protected $marks;
}
Encontro
Valida se um valor é uma data válida. Ele segue um formato YYYY-MM-DD válido. Sua sintaxe é a seguinte -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\Date()
*/
protected $joinedAt;
}
Escolha
Essa restrição é usada para garantir que o valor fornecido seja um de um determinado conjunto de opções válidas. Ele também pode ser usado para validar se cada item em uma matriz de itens é uma dessas opções válidas. Sua sintaxe é a seguinte -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\Choice(choices = {"male", "female"}, message = "Choose a valid gender.")
*/
protected $gender;
}
Senha do usuário
Isso valida que um valor de entrada é igual à senha do usuário autenticado atual. Isso é útil em uma forma em que os usuários podem alterar sua senha, mas precisam inserir a senha antiga por segurança. Sua sintaxe é a seguinte -
namespace AppBundle\Form\Model;
use Symfony\Component\Security\Core\Validator\Constraints as SecurityAssert;
class ChangePassword {
/**
* @SecurityAssert\UserPassword(
* message = "Wrong value for your current password"
* )
*/
protected $oldPassword;
}
Essa restrição valida se a senha antiga corresponde à senha atual do usuário.
Exemplo de Validação
Vamos escrever um exemplo de aplicativo simples para entender o conceito de validação.
Step 1 - Crie um aplicativo de validação.
Crie um aplicativo Symfony, validationsample, usando o seguinte comando.
symfony new validationsample
Step 2 - Crie uma entidade chamada, FormValidation no arquivo “FormValidation.php” debaixo de “src/AppBundle/Entity/”diretório. Adicione as seguintes alterações no arquivo.
FormValidation.php
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class FormValidation {
/**
* @Assert\NotBlank()
*/
protected $name; /** * @Assert\NotBlank() */ protected $id;
protected $age; /** * @Assert\NotBlank() */ protected $address;
public $password; /** * @Assert\Email( * message = "The email '{{ value }}' is not a valid email.", * checkMX = true * ) */ protected $email;
public function getName() {
return $this->name; } public function setName($name) {
$this->name = $name;
}
public function getId() {
return $this->id; } public function setId($id) {
$this->id = $id;
}
public function getAge() {
return $this->age; } public function setAge($age) {
$this->age = $age;
}
public function getAddress() {
return $this->address; } public function setAddress($address) {
$this->address = $address;
}
public function getEmail() {
return $this->email; } public function setEmail($email) {
$this->email = $email;
}
}
Step 3 - Crie um validateActionmétodo em StudentController. Mover para o diretório“src/AppBundle/Controller”, crio “studentController.php” arquivo e adicione o seguinte código nele.
StudentController.php
use AppBundle\Entity\FormValidation;
/**
* @Route("/student/validate")
*/
public function validateAction(Request $request) { $validate = new FormValidation();
$form = $this->createFormBuilder($validate) ->add('name', TextType::class) ->add('id', TextType::class) ->add('age', TextType::class) ->add('address', TextType::class) ->add('email', TextType::class) ->add('save', SubmitType::class, array('label' => 'Submit')) ->getForm(); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $validate = $form->getData(); return new Response('Form is validated.'); } return $this->render('student/validate.html.twig', array(
'form' => $form->createView(),
));
}
Aqui, criamos o formulário usando classes de formulário e, em seguida, manipulamos o formulário. Se o formulário for enviado e for válido, uma mensagem de formulário validado será exibida. Caso contrário, o formulário padrão é mostrado.
Step 4- Crie uma visão para a ação criada acima em StudentController. Mover para o diretório“app/Resources/views/student/”. Crio“validate.html.twig” arquivo e adicione o seguinte código nele.
{% extends 'base.html.twig' %}
{% block stylesheets %}
<style>
#simpleform {
width:600px;
border:2px solid grey;
padding:14px;
}
#simpleform label {
font-size:14px;
float:left;
width:300px;
text-align:right;
display:block;
}
#simpleform span {
font-size:11px;
color:grey;
width:100px;
text-align:right;
display:block;
}
#simpleform input {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:24px;
width:250px;
margin: 0 0 10px 10px;
}
#simpleform textarea {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:120px;
width:250px;
margin: 0 0 20px 10px;
}
#simpleform select {
margin: 0 0 20px 10px;
}
#simpleform button {
clear:both;
margin-left:250px;
background: grey;
color:#FFFFFF;
border:solid 1px #666666;
font-size:16px;
}
</style>
{% endblock %}
{% block body %}
<h3>Student form validation:</h3>
<div id = "simpleform">
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</div>
{% endblock %}
Aqui, usamos tags de formulário para criar o formulário.
Step 5 - Por fim, execute o aplicativo, http://localhost:8000/student/validate.
Resultado: Página Inicial
Resultado: Página Final
O componente Symfony Form fornece FileTypeclasse para lidar com o elemento de entrada do arquivo. Ele permite o upload fácil de imagens, documentos, etc. Vamos aprender como criar um aplicativo simples usando o recurso FileType.
Step 1 - Crie um novo aplicativo, fileuploadsample usando o seguinte comando.
symfony new fileuploadsample
Step 2 - Crie uma entidade, Student, tendo nome, idade e foto conforme mostrado no código a seguir.
src / AppBundle / Entity / Student.php
<?php
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert; class Student {
/**
* @Assert\NotBlank()
*/
private $name;
/**
* @Assert\NotBlank()
*/
private $age; /** * @Assert\NotBlank(message="Please, upload the photo.") * @Assert\File(mimeTypes={ "image/png", "image/jpeg" }) */ private $photo;
public function getName() {
return $this->name; } public function setName($name) {
$this->name = $name;
return $this; } public function getAge() { return $this->age;
}
public function setAge($age) { $this->age = $age; return $this;
}
public function getPhoto() {
return $this->photo; } public function setPhoto($photo) {
$this->photo = $photo;
return $this;
}
}
Aqui, especificamos Arquivo para a propriedade da foto.
Step 3 - Crie o controlador de aluno, StudentController e um novo método, addAction, conforme mostrado no código a seguir.
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\Student;
use AppBundle\Form\FormValidationType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
class StudentController extends Controller {
/**
* @Route("/student/new")
*/
public function newAction(Request $request) {
$student = new Student(); $form = $this->createFormBuilder($student)
->add('name', TextType::class)
->add('age', TextType::class)
->add('photo', FileType::class, array('label' => 'Photo (png, jpeg)'))
->add('save', SubmitType::class, array('label' => 'Submit'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$file = $student->getPhoto();
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($this->getParameter('photos_directory'), $fileName); $student->setPhoto($fileName); return new Response("User photo is successfully uploaded."); } else { return $this->render('student/new.html.twig', array(
'form' => $form->createView(),
));
}
}
}
Aqui, criamos o formulário para entidade de estudante e tratamos da solicitação. Quando o formulário é enviado pelo usuário e é válido, movemos o arquivo enviado para o nosso diretório de upload usando o parâmetro,photos_directory.
Step 4 - Crie a vista, new.html.twig, usando as seguintes tags de formulário.
{% extends 'base.html.twig' %}
{% block javascripts %}
<script language = "javascript" src = "https://code.jquery.com/jquery-2.2.4.min.js"></script>
{% endblock %}
{% block stylesheets %}
<style>
#simpleform {
width:600px;
border:2px solid grey;
padding:14px;
}
#simpleform label {
font-size:12px;
float:left;
width:300px;
text-align:right;
display:block;
}
#simpleform span {
font-size:11px;
color:grey;
width:100px;
text-align:right;
display:block;
}
#simpleform input {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:grey;
height:24px;
width:250px;
margin: 0 0 20px 10px;
}
#simpleform button {
clear:both;
margin-left:250px;
background:grey;
color:#FFFFFF;
border:solid 1px #666666;
font-size:16px;
}
</style>
{% endblock %}
{% block body %}
<h3>Student form</h3>
<div id="simpleform">
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</div>
{% endblock %}
Step 5 - Defina o parâmetro, photos_directory no arquivo de configuração de parâmetro da seguinte maneira.
app / config / config.xml
parameters: photos_directory: '%kernel.root_dir%/../web/uploads/photos'
Step 6- Agora, execute o aplicativo e abra http: // localhost: 8000 / student / new e carregue uma foto. A foto enviada será enviada para o photos_directory e uma mensagem de sucesso será exibida.
Resultado: Página Inicial
Resultado: página de upload de arquivo
AJAX é uma tecnologia moderna em programação web. Ele fornece opções para enviar e receber dados em uma página da Web de forma assíncrona, sem atualizar a página. Vamos aprender programação Symfony AJAX neste capítulo.
O framework Symfony oferece opções para identificar se o tipo de solicitação é AJAX ou não. A classe Request do componente Symfony HttpFoundation tem um método, isXmlHttpRequest () para este propósito. Se uma solicitação AJAX for feita, o método isXmlHttpRequest () do objeto de solicitação atual retornará verdadeiro, caso contrário, será falso.
Este método é usado para lidar com uma solicitação AJAX corretamente no lado do servidor.
if ($request->isXmlHttpRequest()) {
// Ajax request
} else {
// Normal request
}
Symfony também fornece uma classe de resposta baseada em JSON, JsonResponse, para criar a resposta no formato JSON. Podemos combinar esses dois métodos para criar um aplicativo da web baseado em AJAX simples e limpo.
AJAX - Exemplo de Trabalho
Vamos adicionar uma nova página, student/ajax no aplicativo do aluno e tente buscar as informações do aluno de forma assíncrona.
Step 1 - Adicione o método ajaxAction em StudentController (src / AppBundle / Controller / StudentController.php).
/**
* @Route("/student/ajax")
*/
public function ajaxAction(Request $request) { $students = $this->getDoctrine() ->getRepository('AppBundle:Student') ->findAll(); if ($request->isXmlHttpRequest() || $request->query->get('showJson') == 1) { $jsonData = array();
$idx = 0; foreach($students as $student) { $temp = array(
'name' => $student->getName(), 'address' => $student->getAddress(),
);
$jsonData[$idx++] = $temp; } return new JsonResponse($jsonData);
} else {
return $this->render('student/ajax.html.twig');
}
}
Aqui, se a solicitação for AJAX, buscamos informações do aluno, codificamos como JSON e as retornamos usando JsonResponseobjeto. Caso contrário, apenas renderizaremos a visualização correspondente.
Step 2 - Crie um arquivo de visualização ajax.html.twig no diretório de visualizações do aluno, app/Resources/views/student/ e adicione o seguinte código.
{% extends 'base.html.twig' %}
{% block javascripts %}
<script language = "javascript"
src = "https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script language = "javascript">
$(document).ready(function(){
$("#loadstudent").on("click", function(event){ $.ajax({
url: '/student/ajax',
type: 'POST',
dataType: 'json',
async: true,
success: function(data, status) {
var e = $('<tr><th>Name</th><th>Address</th></tr>'); $('#student').html('');
$('#student').append(e); for(i = 0; i < data.length; i++) { student = data[i]; var e = $('<tr><td id = "name"></td><td id = "address"></td></tr>');
$('#name', e).html(student['name']); $('#address', e).html(student['address']);
$('#student').append(e);
}
},
error : function(xhr, textStatus, errorThrown) {
alert('Ajax request failed.');
}
});
});
});
</script>
{% endblock %}
{% block stylesheets %}
<style>
.table { border-collapse: collapse; }
.table th, td {
border-bottom: 1px solid #ddd;
width: 250px;
text-align: left;
align: left;
}
</style>
{% endblock %}
{% block body %}
<a id = "loadstudent" href = "#">Load student information</a>
</br>
</br>
<table class = "table">
<tbody id = "student"></tbody>
</table>
{% endblock %}
Aqui, criamos uma tag âncora (id: loadstudent) para carregar as informações do aluno usando a chamada AJAX. A chamada AJAX é feita usando JQuery. O evento anexado à tag loadstudent é ativado quando um usuário clica nele. Em seguida, ele buscará as informações do aluno usando a chamada AJAX e gerará o código HTML necessário de forma dinâmica.
Step 3- Por fim, execute o aplicativo, http://localhost:8000/student/ajax e clique na guia Carregar âncora de informações do aluno.
Resultado: Página Inicial
Resultado: Página com Informações do Aluno
O componente Symfony HttpFoundation fornece cookies e gerenciamento de sessão de uma maneira orientada a objetos. Cookiefornece armazenamento de dados do lado do cliente e suporta apenas uma pequena quantidade de dados. Normalmente, é de 2 KB por domínio e depende do navegador.Sessionfornece armazenamento de dados do lado do servidor e suporta uma grande quantidade de dados. Vamos ver como criar um cookie e uma sessão em um aplicativo da web Symfony.
Bolacha
Symfony fornece a classe Cookie para criar um item de cookie. Vamos criar uma cor de cookie, que expira em 24 horas com valorblue. O parâmetro do construtor da classe cookie é o seguinte.
- nome (tipo: string) - nome do cookie
- valor (tipo: string) - valor do cookie
- expire (type: integer / string / datetime) - informações de expiração
- caminho (tipo: string) - o caminho do servidor no qual o cookie está disponível
- domínio (tipo: string) - o endereço de domínio no qual o cookie está disponível
- seguro (tipo: booleano) - se o cookie precisa ser transmitido na conexão HTTPS
- httpOnly (type: boolean) - se o cookie está disponível apenas no protocolo HTTP
use Symfony\Component\HttpFoundation\Cookie;
$cookie = new Cookie('color', 'green', strtotime('tomorrow'), '/',
'somedomain.com', true, true);
Symfony também oferece a seguinte opção de criação de cookie baseada em string.
$cookie = Cookie::fromString('color = green; expires = Web, 4-May-2017 18:00:00 +0100;
path=/; domain = somedomain.com; secure; httponly');
Agora, o cookie criado precisa ser anexado ao cabeçalho do objeto de resposta http da seguinte maneira.
$response->headers->setCookie($cookie);
Para obter o cookie, podemos usar o objeto Request da seguinte maneira.
$cookie = $request->cookie->get('color');
Aqui, request->cookie é do tipo PropertyBag e podemos manipulá-lo usando métodos PropertyBag.
Sessão
Symfony fornece uma classe Session que implementa a interface SessionInterface. As APIs de sessão importantes são as seguintes,
start - Inicia a sessão.
Session $session = new Session();
$session->start();
invalidate - Limpa todos os dados da sessão e regenera o ID da sessão.
set - Armazena dados na sessão usando uma chave.
$session->set('key', 'value');
Podemos usar qualquer dado no valor da sessão, seja em um inteiro simples para objetos complexos.
get - Obtém dados da sessão usando a chave.
$val = $session->get('key');
remove - Remove uma chave da sessão.
clear - Remove os dados de uma sessão.
FlashBag
A sessão oferece outro recurso útil chamado FlashBag. É um contêiner especial dentro da sessão que mantém os dados apenas durante o redirecionamento da página. É útil em redirecionamentos http. Antes de redirecionar para uma página, os dados podem ser salvos em FlashBag em vez de um contêiner de sessão normal e os dados salvos estarão disponíveis na próxima solicitação (a página redirecionada). Então, os dados serão invalidados automaticamente.
$session->getFlashBag()->add('key', 'value'); $session->getFlashBag()->get('key');
Internationalization (i18n) e Localization (l10n)ajudam a aumentar a cobertura do cliente de um aplicativo da web. Symfony fornece um excelente componente de tradução para este propósito. Vamos aprender como usar o componente Tradução neste capítulo.
Habilitar tradução
Por padrão, o framework web Symfony desabilita o componente Tradução. Para habilitá-lo, adicione a seção do tradutor no arquivo de configuração, app / config / config.yml.
framework: translator: { fallbacks: [en] }
Arquivo de Tradução
O componente de tradução traduz o texto usando o arquivo de recursos de tradução. O arquivo de recurso pode ser escrito em PHP, XML e YAML. A localização padrão do arquivo de recurso éapp/Resources/translations. Ele precisa de um arquivo de recursos por idioma. Vamos escrever um arquivo de recurso,messages.fr.yml para o idioma francês.
I love Symfony: J'aime Symfony
I love %name%: J'aime %name%
O texto do lado esquerdo está em inglês e o texto do lado direito está em francês. A segunda linha mostra o uso de um espaço reservado. As informações do espaço reservado podem ser adicionadas dinamicamente ao usar a tradução.
Uso
Por padrão, a localidade padrão do sistema do usuário será definida pela estrutura da web Symfony. Se o local padrão não estiver configurado no aplicativo da web, ele voltará para o inglês. O local também pode ser definido no URL da página da web.
http://www.somedomain.com/en/index
http://www.somedomain.com/fr/index
Vamos usar a localidade baseada em URL em nosso exemplo para entender facilmente o conceito de tradução. Crie uma nova função,translationSample com rota /{_locale}/translation/sampleem DefaultController (src / AppBundle / Controller / DefaultController.php). {_locale} é uma palavra-chave especial no Symfony para especificar o local padrão.
/**
* @Route("/{_locale}/translation/sample", name="translation_sample")
*/
public function translationSample() {
$translated = $this->get('translator')->trans('I love Symfony');
return new Response($translated);
}
Aqui, usamos o método de tradução, trans, que traduz o conteúdo para o local atual. Nesse caso, o local atual é a primeira parte da URL. Agora, execute o aplicativo e carregue a página,http://localhost:8000/en/translation/sample no navegador.
O resultado será "I love Symfony" em inglês. Agora, carregue a páginahttp://localhost:8000/fr/translation/sampleno navegador. Agora, o texto será traduzido para o francês da seguinte maneira.
Da mesma forma, o modelo twig tem {% trans %}bloco para habilitar o recurso de tradução nas visualizações também. Para verificar isso, adicione uma nova função,translationTwigSample e a visualização correspondente em app/Resources/views/translate/index.html.twig.
/**
* @Route("/{_locale}/translation/twigsample", name="translation_twig_sample")
*/
public function translationTwigSample() {
return $this->render('translate/index.html.twig');
}
Visão
{% extends 'base.html.twig' %}
{% block body %}
{% trans with {'%name%': 'Symfony'} from "app" into "fr" %}I love %name% {% endtrans %}
{% endblock %}
Aqui, o bloco trans especifica o espaço reservado também. O resultado da página é o seguinte.
O registro é muito importante para um aplicativo da web. Os aplicativos da Web são usados por centenas a milhares de usuários ao mesmo tempo. Para obter uma prévia dos acontecimentos em um aplicativo da web, o registro deve estar ativado. Sem o registro, o desenvolvedor não poderá encontrar o status do aplicativo. Vamos considerar que um cliente final relata um problema ou um stackholder do projeto relata um problema de desempenho; então, a primeira ferramenta para o desenvolvedor é o Logging. Ao verificar as informações do log, pode-se ter uma ideia sobre o possível motivo do problema.
Symfony fornece um excelente recurso de registro integrando a estrutura de registro Monolog. Monologé um padrão de fato para registro em ambiente PHP. O registro é habilitado em todos os aplicativos da Web Symfony e é fornecido como um Serviço. Basta obter o objeto logger usando o controlador básico da seguinte maneira.
$logger = $this->get('logger');
Depois que o objeto logger é buscado, podemos registrar informações, avisos e erros usando-o.
$logger->info('Hi, It is just a information. Nothing to worry.'); $logger->warn('Hi, Something is fishy. Please check it.');
$logger->error('Hi, Some error occured. Check it now.'); $logger->critical('Hi, Something catastrophic occured. Hurry up!');
Arquivo de configuração do aplicativo da web Symfony app/config/config.ymltem uma seção separada para a estrutura do logger. Ele pode ser usado para atualizar o funcionamento da estrutura do logger.
A funcionalidade de e-mail é o recurso mais solicitado em uma estrutura da web. Mesmo um aplicativo simples terá um formulário de contato e os detalhes serão enviados para a administração do sistema por e-mail. Symfony integraSwiftMailer, o melhor módulo de email em PHP disponível no mercado. O SwiftMailer é uma excelente biblioteca de e-mail que oferece uma opção de enviar e-mail usando o sendmail da velha escola para o aplicativo de correio mais recente baseado em nuvem.
Vamos entender o conceito de mailing no Symfony enviando um simples e-mail. Antes de escrever a funcionalidade do mailer, defina os detalhes de configuração do mailer emapp/config/parameters.yml. Em seguida, crie uma nova função,MailerSample dentro DefaultController e adicione o seguinte código.
/**
* @Route("/mailsample/send", name="mail_sample_send")
*/
public function MailerSample() {
$message = \Swift_Message::newInstance() ->setSubject('Hello Email') ->setFrom('[email protected]') ->setTo('[email protected]') ->setBody( $this->renderView('Emails/sample.html.twig'), 'text/html' );
$this->get('mailer')->send($message);
return new Response("Mail send");
}
Aqui, simplesmente criamos uma mensagem usando SwiftMailer componente e renderizou o corpo da mensagem usando Twigmodelo. Então, buscamos o componente mailer do controladorgetmétodo com a chave 'mailer'. Finalmente, enviamos a mensagem usandosend método e imprimiu o Mail send mensagem.
Agora, execute a página, http://localhost:8000/mailsample/send e o resultado seria o seguinte.
O teste de unidade é essencial para o desenvolvimento contínuo em grandes projetos. Os testes de unidade irão testar automaticamente os componentes do seu aplicativo e alertá-lo quando algo não estiver funcionando. O teste de unidade pode ser feito manualmente, mas geralmente é automatizado.
PHPUnit
O framework Symfony se integra ao framework de teste de unidade PHPUnit. Para escrever um teste de unidade para o framework Symfony, precisamos configurar o PHPUnit. Se o PHPUnit não estiver instalado, faça o download e instale-o. Se estiver instalado corretamente, você verá a seguinte resposta.
phpunit
PHPUnit 5.1.3 by Sebastian Bergmann and contributors
Teste de unidade
Um teste de unidade é um teste contra uma única classe PHP, também chamada de unidade.
Crie uma classe Student no diretório Libs / do AppBundle. Está localizado em“src/AppBundle/Libs/Student.php”.
Student.php
namespace AppBundle\Libs;
class Student {
public function show($name) { return $name. “ , Student name is tested!”;
}
}
Agora, crie um arquivo StudentTest no diretório “tests / AppBundle / Libs”.
StudentTest.php
namespace Tests\AppBundle\Libs;
use AppBundle\Libs\Student;
class StudentTest extends \PHPUnit_Framework_TestCase {
public function testShow() {
$stud = new Student(); $assign = $stud->show(‘stud1’); $check = “stud1 , Student name is tested!”;
$this->assertEquals($check, $assign);
}
}
Teste de corrida
Para executar o teste no diretório, use o seguinte comando.
$ phpunit
Depois de executar o comando acima, você verá a seguinte resposta.
PHPUnit 5.1.3 by Sebastian Bergmann and contributors.
Usage: phpunit [options] UnitTest [UnitTest.php]
phpunit [options] <directory>
Code Coverage Options:
--coverage-clover <file> Generate code coverage report in Clover XML format.
--coverage-crap4j <file> Generate code coverage report in Crap4J XML format.
--coverage-html <dir> Generate code coverage report in HTML format.
Agora, execute os testes no diretório Libs da seguinte maneira.
$ phpunit tests/AppBundle/Libs
Resultado
Time: 26 ms, Memory: 4.00Mb
OK (1 test, 1 assertion)
Neste capítulo, aprenderemos sobre alguns conceitos avançados no framework Symfony.
Cache HTTP
O armazenamento em cache em um aplicativo da web melhora o desempenho. Por exemplo, produtos importantes em um aplicativo da web de carrinho de compras podem ser armazenados em cache por um tempo limitado, para que possam ser apresentados ao cliente de maneira rápida, sem acessar o banco de dados. A seguir estão alguns componentes básicos do Cache.
Item de Cache
Item de cache é uma unidade única de informação armazenada como um par chave / valor. okey deve ser string e valuepode ser qualquer objeto PHP. Os objetos PHP são armazenados como string por serialização e convertidos de volta em objetos durante a leitura dos itens.
Adaptador de Cache
O adaptador de cache é o mecanismo real para armazenar o item em uma loja. O armazenamento pode ser uma memória, sistema de arquivos, banco de dados, redis, etc. O componente de cache fornece umAdapterInterfacepor meio do qual um adaptador pode armazenar item de cache em um armazenamento de backend. Existem muitos adaptadores de cache integrados disponíveis. Poucos deles são os seguintes -
Adaptador de cache de matriz - os itens de cache são armazenados na matriz de PHP.
Adaptador de cache do sistema de arquivos - os itens do cache são armazenados em arquivos.
Adaptador de cache de arquivos PHP - Os itens de cache são armazenados como arquivos php.
Adaptador de cache APCu - Os itens de cache são armazenados na memória compartilhada usando a extensão PHP APCu.
Adaptador de cache Redis - os itens de cache são armazenados no servidor Redis.
Adaptador de cache PDO e Doctrine DBAL - Os itens de cache são armazenados no banco de dados.
Adaptador de cache de cadeia - Combina vários adaptadores de cache para fins de replicação.
Adaptador de cache proxy - os itens de cache são armazenados usando um adaptador de terceiros, que implementa CacheItemPoolInterface.
Pool de Cache
O pool de cache é um repositório lógico de itens de cache. Os pools de cache são implementados por adaptadores de cache.
Aplicação Simples
Vamos criar um aplicativo simples para entender o conceito de cache.
Step 1 - Crie um novo aplicativo, cache-example.
cd /path/to/app
mkdir cache-example
cd cache-example
Step 2 - Instale o componente de cache.
composer require symfony/cache
Step 3 - Crie um adaptador de sistema de arquivos.
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter();
Step 4 - Crie um item de cache usando getItem e setmétodo do adaptador. getItem busca o item de cache usando sua chave. se a chave não for persistente, ele cria um novo item. O método set armazena os dados reais.
$usercache = $cache->getitem('item.users');
$usercache->set(['jon', 'peter']); $cache->save($usercache);
Step 5 - Acesse o item de cache usando getItem, isHit e getmétodo. isHit informa a disponibilidade do item de cache e o método get fornece os dados reais.
$userCache = $cache->getItem('item.users'); if(!$userCache->isHit()) {
echo "item.users is not available";
} else {
$users = $userCache->get();
var_dump($users);
}
Step 6 - Exclua o item de cache usando deleteItem método.
$cache->deleteItem('item.users');
A lista de códigos completa é a seguinte.
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter(); $usercache = $cache->getitem('item.users'); $usercache->set(['jon', 'peter']);
$cache->save($usercache);
$userCache = $cache->getItem('item.users');
if(!$userCache->isHit()) { echo "item.users is not available"; } else { $users = $userCache->get(); var_dump($users);
}
$cache->deleteItem('item.users');
?>
Resultado
array(2) {
[0]=>
string(3) "jon"
[1]=>
string(5) "peter"
}
Depurar
A depuração é uma das atividades mais frequentes durante o desenvolvimento de um aplicativo. Symfony fornece um componente separado para facilitar o processo de depuração. Podemos habilitar as ferramentas de depuração do Symfony apenas chamando oenable método da classe Debug.
use Symfony\Component\Debug\Debug
Debug::enable()
Symfony oferece duas classes, ErrorHandler e ExceptionHandlerpara fins de depuração. Enquanto ErrorHandler captura erros de PHP e os converte em exceções, ErrorException ou FatalErrorException, ExceptionHandler captura exceções de PHP não detectadas e as converte em respostas úteis de PHP. ErrorHandler e ExceptionHandler são desabilitados por padrão. Podemos habilitá-lo usando o método de registro.
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\ExceptionHandler;
ErrorHandler::register();
ExceptionHandler::register();
Em um aplicativo da web Symfony, o debug environmenté fornecido por DebugBundle. Registre o pacote no AppKernelregisterBundles método para ativá-lo.
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
}
analisador
O desenvolvimento de um aplicativo precisa de uma ferramenta de criação de perfil de classe mundial. A ferramenta de criação de perfil coleta todas as informações de tempo de execução sobre um aplicativo, como tempo de execução, tempo de execução de módulos individuais, tempo gasto por uma atividade de banco de dados, uso de memória, etc. Um aplicativo da web precisa de muito mais informações, como o tempo de solicitação, tempo gasto para criar uma resposta, etc., além das métricas acima.
Symfony habilita todas essas informações em um aplicativo da web por padrão. Symfony fornece um pacote separado para perfis da web chamadoWebProfilerBundle. O pacote de criação de perfil da Web pode ser habilitado em um aplicativo da web, registrando-se o pacote no método registerBundles do AppKernel.
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
}
O componente de perfil da web pode ser configurado em web_profile section do arquivo de configuração do aplicativo, app/config/config.xml
web_profiler:
toolbar: false
position: bottom
O aplicativo Symfony mostra os dados perfilados na parte inferior da página como uma seção distinta.
Symfony também fornece uma maneira fácil de adicionar detalhes personalizados sobre a página nos dados do perfil usando DataCollectorInterface interfacee modelo de galho. Resumindo, o Symfony permite que um desenvolvedor da web crie um aplicativo de classe mundial, fornecendo uma grande estrutura de criação de perfil com relativa facilidade.
Segurança
Conforme discutido anteriormente, o Symfony fornece uma estrutura de segurança robusta por meio de seu componente de segurança. O componente de segurança é dividido em quatro subcomponentes da seguinte maneira.
- symfony / security-core - Funcionalidade de segurança central.
- symfony / security-http - Recurso de segurança integrado no protocolo HTTP.
- symfony / security-csrf - Proteção contra falsificação de solicitação entre sites em uma aplicação web.
- symfony / security-acl - Estrutura de segurança baseada em lista de controle de acesso avançado.
Autenticação e autorização simples
Vamos aprender o conceito de autenticação e autorização usando um aplicativo de demonstração simples.
Step 1 - Crie um novo aplicativo da web securitydemo usando o seguinte comando.
symfony new securitydemo
Step 2- Habilite o recurso de segurança no aplicativo usando o arquivo de configuração de segurança. A configuração relacionada à segurança é colocada em um arquivo separado,security.yml. A configuração padrão é a seguinte.
security:
providers:
in_memory:
memory: ~
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
#http_basic: ~
#form_login: ~
A configuração padrão permite provedor de segurança baseado em memória e acesso anônimo a todas as páginas. A seção de firewall exclui os arquivos que correspondem ao padrão,^/(_(profiler|wdt)|css|images|js)/da estrutura de segurança. O padrão padrão inclui folhas de estilo, imagens e JavaScripts (além de ferramentas de desenvolvimento como criador de perfil).
Step 3 - Habilite o sistema de autenticação de segurança baseado em HTTP adicionando a opção http_basic na seção principal como segue.
security:
# ...
firewalls:
# ...
main:
anonymous: ~
http_basic: ~
#form_login: ~
Step 4- Adicione alguns usuários na seção do provedor de memória. Além disso, adicione funções para os usuários.
security:
providers:
in_memory:
memory:
users:
myuser:
password: user
roles: 'ROLE_USER'
myadmin:
password: admin
roles: 'ROLE_ADMIN'
Adicionamos dois usuários, usuário na função ROLE_USER e administrador na função ROLE_ADMIN.
Step 5- Adicione o codificador para obter detalhes completos do usuário conectado no momento. O objetivo do codificador é obter detalhes completos do objeto de usuário atual da solicitação da web.
security:
# ...
encoders:
Symfony\Component\Security\Core\User\User: bcrypt
# ...
Symfony fornece uma interface, UserInterface para obter detalhes do usuário, como nome de usuário, funções, senha, etc. Precisamos implementar a interface de acordo com nossos requisitos e configurá-la na seção do codificador.
Por exemplo, vamos considerar que os detalhes do usuário estão no banco de dados. Então, precisamos criar uma nova classe User e implementar métodos UserInterface para obter os detalhes do usuário do banco de dados. Assim que os dados estiverem disponíveis, o sistema de segurança os usará para permitir / negar o usuário. Symfony fornece uma implementação de usuário padrão para provedor de memória. Algoritmo é usado para descriptografar a senha do usuário.
Step 6 - Criptografe a senha do usuário usando bcryptalgoritmo e coloque-o no arquivo de configuração. Desde que usamosbcryptalgoritmo, o objeto Usuário tenta descriptografar a senha especificada no arquivo de configuração e, em seguida, tenta corresponder à senha inserida pelo usuário. O aplicativo do console Symfony fornece um comando simples para criptografar a senha.
php bin/console security:encode-password admin
Symfony Password Encoder Utility
================================
------------------ -----------------------------------
Key Value
------------------ ------------------------------------
Encoder used Symfony\Component\Security\Core\Encoder\BCryptPasswordEncoder
Encoded password
$2y$12$0Hy6/.MNxWdFcCRDdstHU.hT5j3Mg1tqBunMLIUYkz6..IucpaPNO
------------------ ------------------------------------
! [NOTE] Bcrypt encoder used: the encoder generated its own built-in salt.
[OK] Password encoding succeeded
Step 7 - Use o comando para gerar a senha criptografada e atualizá-la no arquivo de configuração.
# To get started with security, check out the documentation:
# http://symfony.com/doc/current/security.html
security:
# http://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers:
in_memory:
memory:
users:
user:
password: $2y$13$WsGWNufreEnVK1InBXL2cO/U7WftvfNvH Vb/IJBH6JiYoDwVN4zoi roles: 'ROLE_USER' admin: password: $2y$13$jQNdIeoNV1BKVbpnBuhKRuOL01NeMK
F7nEqEi/Mqlzgts0njK3toy
roles: 'ROLE_ADMIN'
encoders:
Symfony\Component\Security\Core\User\User: bcrypt
firewalls:
# disables authentication for assets and the profiler,
# adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
# activate different ways to authenticate
# http://symfony.com/doc/current/security.html#a-co
nfiguring-howyour-users-will-authenticate
http_basic: ~
# http://symfony.com/doc/current/cookbook/security/
form_login_setup.html
#form_login: ~
Step 8- Agora, aplique a segurança a alguma seção do aplicativo. Por exemplo, restrinja a seção admin aos usuários na função, ROLE_ADMIN.
security:
# ...
firewalls:
# ...
default:
# ...
access_control:
# require ROLE_ADMIN for /admin*
- { path: ^/admin, roles: 'ROLE_ADMIN' }
Step 9 - Adicione uma página de administração em DefaultController da seguinte maneira.
/**
* @Route("/admin")
*/
public function adminLandingAction() {
return new Response('<html><body>This is admin section.</body></html>');
}
Step 10- Por fim, acesse a página de administração para verificar a configuração de segurança em um navegador. O navegador solicitará o nome de usuário e a senha e permitirá apenas usuários configurados.
Resultado
Fluxo de Trabalho
Fluxo de trabalho é um conceito avançado que pode ser usado em muitos aplicativos corporativos. Em um aplicativo de comércio eletrônico, o processo de entrega do produto é um fluxo de trabalho. O produto é primeiro faturado (criação do pedido), adquirido na loja e embalado (embalagem / pronto para despacho) e despachado para o usuário. Se houver algum problema, o produto retorna do usuário e o pedido é revertido. A ordem do fluxo da ação é muito importante. Por exemplo, não podemos entregar um produto sem faturamento.
O componente Symfony fornece uma maneira orientada a objetos para definir e gerenciar um fluxo de trabalho. Cada etapa de um processo é chamadaplace e a ação necessária para se mover de um lugar para outro é chamada transition. A coleção de lugares e transição para criar um fluxo de trabalho é chamada deWorkflow definition.
Vamos entender o conceito de fluxo de trabalho criando um aplicativo simples para gerenciamento de licenças.
Step 1 - Crie um novo aplicativo, workflow-example.
cd /path/to/dev
mkdir workflow-example
cd workflow-example
composer require symfony/workflow
Step 2 - Crie uma nova classe, Leave tendo applied_by, leave_on e status atributos.
class Leave {
public $applied_by; public $leave_on;
public $status;
}
Aqui, apply_by se refere aos funcionários que desejam sair. leave_on refere-se à data de licença. status refere-se ao status de licença.
Step 3 - O gerenciamento de licenças tem quatro vagas, aplicadas, em processo e aprovadas / rejeitadas.
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\Workflow;
use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\Dumper\GraphvizDumper;
$builder = new DefinitionBuilder();
$builder->addPlaces(['applied', 'in_process', 'approved', 'rejected']);
Aqui, criamos uma nova definição usando DefinitionBuilder e lugares adicionados usando addPlaces método.
Step 4 - Defina as ações necessárias para se deslocar de um lugar para outro.
$builder->addTransition(new Transition('to_process', 'applied', 'in_process'));
$builder->addTransition(new Transition('approve', 'in_process', 'approved')); $builder->addTransition(new Transition('reject', 'in_process', 'rejected'));
Aqui, temos três transições, to_process, approve e reject. a transição to_process aceita o aplicativo de saída e move o local de aplicado para in_process. aprovar transição aprova o pedido de licença e move o local para aprovado. Da mesma forma, rejeitar a transição rejeita o pedido de licença e muda o local para rejeitado. Criamos todas as transições usando o método addTransition.
Step 5 - Construir a definição usando o método de construção.
$definition = $builder->build();
Step 6 - Opcionalmente, a definição pode ser despejada como formato de ponto graphviz, que pode ser convertido em arquivo de imagem para fins de referência.
$dumper = new GraphvizDumper(); echo $dumper->dump($definition);
Step 7 - Crie um armazenamento de marcação, que é usado para armazenar os locais / status atuais do objeto.
$marking = new SingleStateMarkingStore('status');
Aqui, nós usamos SingleStateMarkingStorepara criar a marca e marcar o status atual na propriedade de status do objeto. Em nosso exemplo, o objeto é Deixar objeto.
Step 8 - Crie o fluxo de trabalho usando definição e marcação.
$leaveWorkflow = new Workflow($definition, $marking);
Aqui, nós usamos Workflow classe para criar o fluxo de trabalho.
Step 9 - Adicione o fluxo de trabalho ao registro da estrutura de fluxo de trabalho usando Registry classe.
$registry = new Registry();
$registry->add($leaveWorkflow, Leave::class);
Step 10 - Por fim, use o fluxo de trabalho para descobrir se uma determinada transição é aplicada usando can método e se assim for, applya transição usando o método de aplicação. Quando uma transição é aplicada, o status do objeto se move de um lugar para outro.
$workflow = $registry->get($leave); echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n"; echo "Can we approve the start process now? " . $workflow->can($leave, 'to_process') . "\r\n"; $workflow->apply($leave, 'to_process'); echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n"; echo $leave->status . "\r\n";
$workflow->apply($leave, 'approve');
echo $leave->status . "\r\n";
A codificação completa é a seguinte -
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Workflow\DefinitionBuilder;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\Workflow;
use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\Dumper\GraphvizDumper;
class Leave {
public $applied_by;
public $leave_on; public $status;
}
$builder = new DefinitionBuilder(); $builder->addPlaces(['applied', 'in_process', 'approved', 'rejected']);
$builder->addTransition(new Transition('to_process', 'applied', 'in_process')); $builder->addTransition(new Transition('approve', 'in_process', 'approved'));
$builder->addTransition(new Transition('reject', 'in_process', 'rejected')); $definition = $builder->build(); // $dumper = new GraphvizDumper();
// echo $dumper->dump($definition);
$marking = new SingleStateMarkingStore('status'); $leaveWorkflow = new Workflow($definition, $marking);
$registry = new Registry(); $registry->add($leaveWorkflow, Leave::class); $leave = new Leave();
$leave->applied_by = "Jon"; $leave->leave_on = "1998-12-12";
$leave->status = 'applied'; $workflow = $registry->get($leave);
echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n";
echo "Can we approve the start process now? " . $workflow->can($leave, 'to_process') . "\r\n";
$workflow->apply($leave, 'to_process');
echo "Can we approve the leave now? " . $workflow->can($leave, 'approve') . "\r\n";
echo $leave->status . "\r\n"; $workflow->apply($leave, 'approve'); echo $leave->status . "\r\n";
?>
Resultado
Can we approve the leave now?
Can we approve the start process now? 1
Can we approve the leave now? 1
in_process
approved
Em qualquer aplicativo moderno, o serviço REST é um dos principais blocos de construção fundamentais. Seja um aplicativo baseado na web ou um aplicativo móvel inteligente, o front-end é geralmente uma interface bem projetada para os serviços REST de back-end. A edição Symfony REST fornece um modelo pronto para iniciar nosso aplicativo da web baseado em REST.
Vamos aprender como instalar um aplicativo modelo REST usando a edição Symfony REST.
Step 1 - Baixe a edição REST do Symfony usando o seguinte comando.
composer create-project gimler/symfony-rest-edition --stability=dev path/to/install
Isso fará o download da edição REST do Symfony.
Step 2- Tente configurá-lo fazendo algumas perguntas. Para todas as perguntas, selecione a resposta padrão, exceto banco de dados. Para banco de dados, selecione pdo_sqlite. Você pode precisar habilitar a extensão sqlite do PHP, se ainda não estiver instalada.
Step 3 - Agora, execute o aplicativo usando o seguinte comando.
php app/console server:run
Step 4 - Por fim, abra o aplicativo no navegador usando http: // localhost: 8000 /.
Isso produzirá o seguinte resultado -
O sistema de gerenciamento de conteúdo é um dos maiores do mercado no cenário de aplicativos web. Existem muitos frameworks disponíveis para o sistema de gerenciamento de conteúdo, em praticamente todos os idiomas existentes. A maioria das estruturas é fácil de trabalhar como cliente final, mas muito difícil de trabalhar como desenvolvedor e vice-versa.
Symfony fornece uma estrutura simples e fácil para um desenvolvedor começar. Ele também possui todos os recursos básicos esperados por um cliente final. Resumindo, é responsabilidade do desenvolvedor fornecer uma ótima experiência para o cliente final.
Vamos ver como instalar um modelo de aplicativo CMS usando a edição Symfony CMF.
Step 1 - Baixe o sandbox do Symfony CMF usando o seguinte comando.
composer create-project symfony-cmf/sandbox cmf-sandbox
Isso fará o download do Symfony CMF.
Step 2- Tente configurá-lo fazendo algumas perguntas. Para todas as perguntas, selecione a resposta padrão, exceto banco de dados. Para banco de dados, selecione pdo_sqlite. Você pode precisar habilitar a extensão sqlite do PHP, se ainda não estiver instalada.
Step 3 - Crie um banco de dados de demonstração usando o aplicativo de console da seguinte maneira.
php app/console doctrine:database:create
Step 4 - Carregue os dados de demonstração no banco de dados usando o seguinte comando.
php app/console doctrine:phpcr:init:dbal --force
php app/console doctrine:phpcr:repository:init
php app/console doctrine:phpcr:fixtures:load -n
Step 5 - Agora, execute o aplicativo usando o seguinte comando.
php app/console server:run
Step 6 - Por fim, abra o aplicativo no navegador usando http: // localhost: 8000 /.
Ele produzirá a seguinte saída -
Neste capítulo, aprenderemos como criar um MVC completo baseado BookStore Applicationno Symfony Framework. A seguir estão as etapas.
Etapa 1: Criar um Projeto
Vamos criar um novo projeto chamado “BookStore” no Symfony usando o seguinte comando.
symfony new BookStore
Etapa 2: criar um controlador e uma rota
Crie um BooksController no diretório “src / AppBundle / Controller”. É definido como segue.
BooksController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class BooksController {
/**
* @Route("/books/author")
*/
public function authorAction() {
return new Response('Book store application!');
}
}
Agora, criamos um BooksController e, em seguida, criamos uma visualização para renderizar a ação.
Etapa 3: criar uma visualização
Vamos criar uma nova pasta chamada “Books” no diretório “app / Resources / views /”. Dentro da pasta, crie um arquivo “author.html.twig” e adicione as seguintes alterações.
author.html.twig
<h3> Simple book store application</h3>
Agora, renderize a visualização na classe BooksController. É definido como segue.
BooksController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class BooksController extends Controller {
/**
* @Route("/books/author")
*/
public function authorAction() {
return $this->render('books/author.html.twig');
}
}
A partir de agora, criamos um BooksController básico e o resultado é renderizado. Você pode verificar o resultado no navegador usando a URL “http: // localhost: 8000 / books / author”.
Etapa 4: configuração do banco de dados
Configure o banco de dados no arquivo “app / config / parameters.yml”.
Abra o arquivo e adicione as seguintes alterações.
parameter.yml
# This file is auto-generated during the composer install
parameters:
database_driver: pdo_mysql
database_host: localhost
database_port: 3306
database_name: booksdb
database_user: <database_username>
database_password: <database_password>
mailer_transport: smtp
mailer_host: 127.0.0.1
mailer_user: null
mailer_password: null
secret: 0ad4b6d0676f446900a4cb11d96cf0502029620d
doctrine:
dbal:
driver: pdo_mysql
host: '%database_host%'
dbname: '%database_name%'
user: '%database_user%'
password: '%database_password%'
charset: utf8mb4
Agora, o Doctrine pode se conectar ao seu banco de dados “booksdb”.
Etapa 5: Criar um banco de dados
Emita o seguinte comando para gerar o banco de dados “booksdb”. Esta etapa é usada para ligar o banco de dados no Doctrine.
php bin/console doctrine:database:create
Depois de executar o comando, ele gera automaticamente um banco de dados “booksdb” vazio. Você pode ver a seguinte resposta na tela.
Isso produzirá o seguinte resultado -
Created database `booksdb` for connection named default
Etapa 6: mapeamento de informações
Crie uma classe de entidade Book dentro do diretório Entity que está localizado em “src / AppBundle / Entity”.
Você pode passar diretamente na classe Book usando anotações. É definido como segue.
Book.php
Adicione o seguinte código no arquivo.
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name = "Books")
*/
class Book {
/**
* @ORM\Column(type = "integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy = "AUTO")
*/
private $id;
/**
* @ORM\Column(type = "string", length = 50)
*/
private $name; /** * @ORM\Column(type = "string", length = 50) */ private $author;
/**
* @ORM\Column(type = "decimal", scale = 2)
*/
private $price;
}
Aqui, o nome da tabela é opcional.
Se o nome da tabela não for especificado, ele será determinado automaticamente com base no nome da classe de entidade.
Etapa 7: vincular uma entidade
O Doctrine cria classes de entidade simples para você. Ajuda a construir qualquer entidade.
Emita o seguinte comando para gerar uma entidade.
php bin/console doctrine:generate:entities AppBundle/Entity/Book
Então você verá o seguinte resultado e a entidade será atualizada.
Generating entity "AppBundle\Entity\Book”
> backing up Book.php to Book.php~
> generating AppBundle\Entity\Book
Book.php
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
* @ORM\Table(name = "Books")
*/
class Book {
/**
* @ORM\Column(type = "integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy = "AUTO")
*/
private $id;
/**
* @ORM\Column(type = "string", length = 50)
*/
private $name; /** * @ORM\Column(type = "string", length = 50) */ private $author;
/**
* @ORM\Column(type = "decimal", scale = 2)
*/
private $price; /** * Get id * * @return integer */ public function getId() { return $this->id;
}
/**
* Set name
*
* @param string $name * * @return Book */ public function setName($name) {
$this->name = $name;
return $this; } /** * Get name * * @return string */ public function getName() { return $this->name;
}
/**
* Set author
*
* @param string $author * * @return Book */ public function setAuthor($author) {
$this->author = $author;
return $this; } /** * Get author * * @return string */ public function getAuthor() { return $this->author;
}
/**
* Set price
*
* @param string $price * * @return Book */ public function setPrice($price) {
$this->price = $price;
return $this; } /** * Get price * * @return string */ public function getPrice() { return $this->price;
}
}
Etapa 8: Validação de Mapeamento
Depois de criar entidades, você deve validar os mapeamentos usando o seguinte comando.
php bin/console doctrine:schema:validate
Isso produzirá o seguinte resultado -
[Mapping] OK - The mapping files are correct
[Database] FAIL - The database schema is not in sync with the current mapping file.
Como não criamos a tabela Books, a entidade está fora de sincronia. Vamos criar a tabela Books usando o comando Symfony na próxima etapa.
Etapa 9: Criação do esquema
O Doctrine pode criar automaticamente todas as tabelas de banco de dados necessárias para a entidade Livro. Isso pode ser feito usando o seguinte comando.
php bin/console doctrine:schema:update --force
Depois de executar o comando, você verá a seguinte resposta.
Updating database schema...
Database schema updated successfully! "1" query was executed
Agora, valide novamente o esquema usando o seguinte comando.
php bin/console doctrine:schema:validate
Isso produzirá o seguinte resultado -
[Mapping] OK - The mapping files are correct.
[Database] OK - The database schema is in sync with the mapping files.
Etapa 10: Getter e Setter
Conforme visto na seção Vincular uma entidade, o comando a seguir gera todos os getters e setters para a classe Book.
$ php bin/console doctrine:generate:entities AppBundle/Entity/Book
Etapa 11: Buscando objetos do banco de dados
Crie um método em BooksController que exibirá os detalhes dos livros.
BooksController.php
/**
* @Route("/books/display", name="app_book_display")
*/
public function displayAction() {
$bk = $this->getDoctrine() ->getRepository('AppBundle:Book') ->findAll(); return $this->render('books/display.html.twig', array('data' => $bk));
}
Etapa 12: Criar uma visualização
Vamos criar uma visão que aponta para a ação de exibição. Vá para o diretório de visualizações e crie o arquivo “display.html.twig”. Adicione as seguintes alterações no arquivo.
display.html.twig
{% extends 'base.html.twig' %}
{% block stylesheets %}
<style>
.table { border-collapse: collapse; }
.table th, td {
border-bottom: 1px solid #ddd;
width: 250px;
text-align: left;
align: left;
}
</style>
{% endblock %}
{% block body %}
<h2>Books database application!</h2>
<table class = "table">
<tr>
<th>Name</th>
<th>Author</th>
<th>Price</th>
</tr>
{% for x in data %}
<tr>
<td>{{ x.Name }}</td>
<td>{{ x.Author }}</td>
<td>{{ x.Price }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
Você pode obter o resultado solicitando a URL “http: // localhost: 8000 / books / display” no navegador.
Resultado
Etapa 13: Adicionar um formulário de livro
Vamos criar uma funcionalidade para adicionar um livro ao sistema. Crie uma nova página, o método newAction no BooksController da seguinte maneira.
// use section
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
// methods section
/**
* @Route("/books/new")
*/
public function newAction(Request $request) {
$stud = new StudentForm(); $form = $this->createFormBuilder($stud)
->add('name', TextType::class)
->add('author', TextType::class)
->add('price', TextType::class)
->add('save', SubmitType::class, array('label' => 'Submit'))
->getForm();
return $this->render('books/new.html.twig', array('form' => $form->createView(),));
}
Etapa 14: Criar um formulário de visualização para livro
Vamos criar uma visão que aponta para uma nova ação. Vá para o diretório de visualizações e crie um arquivo “new.html.twig”. Adicione as seguintes alterações no arquivo.
{% extends 'base.html.twig' %}
{% block stylesheets %}
<style>
#simpleform {
width:600px;
border:2px solid grey;
padding:14px;
}
#simpleform label {
font-size:14px;
float:left;
width:300px;
text-align:right;
display:block;
}
#simpleform span {
font-size:11px;
color:grey;
width:100px;
text-align:right;
display:block;
}
#simpleform input {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:24px;
width:250px;
margin: 0 0 10px 10px;
}
#simpleform textarea {
border:1px solid grey;
font-family:verdana;
font-size:14px;
color:light blue;
height:120px;
width:250px;
margin: 0 0 20px 10px;
}
#simpleform select {
margin: 0 0 20px 10px;
}
#simpleform button {
clear:both;
margin-left:250px;
background: grey;
color:#FFFFFF;
border:solid 1px #666666;
font-size:16px;
}
</style>
{% endblock %}
{% block body %}
<h3>Book details:</h3>
<div id = "simpleform">
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
</div>
{% endblock %}
Ele produzirá a seguinte tela como saída -
Etapa 15: coletar informações do livro e armazená-las
Vamos alterar o método newAction e incluir o código para lidar com o envio do formulário. Além disso, armazene as informações do livro no banco de dados.
/**
* @Route("/books/new", name="app_book_new")
*/
public function newAction(Request $request) { $book = new Book();
$form = $this->createFormBuilder($book) ->add('name', TextType::class) ->add('author', TextType::class) ->add('price', TextType::class) ->add('save', SubmitType::class, array('label' => 'Submit')) ->getForm(); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $book = $form->getData(); $doct = $this->getDoctrine()->getManager(); // tells Doctrine you want to save the Product $doct->persist($book); //executes the queries (i.e. the INSERT query) $doct->flush();
return $this->redirectToRoute('app_book_display'); } else { return $this->render('books/new.html.twig', array(
'form' => $form->createView(),
));
}
}
Depois que o livro estiver armazenado no banco de dados, redirecione para a página de exibição do livro.
Etapa 16: Atualizando o livro
Para atualizar o livro, crie uma ação, updateAction e adicione as seguintes alterações.
/**
* @Route("/books/update/{id}", name = "app_book_update" )
*/
public function updateAction($id, Request $request) { $doct = $this->getDoctrine()->getManager(); $bk = $doct->getRepository('AppBundle:Book')->find($id);
if (!$bk) { throw $this->createNotFoundException(
'No book found for id '.$id ); } $form = $this->createFormBuilder($bk)
->add('name', TextType::class)
->add('author', TextType::class)
->add('price', TextType::class)
->add('save', SubmitType::class, array('label' => 'Submit'))
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$book = $form->getData();
$doct = $this->getDoctrine()->getManager();
// tells Doctrine you want to save the Product
$doct->persist($book);
//executes the queries (i.e. the INSERT query)
$doct->flush(); return $this->redirectToRoute('app_book_display');
} else {
return $this->render('books/new.html.twig', array( 'form' => $form->createView(),
));
}
}
Aqui, estamos processando duas funcionalidades. Se a solicitação contém apenas id, então nós o obtemos do banco de dados e o mostramos no formulário de livro. E, se a solicitação contiver informações completas do livro, atualizamos os detalhes no banco de dados e redirecionamos para a página de exibição do livro.
Etapa 17: Excluindo um objeto
A exclusão de um objeto requer uma chamada ao método remove () do gerenciador de entidade (doutrina).
Isso pode ser feito usando o código a seguir.
/**
* @Route("/books/delete/{id}", name="app_book_delete")
*/
public function deleteAction($id) { $doct = $this->getDoctrine()->getManager(); $bk = $doct->getRepository('AppBundle:Book')->find($id);
if (!$bk) { throw $this->createNotFoundException('No book found for id '.$id); } $doct->remove($bk); $doct->flush();
return $this->redirectToRoute('app_book_display');
}
Aqui, excluímos o livro e redirecionamos para a página de exibição do livro.
Etapa 18: Incluir Funcionalidade Adicionar / Editar / Excluir na Página de Exibição
Agora, atualize o bloco do corpo na visualização de exibição e inclua links de inclusão / edição / exclusão conforme a seguir.
{% block body %}
<h2>Books database application!</h2>
<div>
<a href = "{{ path('app_book_new') }}">Add</a>
</div>
<table class = "table">
<tr>
<th>Name</th>
<th>Author</th>
<th>Price</th>
<th></th>
<th></th>
</tr>
{% for x in data %}
<tr>
<td>{{ x.Name }}</td>
<td>{{ x.Author }}</td>
<td>{{ x.Price }}</td>
<td><a href = "{{ path('app_book_update', { 'id' : x.Id }) }}">Edit</a></td>
<td><a href = "{{ path('app_book_delete', { 'id' : x.Id }) }}">Delete</a></td>
</tr>
{% endfor %}
</table>
{% endblock %}
Ele produzirá a seguinte tela como saída -
Symfony é composto por um conjunto de componentes PHP, uma estrutura de aplicativo, uma comunidade e uma filosofia. Symfony é extremamente flexível e capaz de atender a todos os requisitos de usuários avançados, profissionais e uma escolha ideal para todos os iniciantes em PHP.