Symfony - Szybki przewodnik
Framework sieciowy PHP to zbiór klas, które pomagają w tworzeniu aplikacji internetowych. Symfony to framework MVC typu open source do szybkiego tworzenia nowoczesnych aplikacji internetowych. Symfony to framework sieciowy z pełnym stosem. Zawiera zestaw komponentów PHP wielokrotnego użytku. Możesz używać dowolnych komponentów Symfony w aplikacjach, niezależnie od frameworka.
Symfony ma ogromną funkcjonalność i aktywną społeczność. Ma elastyczną konfigurację przy użyciu YAML, XML lub adnotacji. Symfony integruje się z niezależną biblioteką i jednostką PHP. Symfony jest inspirowany głównie przez frameworki aplikacji internetowych Ruby on Rails, Django i Spring. Komponenty Symfony są używane w wielu projektach open source, w tym Composer, Drupal i phpBB.
Framework Symfony składa się z kilku komponentów, takich jak komponent HttpFoundation, który rozumie HTTP i oferuje ładny obiekt żądania i odpowiedzi używany przez inne komponenty. Inne są jedynie komponentami pomocniczymi, takimi jak Validator, który pomaga w walidacji danych. Składnik jądra jest sercem systemu. Jądro jest w zasadzie „główną klasą”, która zarządza środowiskiem i odpowiada za obsługę żądań http.
Dobrze zorganizowana struktura Symfony, czysty kod i dobre praktyki programistyczne ułatwiają tworzenie stron internetowych. Symfony jest bardzo elastyczny, używany do tworzenia mikro-witryn i obsługi aplikacji korporacyjnych z miliardami połączeń.
Framework Symfony - funkcje
Symfony ma na celu optymalizację tworzenia aplikacji internetowych i rozszerza funkcje z każdym wydaniem.
Oto niektóre z najważniejszych cech Symfony Framework -
- System oparty na modelu-widoku-kontrolerze
- Wysokowydajny framework PHP
- Elastyczny routing URI
- Kod wielokrotnego użytku i łatwiejszy w utrzymaniu
- Zarządzanie sesjami
- Błąd podczas logowania
- W pełni funkcjonalne klasy bazy danych z obsługą kilku platform
- Wspiera ogromną i aktywną społeczność
- Zestaw odsprzęgniętych i wielokrotnego użytku elementów
- Standaryzacja i interoperacyjność aplikacji
- Zabezpieczenie przed fałszowaniem żądań między lokacjami i innymi atakami
- Silnik szablonów Twig
Symfony oferuje programistom dużą elastyczność. Ma świetne funkcje do debugowania, czytelności kodu i tworzenia rozszerzalnych programów.
Symfony jest pełnym frameworkiem sieciowym; jest to bardzo efektywne narzędzie do tworzenia aplikacji internetowych. Wiele firm oferuje klientom usługi Symfony.
Oto niektóre z korzyści, które można uzyskać, korzystając z Symfony Framework.
Microframework- Symfony może służyć do rozwijania określonej funkcjonalności. Nie musisz przebudowywać ani instalować całego frameworka.
Zmniejsza narzut czasu na rozwój.
Niezwykle dojrzały silnik szablonów i szybko dostarcza treści do użytkowników.
Compatible and extensible - Programiści mogą łatwo rozszerzać wszystkie klasy frameworka.
Framework Symfony - Aplikacje
Komponenty Symfony mogą być używane jako część innych aplikacji, takich jak Drupal, Laravel, phpBB, Behat, Doctrine i Joomla.
Drupal 8- Drupal to framework PHP do zarządzania treścią typu open source. Drupal 8 wykorzystuje podstawowe warstwy Symfony i rozszerza je o obsługę modułów Drupala.
Thelia- Thelia to oparte na Symfony rozwiązanie do handlu elektronicznego. Początkowo Thelia została napisana w kodzie PHP i MySQL, jednak opóźniało się tworzenie szybszych aplikacji. Aby przezwyciężyć tę wadę, Thelia zintegrowała się z Symfony w celu tworzenia aplikacji w sposób dostosowywalny.
Dailymotion- Dailymotion to jeden z największych na świecie niezależnych witryn rozrywki wideo z siedzibą we Francji. Gdy zdecydowali się na migrację frameworka open source z dużą społecznością, programiści Dailymotion zdecydowali się użyć funkcji komponentów Symfony ze względu na jego elastyczność.
W tym rozdziale wyjaśniono, jak zainstalować framework Symfony na twoim komputerze. Instalacja frameworka Symfony jest bardzo prosta i łatwa. Istnieją dwie metody tworzenia aplikacji we frameworku Symfony. Pierwsza metoda to użycie Symfony Installer, aplikacji do tworzenia projektu w frameworku Symfony. Druga metoda to instalacja oparta na kompozytorze. Przeanalizujmy szczegółowo każdą z metod w kolejnych sekcjach.
wymagania systemowe
Przed przejściem do instalacji wymagane są następujące wymagania systemowe.
- Serwer WWW (dowolny z poniższych)
- WAMP (Windows)
- LAMP (Linux)
- XAMP (wieloplatformowy)
- MAMP (Macintosh)
- Nginx (wiele platform)
- Microsoft IIS (Windows)
- Wbudowany serwer WWW do programowania w języku PHP (wieloplatformowy)
- System operacyjny: wieloplatformowy
- Obsługa przeglądarek: IE (Internet Explorer 8+), Firefox, Google Chrome, Safari, Opera
- Zgodność z PHP: PHP 5.4 lub nowszy. Aby uzyskać maksymalne korzyści, użyj najnowszej wersji.
W tym samouczku użyjemy wbudowanego w PHP serwera WWW do programowania.
Instalator Symfony
Instalator Symfony służy do tworzenia aplikacji internetowych w frameworku Symfony. Teraz skonfigurujmy instalator Symfony za pomocą następującego polecenia.
$ 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
Teraz zainstalowałeś instalator Symfony na swoim komputerze.
Stwórz swoją pierwszą aplikację Symfony
Poniższa składnia służy do tworzenia aplikacji Symfony w najnowszej wersji.
Składnia
symfony new app_name
Tutaj nazwa_aplikacji to nowa nazwa aplikacji. Możesz podać dowolną nazwę.
Przykład
symfony new HelloWorld
Po wykonaniu powyższego polecenia zobaczysz następującą odpowiedź.
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
To polecenie tworzy nowy katalog o nazwie „firstapp /”, który zawiera pusty projekt najnowszej wersji frameworka Symfony.
Zainstaluj określoną wersję
Jeśli chcesz zainstalować określoną wersję Symfony, użyj następującego polecenia.
symfony new app_name 2.8
symfony new app_name 3.1
Instalacja oparta na komponencie
Możesz tworzyć aplikacje Symfony używając Composera. Mamy nadzieję, że zainstalowałeś kompozytora na swoim komputerze. Jeśli kompozytor nie jest zainstalowany, pobierz go i zainstaluj.
Poniższe polecenie służy do tworzenia projektu za pomocą kompozytora.
$ composer create-project symfony/framework-standard-edition app_name
Jeśli chcesz określić konkretną wersję, możesz określić w powyższym poleceniu.
Uruchomienie aplikacji
Przejdź do katalogu projektu i uruchom aplikację za pomocą następującego polecenia.
cd HelloWorld
php bin/console server:run
Po wykonaniu powyższego polecenia otwórz przeglądarkę i poproś o adres URL http://localhost:8000/. Daje następujący wynik.
Wynik
Symfony to po prostu zbiór wysokiej jakości komponentów i pakietów. Komponenty to zbiór klas zapewniających pojedynczą podstawową funkcjonalność. Na przykład,Cache componentzapewnia funkcjonalność pamięci podręcznej, którą można dodać do dowolnej aplikacji. Komponenty są elementami składowymi aplikacji Symfony. Symfony ma ponad 30 wysokiej jakości komponentów, które są używane w wielu frameworkach PHP, takich jak Laravel, Silex itp.
Pakiety są podobne do wtyczek, ale łatwe do utworzenia i łatwe w użyciu. W rzeczywistości aplikacja Symfony jest sama w sobie pakietem złożonym z innych pakietów. Pojedynczy pakiet może korzystać z dowolnej liczby komponentów Symfony, a także komponentów innych firm, aby zapewnić funkcje takie jak Webframework, dostęp do baz danych, itp. Rdzeń sieciowy Symfony to pakiet o nazwie FrameworkBundle i jest pakiet o nazwie FrameworkExtraBundle, który zapewnia bardziej wyrafinowane opcje pisania aplikacji internetowej.
Relacje między komponentami, pakietami i aplikacją Symfony przedstawiono na poniższym diagramie.
Framework sieciowy
Symfony jest przeznaczony głównie do pisania wysokiej jakości aplikacji internetowych ze względną łatwością. Zapewnia różne opcje pisania różnych typów aplikacji internetowych, od prostych witryn internetowych po zaawansowane usługi internetowe oparte na REST. Symfony dostarcza frameworki internetowe jako oddzielne pakiety. Typowe pakiety używane we frameworku sieciowym Symfony są następujące -
- FrameworkBundle
- FrameworkExtraBundle
- DoctrineBundle
Framework sieciowy Symfony jest oparty na architekturze Model-View-Controller (MVC). Model przedstawia strukturę naszych podmiotów gospodarczych. View pokazuje modele użytkownikowi w najlepszy możliwy sposób w zależności od sytuacji. Controller obsługuje wszystkie żądania od użytkownika, wykonuje rzeczywistą pracę, wchodząc w interakcję z modelem, a na koniec dostarcza widokowi niezbędne dane, aby pokazać je użytkownikowi.
Framework sieciowy Symfony zapewnia wszystkie funkcje wysokiego poziomu wymagane dla aplikacji dla przedsiębiorstw. Poniżej znajduje się prosty przepływ pracy aplikacji internetowej Symfony.
Przepływ pracy składa się z następujących kroków.
Step 1 - Użytkownik wysyła żądanie do aplikacji za pośrednictwem przeglądarki, na przykład http://www.symfonyexample.com/index.
Step 2 - Przeglądarka wyśle żądanie do serwera WWW, na przykład serwera WWW Apache.
Step 3 - Serwer sieciowy przekaże żądanie do bazowego PHP, które z kolei prześle je do frameworka internetowego Symfony.
Step 4- HttpKernel jest podstawowym komponentem frameworka internetowego Symfony. HttpKernel rozpoznaje kontroler danego żądania przy użyciu komponentu routingu i przekazuje żądanie do kontrolera docelowego.
Step 5 - Cała logika biznesowa odbywa się w kontrolerze docelowym.
Step 6 - Kontroler będzie współpracował z modelem, który z kolei współdziała z źródłem danych za pośrednictwem Doctrine ORM.
Step 7 - Po zakończeniu procesu kontroler generuje odpowiedź samodzielnie lub za pośrednictwem mechanizmu View Engine i odsyła ją z powrotem do serwera WWW.
Step 8 - Na koniec odpowiedź zostanie wysłana do żądanej przeglądarki przez serwer WWW.
Jak wspomniano wcześniej, komponenty Symfony to samodzielna biblioteka PHP zapewniająca określoną funkcję, której można użyć w dowolnej aplikacji PHP. Przydatne nowe komponenty są wprowadzane w każdym wydaniu Symfony. Obecnie we frameworku Symfony jest ponad 30 wysokiej jakości komponentów. W tym rozdziale poznajmy użycie komponentów Symfony.
Instalowanie składnika Symfony
Komponenty Symfony można łatwo zainstalować za pomocą polecenia composer. Poniższe ogólne polecenie może być użyte do zainstalowania dowolnego komponentu Symfony.
cd /path/to/project/dir
composer require symfony/<component_name>
Stwórzmy prostą aplikację php i spróbujmy ją zainstalować Filesystem składnik.
Step 1 - Utwórz folder dla aplikacji, filesystem-example
cd /path/to/dev/folder
mdkir filesystem-example
cd filesystem-example
Step 2 - Zainstaluj komponent Filesystem za pomocą następującego polecenia.
composer require symfony/filesystem
Step 3 - Utwórz plik main.php i wprowadź następujący kod.
<?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;
}
?>
Bardzo ważna jest pierwsza linia, która ładuje wszystkie niezbędne klasy ze wszystkich komponentów zainstalowanych za pomocą polecenia Composer. Następne wiersze używają klasy Filesystem.
Step 4 - Uruchom aplikację za pomocą następującego polecenia, a utworzy nowy folder sample-dir i plik test.txt pod tym.
php main.php
Szczegóły składników Symfony
Symfony dostarcza komponenty, od prostych funkcji, powiedzmy, systemu plików po zaawansowane funkcje, powiedzmy zdarzenia, technologię kontenerów i wstrzykiwanie zależności. Poinformuj nas o wszystkich składnikach jeden po drugim w kolejnych sekcjach.
System plików
Komponent systemu plików udostępnia podstawowe polecenie systemowe związane z plikami i katalogami, takie jak tworzenie plików, tworzenie folderów, istnienie plików itp. Komponent systemu plików można zainstalować za pomocą następującego polecenia.
composer require symfony/filesystem
Znalazca
Komponent Finder zapewnia płynne klasy do znajdowania plików i katalogów w określonej ścieżce. Zapewnia łatwy sposób iteracji po plikach w ścieżce. Komponent Findera można zainstalować za pomocą następującego polecenia.
composer require symfony/finder
Konsola
Komponent konsoli zapewnia różne opcje do łatwego tworzenia poleceń, które mogą być wykonywane w terminalu. Symfony używa rozszerzeniaCommand komponent szeroko w celu zapewnienia różnych funkcjonalności, takich jak tworzenie nowej aplikacji, tworzenie pakietu itp. Nawet kompilacja PHP na serwerze WWW może być wywołana za pomocą polecenia Symfony, php bin/console server:runjak widać w sekcji dotyczącej instalacji. PlikConsole składnik można zainstalować za pomocą następującego polecenia.
composer require symfony/console
Stwórzmy prostą aplikację i stwórzmy polecenie, HelloCommand używając Console i wywołaj go.
Step 1 - Utwórz projekt za pomocą następującego polecenia.
cd /path/to/project
composer require symfony/console
Step 2 - Utwórz plik main.php i dołącz następujący kod.
<?php
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Console\Application;
$app = new Application();
$app->run();
?>
Application class ustawia niezbędną funkcjonalność aplikacji konsoli bare-bone.
Step 3 - Uruchom aplikację, php main.php, co da następujący wynik.
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 - Utwórz klasę o nazwie HelloCommand rozsuwalny Command klasa w main.php samo.
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 {
}
Aplikacja korzysta z następujących czterech klas dostępnych w Command składnik.
Command - Służy do tworzenia nowego polecenia
InputInterface - Służy do ustawiania danych wejściowych użytkownika
InputArgument - Służy do pobierania danych wejściowych użytkownika
OutputInterface - Służy do drukowania danych wyjściowych na konsoli
step 5 - Utwórz funkcję configure() i ustaw nazwę, opis i tekst pomocy.
protected function configure() {
$this
->setName('app:hello')
->setDescription('Sample command, hello')
->setHelp('This command is a sample command')
}
step 6 - Utwórz argument wejściowy, user dla polecenia i ustaw jako obowiązkowe.
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 - Utwórz funkcję execute() z dwoma argumentami InputArgument i OutputArgument.
protected function execute(InputInterface $input, OutputInterface $output) {
}
step 8 - Użyj InputArgument aby uzyskać dane użytkownika wprowadzone przez użytkownika i wydrukować je na konsoli za pomocą OutputArgument.
protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument('name'); $output->writeln('Hello, ' . $name);
}
step 9 - Zarejestruj HelloCommand do aplikacji przy użyciu rozszerzenia add metoda Application klasa.
$app->add(new HelloCommand());
Kompletna aplikacja jest następująca.
<?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 - Teraz uruchom aplikację za pomocą następującego polecenia, a wynikiem będzie Hello, Jon, zgodnie z oczekiwaniami.
php main.php app:hello Jon
Symfony zawiera wbudowany plik binarny o nazwie console w katalogu bin dowolnej aplikacji internetowej Symfony, której można użyć do wywołania poleceń w aplikacji.
Proces
Komponent procesu zapewnia opcje uruchamiania dowolnego polecenia systemowego w podprocesie w bezpieczny i wydajny sposób. Komponent procesu można zainstalować za pomocą następującego polecenia.
composer require symfony/process
ClassLoader
Składnik ClassLoader zapewnia implementację obu PSR-0 i PSR-4klasa standardowej ładowarki. Może służyć do automatycznego ładowania klas. W najbliższej przyszłości zostanie on umorzony. Program ładujący klasy oparty na komponencie jest preferowany w stosunku do tego składnika. Komponent ClassLoader można zainstalować za pomocą następującego polecenia.
composer require symfony/class-loader
PropertyAccess
Składnik PropertyAccess zapewnia różne opcje odczytu i zapisu szczegółów obiektu i tablicy przy użyciu notacji ciągu. Na przykład tablicaProduct z kluczem price można uzyskać dostęp dynamicznie za pomocą [price] strunowy.
$product = array( 'name' => 'Cake' 'price' => 10 ); var priceObj = $propertyAccesserObj->getValue($product, '[price]');
Komponent PropertyAccess można zainstalować za pomocą następującego polecenia.
composer require symfony/property-access
PropertyInfo
Komponent PropertyInfo jest podobny do komponentu PropertyAccess, jednak działa tylko z obiektami PHP i zapewnia znacznie większą funkcjonalność.
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"
}
*/
Komponent PropertyInfo można zainstalować za pomocą następującego polecenia.
composer require symfony/property-info
EventDispatcher
Komponent EventDispatcher zapewnia programowanie oparte na zdarzeniach w PHP. Umożliwia obiektom komunikowanie się ze sobą poprzez wysyłanie zdarzeń i nasłuchiwanie ich. Dowiemy się, jak tworzyć wydarzenia i słuchać ich w rozdziale Wydarzenia i odbiornik wydarzeń.
Komponent EventDispatcher można zainstalować za pomocą następującego polecenia.
composer require symfony/event-dispatcher
DependencyInjection
Składnik DependencyInjection zapewnia łatwy i wydajny mechanizm tworzenia obiektu wraz z jego zależnością. Kiedy projekt rośnie, zawiera wiele klas z głębokimi zależnościami, które muszą być poprawnie obsługiwane. W przeciwnym razie projekt zakończy się niepowodzeniem. DependencyInjection zapewnia prosty i niezawodny kontener do obsługi zależności. O kontenerach i koncepcji wstrzykiwania zależności dowiemy się w rozdziale Service Container.
Składnik DependencyInjection można zainstalować za pomocą następującego polecenia.
composer require symfony/dependency-injection
Serializator
Komponent Serializer zapewnia opcję konwersji obiektu PHP do określonego formatu, takiego jak XML, JSON, Binary itp., A następnie umożliwia konwersję z powrotem do oryginalnego obiektu bez utraty danych.
Składnik serializatora można zainstalować za pomocą następującego polecenia.
composer require symfony/serializer
Config
Komponent Config zapewnia opcje ładowania, analizowania, odczytywania i sprawdzania poprawności konfiguracji typu XML, YAML, PHP i ini. Zapewnia różne opcje ładowania szczegółów konfiguracji również z bazy danych. Jest to jeden z ważnych składników przydatnych przy konfigurowaniu aplikacji internetowej w jasny i zwięzły sposób. Komponent Config można zainstalować za pomocą następującego polecenia.
composer require symfony/config
ExpressionLanguage
Składnik ExpessionLanguage zapewnia pełnoprawny silnik wyrażeń. Wyrażenia są jednowierszowe przeznaczone do zwracania wartości. Silnik wyrażeń umożliwia łatwe kompilowanie, analizowanie i pobieranie wartości z wyrażenia. Umożliwia użycie jednego lub więcej wyrażeń w środowisku konfiguracyjnym (pliku) przez programistę spoza PHP, na przykład administratora systemu. Komponent ExpressionLanguage można zainstalować za pomocą następującego polecenia.
composer require symfony/expression-language
OptionsResolver
Komponent OptionsResolver umożliwia sprawdzenie poprawności systemu opcji używanego w naszym systemie. Na przykład ustawienie bazy danych jest umieszczane w tablicy, opcja db z hostem, nazwą użytkownika, hasłem itp. Jako klucze. Musisz zweryfikować wpisy przed użyciem go do połączenia z bazą danych. OptionsResolver upraszcza to zadanie, udostępniając prostą klasę OptionsResolver i narzędzie do rozpoznawania nazw metod, które rozwiązuje ustawienia bazy danych i zgłasza je w przypadku jakichkolwiek problemów z walidacją.
$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);
Komponent OptionsResolver można zainstalować za pomocą następującego polecenia.
composer require symfony/options-resolver
Dotenv
Komponent Dotenv zapewnia różne opcje analizowania plików .env i zmiennej zdefiniowanej w nich, aby były dostępne za pośrednictwem getenv(), $_ENVlub $_SERVER. Komponent Dotenv można zainstalować za pomocą następującego polecenia.
composer require symfony/dotenv
Pamięć podręczna
Składnik pamięci podręcznej zapewnia rozszerzenie PSR-6realizacja. Można go użyć do dodania funkcji pamięci podręcznej do naszej aplikacji internetowej. Ponieważ wynikaPSR-6, jest łatwy do rozpoczęcia i może być łatwo używany zamiast innego komponentu pamięci podręcznej opartego na PSR-6. Komponent pamięci podręcznej można zainstalować za pomocą następującego polecenia.
composer require symfony/cache
Intl
Komponent Intl jest biblioteką zastępującą rozszerzenie C Intl. Komponent Intl można zainstalować za pomocą następującego polecenia.
composer require symfony/intl
Tłumaczenie
Komponent tłumaczenia zapewnia różne opcje internacjonalizacji naszej aplikacji. Zwykle szczegóły tłumaczenia na różne języki będą przechowywane w pliku, po jednym pliku na język i będą ładowane dynamicznie podczas działania aplikacji. Istnieją różne formaty zapisu pliku tłumaczenia. Komponent tłumaczenia zapewnia różne opcje ładowania dowolnego typu formatu, takiego jak zwykły plik PHP, CSV, ini, Json, Yaml, plik zasobów ICU itp. Komponent tłumaczenia można zainstalować za pomocą następującego polecenia.
composer require symfony/translation
Przepływ pracy
Komponent Workflow zapewnia zaawansowane narzędzia do przetwarzania skończonej maszyny stanów. Zapewniając tę funkcjonalność w prosty i obiektowy sposób, komponent Workflow umożliwia stosunkowo łatwe zaawansowane programowanie w PHP. Szczegółowo dowiemy się o tym w rozdziale Koncepcja zaawansowana.
Komponent przepływu pracy można zainstalować za pomocą następującego polecenia.
composer require symfony/workflow
Yaml
Składnik Yaml udostępnia opcję, która analizuje format pliku YAML i konwertuje go na tablice PHP. Jest także w stanie napisać plik YAML ze zwykłej tablicy php. Komponent Yaml można zainstalować za pomocą następującego polecenia.
composer require symfony/yaml
Ldap
Komponent Ldap udostępnia klasy PHP do łączenia się z serwerem LDAP lub Active Directory i uwierzytelniania na nim użytkownika. Zapewnia opcję połączenia z kontrolerem domeny Windows. Komponent Ldap można zainstalować za pomocą następującego polecenia.
composer require symfony/ldap
Odpluskwić
Komponent debugowania udostępnia różne opcje umożliwiające debugowanie w środowisku PHP. Zwykle debugowanie kodu PHP jest trudne, ale składnik debugowania udostępnia proste klasy, które ułatwiają proces debugowania i sprawiają, że jest on czysty i uporządkowany. Komponent debugowania można zainstalować za pomocą następującego polecenia.
composer require symfony/debug
Stoper
Komponent Stopwatch udostępnia klasę Stopwatch do profilowania naszego kodu PHP. Proste użycie jest następujące.
use Symfony\Component\Stopwatch\Stopwatch;
$stopwatch = new Stopwatch();
$stopwatch->start('somename'); // our code to profile $profiled_data = $stopwatch->stop('somename'); echo $profiled_data->getPeriods()
Komponent Stopwatch można zainstalować za pomocą następującego polecenia.
composer require symfony/stopwatch
VarDumper
Komponent VarDumper zapewnia lepsze dump()funkcjonować. Wystarczy dołączyć komponent VarDumper i skorzystać z funkcji zrzutu, aby uzyskać lepszą funkcjonalność. Komponent VarDumper można zainstalować za pomocą następującego polecenia.
composer require symfony/var-dumper
BrowserKit
Składnik BrowserKit zapewnia abstrakcyjny interfejs klienta przeglądarki. Może być używany do programowego testowania aplikacji internetowych. Na przykład może zażądać formularza, wprowadzić przykładowe dane i przesłać je, aby programowo znaleźć dowolny problem w formularzu. Komponent BrowserKit można zainstalować za pomocą następującego polecenia.
composer require symfony/browser-kit
PHPUnit Bridge
Komponent PHPUnit Bridge zapewnia wiele opcji usprawniających środowisko testowe PHPUnit. Komponent PHPUnit Bridge można zainstalować za pomocą następującego polecenia.
composer require symfony/phpunit-bridge
Kapitał
Składnik zasobów zapewnia ogólną obsługę zasobów w aplikacji internetowej. Generuje adresy URL dla zasobów, takich jak CSS, HTML, JavaScript, a także przeprowadza konserwację wersji. Szczegółowo sprawdzimy składnik aktywów w rozdziale View Engine. Komponent zasobów można zainstalować za pomocą następującego polecenia.
composer require symfony/asset
CssSelector
Komponent CssSelector zapewnia opcję konwersji selektorów opartych na CSS do wyrażenia XPath. Programista stron internetowych zna wyrażenie selektorów oparte na CSS lepiej niż wyrażenie XPath, ale najbardziej wydajnym wyrażeniem do znalezienia elementu w dokumencie HTML i XML jestXPath Expression.
CssSelector umożliwia programiście zapisanie wyrażenia w selektorach CSS , jednak komponent konwertuje je na wyrażenie XPath przed jego wykonaniem. W związku z tym deweloper ma zaletę polegającą na prostocie selektorów CSS i wydajności wyrażenia XPath.
Komponent CssSelector można zainstalować za pomocą następującego polecenia.
composer require symfony/css-selector
DomCrawler
Komponent DomCrawler zapewnia różne opcje wyszukiwania elementu w dokumencie HTML i XML przy użyciu koncepcji DOM. Zapewnia również opcję użycia wyrażenia XPath do znalezienia elementu. Komponent DomCrawler może być używany razem z komponentem CssSelector do używania selektorów CSS zamiast wyrażenia XPath. Komponent DomCrawler można zainstalować za pomocą następującego polecenia.
composer require symfony/dom-crawler
Formularz
Komponent Form umożliwia łatwe tworzenie formularza w aplikacji internetowej. Szczegółowo nauczymy się programowania formularzy w rozdziale Formularz. Komponent formularza można zainstalować za pomocą następującego polecenia.
composer require symfony/form
HttpFoundation
Składnik HttpFoundation udostępnia warstwę zorientowaną obiektowo zgodnie ze specyfikacją HTTP. Domyślnie PHP dostarcza szczegóły żądań HTTP i odpowiedzi jako obiekt oparty na tablicy, taki jak$_GET, $_POST, $_FILES, $_SESSIONitp. Funkcjonalność oparta na protokole HTTP, taka jak ustawienie pliku cookie, może być wykonana przy użyciu prostej, zwykłej starej funkcji setCookie(). HttpFoundation zapewnia wszystkie funkcje związane z HTTP w niewielkim zestawie klas, takich jak Request, Response, RedirectResponse itp. O tych klasach dowiemy się w dalszych rozdziałach.
Komponent HttpFoundation można zainstalować za pomocą następującego polecenia.
composer require symfony/http-foundation
HttpKernel
Składnik HttpKernel jest głównym składnikiem konfiguracji sieciowej Symfony. Zapewnia wszystkie funkcjonalności wymagane dla aplikacji webowej - od otrzymania plikuRequest sprzeciw wobec odesłania Responseobiekt. Pełna architektura aplikacji internetowej Symfony jest dostarczana przez HttpKernel, jak omówiono w architekturze frameworka internetowego Symfony.
Komponent HttpKernel można zainstalować za pomocą następującego polecenia.
composer require symfony/http-kernel
Wytyczanie
Komponent routingu mapuje żądanie HTTP na predefiniowany zestaw zmiennych konfiguracyjnych. Routing decyduje, która część naszej aplikacji powinna obsłużyć żądanie. Więcej o routingu dowiemy się w rozdziale Routing.
Komponent routingu można zainstalować za pomocą następującego polecenia.
composer require symfony/filesystem
Tworzenie szablonów
Komponent szablonów zapewnia infrastrukturę niezbędną do zbudowania wydajnego systemu szablonów. Symfony używa komponentu Templating do implementacji silnika View. Dowiemy się więcej o komponencie tworzenia szablonów w rozdziale Wyświetl silnik.
Komponent do tworzenia szablonów można zainstalować za pomocą następującego polecenia.
composer require symfony/templating
Validator
Komponent Validator zapewnia implementację JSR-303 Bean Validation Specification. Może służyć do walidacji formularza w środowisku sieciowym. Więcej o Walidatorze dowiemy się w rozdziale Walidacja.
Komponent Validator można zainstalować za pomocą następującego polecenia.
composer require symfony/validator
Bezpieczeństwo
Komponent bezpieczeństwa zapewnia kompletny system bezpieczeństwa dla naszej aplikacji internetowej, czy to podstawowe uwierzytelnianie HTTP, uwierzytelnianie HTTP, uwierzytelnianie interaktywne oparte na formularzach, logowanie certyfikacyjne X.509 itp. Zapewnia również mechanizm autoryzacji oparty na roli użytkownika poprzez wbudowany system ACL . Dowiemy się więcej w rozdziale Advanced Concept.
Komponent bezpieczeństwa można zainstalować za pomocą następującego polecenia.
composer require symfony/security
W każdej aplikacji liczba obiektów rośnie wraz z rozwojem aplikacji. Wraz ze wzrostem liczby obiektów wzrasta również zależność między obiektami. Aby aplikacja zakończyła się sukcesem, należy odpowiednio obsłużyć zależność od obiektu.
Jak omówiono w rozdziale Komponenty, Symfony zapewnia łatwy i wydajny komponent, DependencyInjectiondo obsługi zależności obiektu. Kontener usług to kontener obiektów z odpowiednio rozwiązaną zależnością między nimi. W tym rozdziale nauczmy się, jak korzystać z komponentu DependencyInjection.
Stwórzmy plik Greeterklasa. Celem klasy Greeter jest powitanie użytkownika, jak pokazano w poniższym przykładzie.
$greeter = new Greeter('Hi'); $greeter->greet('Jon'); // print "Hi, Jon"
Pełny kod klasy Greeter jest następujący.
class Greeter {
private $greetingText; public function __construct($greetingText) {
$this->greetingText = $greetingText;
}
public function greet($name) { echo $this->greetingText . ", " . $name . "\r\n";
}
}
Teraz dodajmy klasę Greeter do kontenera usługi. Symfony zapewniaContainerBuilderaby utworzyć nowy kontener. Po utworzeniu kontenera można zarejestrować w nim klasę Greeter za pomocą metody register kontenera.
use Symfony\Component\DependencyInjection\ContainerBuilder;
$container = new ContainerBuilder();
$container
->register('greeter', 'Greeter')
->addArgument('Hi');
Tutaj użyliśmy argumentu statycznego, aby określić tekst powitania, Cześć. Symfony zapewnia również dynamiczne ustawianie parametrów. Aby użyć parametru dynamicznego, musimy wybrać nazwę i określić ją między%, a parametr można ustawić za pomocą kontenerasetParameter metoda.
$container = new ContainerBuilder();
$container ->register('greeter', 'Greeter') ->addArgument('%greeter.text%'); $container->setParameter('greeter.text', 'Hi');
Zarejestrowaliśmy klasę Greeter z odpowiednim ustawieniem. Teraz możemy poprosić kontener o dostarczenie poprawnie skonfigurowanego obiektu Greeter przy użyciu konteneraget metoda.
$greeter = $container->get('greeter');
$greeter->greet('Jon'); // prints "Hi, Jon"
Pomyślnie zarejestrowaliśmy klasę Greeter w kontenerze, pobraliśmy ją z kontenera i wykorzystaliśmy. Teraz stwórzmy kolejną klasęUser, które używają klasy Greeter i zobacz, jak ją zarejestrować.
class User {
private $greeter;
public $name; public $age;
public function setGreeter(\Greeter $greeter) { $this->greeter = $greeter; } public function greet() { $this->greeter->greet($this->name);
}
}
Klasa User pobiera klasę Greeter za pomocą jednej ze swoich metod ustawiających,setGreeter. W tym scenariuszu Symfony zapewnia metodę,addMethodCall i klasą, Reference odwołać się do innej klasy, jak pokazano w poniższym kodzie.
use Symfony\Component\DependencyInjection\Reference;
$container
->register('user', 'User')
->addMethodCall('setGreeter', array(new Reference('greeter')));
Wreszcie zarejestrowaliśmy dwie klasy, Greeter i Usermając między nimi silny związek. Teraz możemy bezpiecznie pobrać obiekt User z odpowiednio skonfigurowaną klasą Greeter z kontenera, jak pokazano w poniższym kodzie.
$container->setParameter('greeter.text', 'Hi'); $user = $container->get('user'); $user->name = "Jon";
$user->age = 20; $user->greet(); // Prints "Hi, Jon"
Widzieliśmy, jak skonfigurować obiekt w kontenerze przy użyciu samego PHP. Symfony zapewnia również inne mechanizmy. Są to pliki konfiguracyjne XML i YAML. Zobaczmy, jak skonfigurować kontener za pomocą YAML. W tym celu zainstalujsymfony/config i symfony/yaml komponenty wraz z symfony/dependency-injection składniki.
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
Konfiguracja YAML zostanie zapisana w osobnym pliku, services.yml. Konfiguracja YAML składa się z dwóch sekcji,parameters i services. Sekcja Parametry definiuje wszystkie wymagane parametry. Sekcja usług definiuje wszystkie obiekty. Sekcja usług jest dalej podzielona na wiele sekcji, a mianowicie:class, arguments, i calls. Klasa określa aktualną klasę. Argumenty określa argumenty konstruktora. Na koniec wywołania określają metody ustawiające. Do innej klasy można odwołać się za pomocą symbolu @, @greeter.
parameters:
greeter.text: 'Hello'
services:
greeter:
class: Greeter
arguments: ['%greeter.text%']
user:
class: User
calls:
- [setGreeter, ['@greeter']]
Teraz, services.yml można załadować i skonfigurować za pomocą FileLoader i YamlFileLoader jak pokazano w poniższym kodzie.
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();
Pełna lista kodów jest następująca.
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']]
Framework sieciowy Symfony szeroko wykorzystuje komponent iniekcji zależności. Wszystkie komponenty są powiązane przez scentralizowany kontener usług. Framework sieciowy Symfony eksponuje kontener w całościController przez containerwłasność. Za jego pośrednictwem możemy pobrać wszystkie zarejestrowane w nim obiekty, powiedzmy logger, mailer itp.
$logger = $this->container->get('logger');
$logger->info('Hi');
Aby znaleźć obiekt zarejestrowany w kontenerze, użyj następującego polecenia.
cd /path/to/app
php bin/console debug:container
Istnieje około 200+ obiektów w hello aplikacja internetowa utworzona w rozdziale dotyczącym instalacji.
Symfony zapewnia programowanie oparte na zdarzeniach poprzez jego EventDispatcherskładnik. Każda aplikacja korporacyjna wymaga programowania opartego na zdarzeniach, aby utworzyć aplikację o dużych możliwościach dostosowania. Zdarzenia to jedno z głównych narzędzi interakcji obiektów. Bez zdarzeń obiekt nie współdziała efektywnie.
Proces programowania opartego na zdarzeniach można podsumować jako - Obiekt o nazwie Event sourceprosi obiekt centralnego dyspozytora o zarejestrowanie zdarzenia, na przykład user.registered. Jeden lub więcej obiektów, zwanych listener, pyta obiekt centralnego dyspozytora, że chce nasłuchiwać określonego zdarzenia, np. User.registered. W pewnym momencie obiekt Źródło zdarzenia prosi obiekt centralnego dyspozytora o wywołanie zdarzenia, na przykład user.registered, wraz z obiektem Event z niezbędnymi informacjami. Centralny dyspozytor informuje wszystkie obiekty nasłuchujące o zdarzeniu, na przykład user.registered i jego obiekt Event *.
W programowaniu opartym na zdarzeniach mamy cztery typy obiektów: źródło zdarzenia, nasłuchiwanie zdarzeń, dyspozytor parzysty i samo zdarzenie.
Napiszmy prostą aplikację, aby zrozumieć koncepcję.
Step 1 - Stwórz projekt, event-dispatcher-example.
cd /path/to/dir
mkdir event-dispatcher-example
cd event-dispatcher-example
composer require symfony/event-dispatcher
Step 2 - Utwórz klasę, .User.
class User {
public $name;
public $age; } $user = new User();
$user->name = "Jon"; $user->age = 25
Step 3 - Utwórz wydarzenie, 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);
Tutaj, UserRegisteredEvent ma dostęp do Userobiekt. Nazwa wydarzenia touser.registered.
Step 4 - Utwórz słuchacza, 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 - Utwórz obiekt rozsyłacza zdarzeń.
use Symfony\Component\EventDispatcher\EventDispatcher;
$dispatcher = new EventDispatcher();
Step 6 - Połącz detektor i zdarzenie za pomocą obiektu dyspozytora i jego metody, addListener.
$dispatcher ->addListener( UserRegisteredEvent::NAME, array($listener, 'onUserRegistrationAction'));
Możemy również dodać anonimową funkcję jako detektor zdarzeń, jak pokazano w poniższym kodzie.
$dispatcher ->addListener( UserRegisteredEvent::NAME, function(Event $event) {
$user = $event->getUser();
echo $user->name . "\r\n";
});
Step 7 - Na koniec odpal / wyślij zdarzenie metodą dyspozytora zdarzeń, dispatch.
$dispatcher->dispatch(UserRegisteredEvent::NAME, $event);
Pełna lista kodów jest następująca.
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);
?>
Wynik
Jon
Jon
25
Framework sieciowy Symfony ma wiele zdarzeń i można zarejestrować słuchacza dla tych zdarzeń i odpowiednio go zaprogramować. Jednym z przykładowych zdarzeń jest kernel.exception, a odpowiadającym mu zdarzeniemGetResponseForExceptionEvent, który przechowuje obiekt odpowiedzi (dane wyjściowe żądania internetowego). Służy do przechwytywania wyjątku i modyfikowania odpowiedzi za pomocą ogólnych informacji o błędzie zamiast pokazywania użytkownikom błędu czasu wykonania.
Jak omówiliśmy wcześniej, język wyrażeń jest jedną z najistotniejszych cech aplikacji Symfony. Wyrażenie Symfony jest tworzone głównie do użytku w środowisku konfiguracyjnym. Umożliwia nieprogramistom skonfigurowanie aplikacji internetowej przy niewielkim wysiłku. Stwórzmy prostą aplikację do testowania wyrażenia.
Step 1 - Stwórz projekt, expression-language-example.
cd /path/to/dir
mkdir expression-language-example
cd expression-language-example
composer require symfony/expression-language
Step 2 - Utwórz obiekt wyrażenia.
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
$language = new ExpressionLanguage();
Step 3 - Przetestuj proste wyrażenie.
echo "Evaluated Value: " . $language->evaluate('10 + 12') . "\r\n" ; echo "Compiled Code: " . $language->compile('130 % 34') . "\r\n" ;
Step 4 - Wyrażenie Symfony jest tak potężne, że może przechwytywać obiekt PHP i jego własność również w języku wyrażeń.
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";
Tutaj wyrażenie product.price i product.price > 5 przechwycić $product własność obiektu price i oceń wynik.
Pełne kodowanie jest następujące.
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";
?>
Wynik
Evaluated Value: 22
Compiled Code: (130 % 34)
Product price is 10
Is Product price higher than 5: 1
Pakiet Symfony to zbiór plików i folderów zorganizowanych według określonej struktury. Pakiety są modelowane w taki sposób, aby można je było ponownie wykorzystać w wielu aplikacjach. Sama aplikacja główna jest spakowana w pakiecie i jest zwykle nazywanaAppBundle.
Pakiet może być spakowany specjalnie dla aplikacji, takiej jak AdminBundle (sekcja administratora), BlogBundle (blog witryny) itp. Takie pakiety nie mogą być współużytkowane między aplikacjami. Zamiast tego możemy modelować pewną część aplikacji, taką jak blogi, jako ogólny pakiet, dzięki czemu możemy po prostu skopiować pakiet z jednej aplikacji do innej, aby ponownie wykorzystać funkcjonalność bloga.
Struktura pakietu
Podstawowa struktura pakietu jest następująca.
Controller - Tutaj należy umieścić wszystkie kontrolery.
DependencyInjection - Cały kod i konfigurację związane z wstrzykiwaniem zależności należy umieścić tutaj.
Resources/config - Tutaj umieszczane są konfiguracje związane z pakietami.
Resources/view - Tutaj umieszczane są szablony widoków związane z pakietami.
Resources/public - Tutaj umieszczane są arkusze stylów związane z pakietami, skrypty JavaScript, obrazy itp.
Tests - Pliki testów jednostkowych związane z pakietami są umieszczane tutaj.
Tworzenie pakietu
Stwórzmy prosty pakiet, TutorialspointDemoBundle w naszym HelloWorld podanie.
Step 1- Wybierz przestrzeń nazw. Przestrzeń nazw pakietu powinna zawierać nazwę dostawcy i nazwę pakietu. W naszym przypadku tak jestTutorialspoint\DemoBundle.
Step 2 - Utwórz pustą klasę, TutorialspointDemoBundle poprzez rozszerzenie Bundle klasę i umieść ją pod src/Tutorialspoint/DemoBundle.
namespace Tutorialspoint\DemoBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class TutorialspointDemoBundle extends Bundle {
}
Step 3 - Zarejestruj klasę na liście pakietów obsługiwanych przez aplikację w formacie AppKernel klasa.
public function registerBundles() {
$bundles = array( // ... // register your bundle new Tutorialspoint\DemoBundle\TutorialspointDemoBundle(), ); return $bundles;
}
To wszystko jest potrzebne do utworzenia pustego pakietu, a wszystkie inne koncepcje są takie same jak w aplikacji. Symfony udostępnia również polecenie konsoligenerate:bundle aby uprościć proces tworzenia nowego pakietu, który jest następujący.
php bin/console generate:bundle --namespace = Tutorialspoint/DemoBundle
Wynik
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 :).
Ten rozdział wyjaśnia jak stworzyć prostą aplikację we frameworku Symfony. Jak wspomniano wcześniej, wiesz, jak stworzyć nowy projekt w Symfony.
Weźmy na przykład dane „ucznia”. Zacznijmy od utworzenia projektu o nazwie „student” za pomocą następującego polecenia.
symfony new student
Po wykonaniu polecenia tworzony jest pusty projekt.
Kontroler
Symfony jest oparty na wzorcu programistycznym Model-View-Controller (MVC). MVC to podejście programowe, które oddziela logikę aplikacji od prezentacji. Kontroler odgrywa ważną rolę w Symfony Framework. Wszystkie strony internetowe w aplikacji muszą być obsługiwane przez kontroler.
DefaultController znajduje się w “src/AppBundle/Controller”. Możesz tam stworzyć własną klasę kontrolera.
Przejdź do lokalizacji “src/AppBundle/Controller” i utwórz nowy StudentController klasa.
Poniżej znajduje się podstawowa składnia StudentController klasa.
StudentController.php
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
class StudentController {
}
Teraz utworzyłeś StudentController. W następnym rozdziale omówimy bardziej szczegółowo kontroler.
Utwórz trasę
Po utworzeniu kontrolera musimy skierować do określonej strony. Mapy trasowania identyfikatora URI żądania do metody określonego kontrolera.
Poniżej przedstawiono podstawową składnię routingu.
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!');
}
}
W powyższej składni @Route(“/student/home”)jest trasa. Definiuje wzorzec adresu URL strony.
homeAction() to metoda akcji, w której można zbudować stronę i zwrócić obiekt Response.
W następnym rozdziale omówimy szczegółowo routing. Teraz poproś o adres URL „http: // localhost: 8000 / student / home”, a otrzymasz następujący wynik.
Wynik
Kontroler jest odpowiedzialny za obsługę każdego żądania przychodzącego do aplikacji Symfony. Administrator odczytuje informacje z żądania. Następnie tworzy i zwraca obiekt odpowiedzi do klienta.
Według Symfony, DefaultController znajduje się w “src/AppBundle/Controller”. Jest zdefiniowany w następujący sposób.
DefaultController.php
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller {
}
Tutaj HttpFoundation składnik definiuje warstwę zorientowaną obiektowo dla specyfikacji HTTP, a FrameworkBundle zawiera większość „podstawowych” funkcjonalności frameworka.
Obiekt żądania
Klasa Request jest zorientowaną obiektowo reprezentacją komunikatu żądania HTTP.
Tworzenie obiektu żądania
Żądanie można utworzyć za pomocą createFromGlobals() metoda.
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
Możesz zasymulować żądanie za pomocą Globals. Zamiast tworzyć żądanie w oparciu o globalne PHP, możesz również symulować żądanie.
$request = Request::create(
'/student',
'GET',
array('name' => 'student1')
);
Tutaj create() metoda tworzy żądanie na podstawie identyfikatora URI, metody i niektórych parametrów.
Przesłanianie obiektu żądania
Możesz nadpisać zmienne globalne PHP za pomocą overrideGlobals()metoda. Jest zdefiniowany w następujący sposób.
$request->overrideGlobals();
Dostęp do obiektu żądania
Żądanie strony internetowej można uzyskać w kontrolerze (metoda akcji) za pomocą getRequest() metoda kontrolera podstawowego.
$request = $this->getRequest();
Identyfikacja obiektu żądania
Jeśli chcesz zidentyfikować żądanie w swojej aplikacji, “PathInfo"metoda zwróci unikalną tożsamość adresu URL żądania. Jest zdefiniowany w następujący sposób.
$request->getPathInfo();
Obiekt odpowiedzi
Jedynym wymaganiem dla kontrolera jest zwrócenie obiektu Response. Obiekt Response przechowuje wszystkie informacje z danego żądania i odsyła je z powrotem do klienta.
Oto prosty przykład.
Przykład
use Symfony\Component\HttpFoundation\Response;
$response = new Response(‘Default'.$name, 10);
Możesz zdefiniować obiekt Response w JSON w następujący sposób.
$response = new Response(json_encode(array('name' => $name)));
$response->headers->set('Content-Type', 'application/json');
Konstruktor odpowiedzi
Konstruktor zawiera trzy argumenty -
- Treść odpowiedzi
- Kod stanu
- Tablica nagłówków HTTP
Poniżej znajduje się podstawowa składnia.
use Symfony\Component\HttpFoundation\Response;
$response = new Response(
'Content',
Response::HTTP_OK,
array('content-type' => 'text/html')
);
Na przykład możesz przekazać argument content jako,
$response->setContent(’Student details’);
Podobnie możesz przekazać także inne argumenty.
Wysyłanie odpowiedzi
Możesz wysłać odpowiedź do klienta przy użyciu send()metoda. Jest zdefiniowany w następujący sposób.
$response->send();
Aby przekierować klienta na inny adres URL, możesz użyć rozszerzenia RedirectResponse klasa.
Jest zdefiniowany w następujący sposób.
use Symfony\Component\HttpFoundation\RedirectResponse;
$response = new RedirectResponse('http://tutorialspoint.com/');
FrontController
Pojedynczy plik PHP, który obsługuje każde żądanie przychodzące do Twojej aplikacji. FrontController wykonuje routing różnych adresów URL do wewnętrznie różnych części aplikacji.
Poniżej znajduje się podstawowa składnia 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();
Tutaj in_array() funkcja przeszukuje tablicę pod kątem określonej wartości.
Mapy trasowania identyfikatora URI żądania do metody określonego kontrolera. Ogólnie każdy identyfikator URI składa się z następujących trzech części -
- Segment nazwy hosta
- Segment ścieżki
- Segment zapytania
Na przykład w URI / URL, http://www.tutorialspoint.com/index?q=data, www.tutorialspoint.comto segment nazwy hosta, indeks to segment ścieżki, a q = data to segment zapytania. Generalnie routing sprawdza, czy segment strony jest zgodny z zestawem ograniczeń. Jeśli jakieś ograniczenie pasuje, zwraca zestaw wartości. Jedną z głównych wartości jest kontroler.
Adnotacje
Adnotacja odgrywa ważną rolę w konfiguracji aplikacji Symfony. Adnotacja upraszcza konfigurację poprzez zadeklarowanie konfiguracji w samym kodzie. Adnotacja to nic innego jak dostarczanie metainformacji o klasie, metodach i właściwościach. Routing intensywnie korzysta z adnotacji. Mimo że trasowanie można wykonać bez adnotacji, opisy w dużym stopniu upraszczają trasowanie.
Poniżej znajduje się przykładowa adnotacja.
/**
* @Route(“/student/home”)
*/
public function homeAction() {
// ...
}
Koncepcje routingu
Rozważmy klasę StudentController utworzoną w projekcie „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() {
}
}
Tutaj routing wykonuje dwa kroki. Jeśli pójdziesz do/student/home, wówczas dopasowywana jest pierwsza trasa homeAction()jest wykonywany. W przeciwnym razie, jeśli przejdziesz do/student/about, dopasowywana jest druga trasa aboutAction() jest wykonywany.
Dodawanie formatów symboli wieloznacznych
Weź pod uwagę, że masz podzieloną na strony listę rekordów uczniów z adresami URL, takimi jak / student / 2 i / student / 3, odpowiednio dla strony 2 i 3. Następnie, jeśli chcesz zmienić ścieżkę trasy, możesz użyć formatów symboli wieloznacznych.
Przykład
// 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) {
// ...
}
}
Tutaj \d+ to wyrażenie regularne pasujące do cyfry o dowolnej długości.
Przypisz symbol zastępczy
W routingu można przypisać wartość zastępczą. Jest zdefiniowany w następujący sposób.
// 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) {
// ...
}
}
Tutaj, jeśli przejdziesz do / student, plik student_about route będzie pasować i $page domyślnie przyjmuje wartość 1.
Przekierowanie do strony
Jeśli chcesz przekierować użytkownika na inną stronę, użyj rozszerzenia redirectToRoute() i redirect() metody.
public function homeAction() {
// redirect to the "homepage" route
return $this->redirectToRoute('homepage');
// redirect externally
\return $this->redirect('http://example.com/doc');
}
Generowanie adresów URL
Aby wygenerować adres URL, rozważ nazwę trasy, student_name i nazwa wieloznaczna, student-namesużywany w ścieżce dla tej trasy. Pełna lista dotycząca generowania adresu URL jest zdefiniowana w następujący sposób.
class StudentController extends Controller {
public function aboutAction($name) {
// ...
// /student/student-names
$url = $this->generateUrl(
‘student_name’,
array(‘name’ =>
’student-names’)
);
}
}
StudentController
Rozważmy prosty przykład routingu w klasie StudentController w następujący sposób.
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>'
);
}
}
Teraz poproś o adres URL,”http://localhost:8000/student/home” i daje następujący wynik.
Podobnie możesz utworzyć inną trasę dla aboutAction() także.
Warstwa widoku to warstwa prezentacji aplikacji MVC. Oddziela logikę aplikacji od logiki prezentacji.
Gdy kontroler musi wygenerować HTML, CSS lub jakąkolwiek inną zawartość, przekazuje zadanie do silnika szablonów.
Szablony
Szablony to w zasadzie pliki tekstowe używane do generowania dowolnych dokumentów tekstowych, takich jak HTML, XML itp. Służy do oszczędzania czasu i zmniejszania liczby błędów.
Domyślnie szablony mogą znajdować się w dwóch różnych lokalizacjach -
app/Resources/views/- Katalog widoków aplikacji może zawierać układy aplikacji i szablony pakietu aplikacji. Zastępuje również szablony pakietów innych firm.
vendor/path/to/Bundle/Resources/views/ - Każdy pakiet strony trzeciej zawiera swoje szablony w katalogu „Zasoby / widoki /”.
Twig Engine
Symfony używa potężnego języka szablonów o nazwie Twig. Twig pozwala w bardzo łatwy sposób pisać zwięzłe i czytelne szablony. Szablony Twig są proste i nie przetwarzają tagów PHP. Twig wykonuje kontrolę białych znaków, piaskownicę i automatyczne usuwanie znaków HTML.
Składnia
Twig zawiera trzy typy specjalnej składni -
{{ ... }} - Drukuje zmienną lub wynik wyrażenia do szablonu.
{% ... %} - Znacznik sterujący logiką szablonu. Służy głównie do wykonywania funkcji.
{# ... #}- Składnia komentarzy. Służy do dodawania komentarzy jedno- lub wielowierszowych.
Szablon podstawy gałązki znajduje się pod adresem “app/Resources/views/base.html.twig”.
Przykład
Przeanalizujmy prosty przykład wykorzystujący silnik twig.
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');
}
}
Tutaj render() renderuje szablon i umieszcza tę zawartość w obiekcie Response.
Teraz przejdź do katalogu „views” i utwórz folder „student”, a wewnątrz tego folderu utwórz plik „home.html.twig”. Dodaj następujące zmiany w pliku.
home.html.twig
//app/Resources/views/student/home.html.twig
<h3>Student application!</h3>
Wynik można uzyskać, prosząc o adres URL „http: // localhost: 8000 / student / home”.
Domyślnie Twig zawiera długą listę tagów, filtrów i funkcji. Przeanalizujmy szczegółowo jeden po drugim.
Tagi
Twig obsługuje następujące ważne tagi -
Zrobić
Plik dotag wykonuje podobne funkcje jak wyrażenie regularne z tym wyjątkiem, że niczego nie drukuje. Jego składnia jest następująca -
{% do 5 + 6 %}
Zawierać
Instrukcja include zawiera szablon i zwraca wyrenderowaną zawartość tego pliku do bieżącej przestrzeni nazw. Jego składnia jest następująca -
{% include 'template.html' %}
Rozciąga się
Znacznika extends można użyć do rozszerzenia szablonu z innego. Jego składnia jest następująca -
{% extends "template.html" %}
Blok
Blok działa jak symbol zastępczy i zastępuje zawartość. Nazwy bloków składają się ze znaków alfanumerycznych i podkreśleń. Na przykład,
<title>{% block title %}{% endblock %}</title>
Osadzać
Plik embedtag wykonuje kombinację włączania i rozszerzania. Pozwala na dołączenie zawartości innego szablonu. Umożliwia również nadpisanie dowolnego bloku zdefiniowanego w dołączonym szablonie, na przykład podczas rozszerzania szablonu. Jego składnia jest następująca -
{% embed “new_template.twig” %}
{# These blocks are defined in “new_template.twig" #}
{% block center %}
Block content
{% endblock %}
{% endembed %}
Filtr
Sekcje filtrów umożliwiają zastosowanie zwykłych filtrów Twig do bloku danych szablonu. Na przykład,
{% filter upper %}
symfony framework
{% endfilter %}
Tutaj tekst zostanie zamieniony na wielkie litery.
Dla
Forpętla pobiera każdy element w sekwencji. Na przykład,
{% for x in 0..10 %}
{{ x }}
{% endfor %}
Gdyby
Plik ifinstrukcja w Twig jest podobna do PHP. Wyrażenie przyjmuje wartość prawda lub fałsz. Na przykład,
{% if value == true %}
<p>Simple If statement</p>
{% endif %}
Filtry
Twig zawiera filtry. Służy do modyfikowania treści przed renderowaniem. Oto niektóre z godnych uwagi filtrów.
Długość
Filtr długości zwraca długość łańcucha. Jego składnia jest następująca -
{% if name|length > 5 %}
...
{% endif %}
Niższy
Dolny filtr konwertuje wartość na małe litery. Na przykład,
{{ 'SYMFONY'|lower }}
Dałoby to następujący wynik -
symfony
Podobnie możesz spróbować wielkich liter.
Zastąpić
Filtr replace formatuje dany ciąg, zastępując symbole zastępcze. Na przykład,
{{ "tutorials point site %si% and %te%."|replace({'%si%': web, '%te%': "site"}) }}
To da następujący wynik -
tutorials point website
Tytuł
Filtr tytułu zwraca wersję wartości w przypadku tytułu. Na przykład,
{{ 'symfony framework '|title }}
To da następujący wynik -
Symfony Framework
Sortować
Filtr sortowania sortuje tablicę. Jego składnia jest następująca -
{% for user in names|sort %}
...
{% endfor %}
Trym
Filtr przycinający przycina białe znaki (lub inne znaki) od początku i końca łańcucha. Na przykład,
{{ ' Symfony! '|trim }}
To da następujący wynik -
Symfony!
Funkcje
Twig obsługuje funkcje. Służy do uzyskania określonego wyniku. Poniżej przedstawiono niektóre z ważnych funkcji Twig.
Atrybut
Plik attributefunkcja może służyć do uzyskania dostępu do „dynamicznego” atrybutu zmiennej. Jego składnia jest następująca -
{{ attribute(object, method) }}
{{ attribute(object, method, arguments) }}
{{ attribute(array, item) }}
Na przykład,
{{ attribute(object, method) is defined ? 'Method exists' : 'Method does not exist' }}
Stały
Funkcja Constant zwraca stałą wartość dla określonego ciągu. Na przykład,
{{ constant('Namespace\\Classname::CONSTANT_NAME') }}
Cykl
Funkcja cyklu wykonuje cykle na tablicy wartości. Na przykład,
{% set months = [‘Jan’, ‘Feb’, ‘Mar’] %}
{% for x in 0..12 %}
{ cycle(months, x) }}
{% endfor %}
Data
Konwertuje argument na datę, aby umożliwić porównanie dat. Na przykład,
<p>Choose your location before {{ 'next Monday'|date('M j, Y') }}</p>
To da następujący wynik -
Choose your location before May 15, 2017
Argument musi być w jednym z obsługiwanych przez PHP formatów daty i czasu.
Jako drugi argument możesz podać strefę czasową.
Wysypisko
Funkcja zrzutu zrzuca informacje o zmiennej szablonu. Na przykład,
{{ dump(user) }}
Maks
Funkcja max zwraca największą wartość sekwencji. Na przykład,
{{ max(1, 5, 9, 11, 15) }}
Min
Funkcja min zwraca najmniejszą wartość sekwencji. Na przykład,
{{ min(1, 3, 2) }}
Zawierać
Funkcja include zwraca wyrenderowaną zawartość szablonu. Na przykład,
{{ include('template.html') }}
Losowy
Funkcja losowa generuje losową wartość. Na przykład,
{{ random([‘Jan’, ‘Feb’, ‘Mar’, ‘Apr’]) }}
{# example output: Jan #}
Zasięg
Funkcja Range zwraca listę zawierającą arytmetyczny postęp liczb całkowitych. Na przykład,
{% for x in range(1, 5) %}
{{ x }},
{% endfor %}
To da następujący wynik -
1,2,3,4,5
Układy
Układ reprezentuje wspólne części wielu widoków, np. Nagłówek strony i stopkę.
Dziedziczenie szablonów
Szablon może być używany przez inny. Możemy to osiągnąć dzięki koncepcji dziedziczenia szablonów. Dziedziczenie szablonów umożliwia zbudowanie podstawowego szablonu „układu”, który zawiera wszystkie typowe elementy witryny internetowej zdefiniowane jako bloki.
Weźmy prosty przykład, aby dowiedzieć się więcej o dziedziczeniu szablonów.
Przykład
Rozważmy podstawowy szablon znajdujący się w „app / Resources / views / base.html.twig”. Dodaj następujące zmiany w pliku.
base.html.twig
<!DOCTYPE html>
<html>
<head>
<meta charset = "UTF-8">
<title>{% block title %}Parent template Layout{% endblock %}</title>
</head>
</html>
Teraz przejdź do pliku szablonu indeksu znajdującego się w „app / Resources / views / default / index.html.twig” . Dodaj w nim następujące zmiany.
index.html.twig
{% extends 'base.html.twig' %}
{% block title %}Child template Layout{% endblock %}
Tutaj {% extends %}informuje silnik tworzenia szablonów, aby najpierw ocenił szablon podstawowy, który konfiguruje układ i definiuje blok. Następnie renderowany jest szablon potomny. Szablon podrzędny może rozszerzyć układ bazowy i zastąpić tabelkę rysunkową. Teraz poproś o adres URL „http: // localhost: 8000” i uzyskaj jego wynik.
Majątek
Zasób zarządza generowaniem adresów URL i wersjonowaniem zasobów internetowych, takich jak arkusze stylów CSS, pliki JavaScript i pliki obrazów.
JavaScript
Aby dołączyć pliki JavaScript, użyj rozszerzenia javascripts tag w dowolnym szablonie.
{# Include javascript #}
{% block javascripts %}
{% javascripts '@AppBundle/Resources/public/js/*' %}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
Arkusze stylów
Aby dołączyć pliki arkuszy stylów, użyj rozszerzenia stylesheets tag w dowolnym szablonie
{# include style sheet #}
{% block stylesheets %}
{% stylesheets 'bundles/app/css/*' filter = 'cssrewrite' %}
<link rel = "stylesheet" href="{{ asset_url }}" />
{% endstylesheets %}
{% endblock %}
Obrazy
Aby dołączyć obraz, możesz użyć tagu obrazu. Jest zdefiniowany w następujący sposób.
{% image '@AppBundle/Resources/public/images/example.jpg' %}
<img src = "{{ asset_url }}" alt = "Example" />
{% endimage %}
Aktywa złożone
Możesz połączyć wiele plików w jeden. Pomaga to zmniejszyć liczbę żądań HTTP i zapewnia lepszą wydajność frontonu.
{% javascripts
'@AppBundle/Resources/public/js/*'
'@AcmeBarBundle/Resources/public/js/form.js'
'@AcmeBarBundle/Resources/public/js/calendar.js' %}
<script src = "{{ asset_url }}"></script>
{% endjavascripts %}
We frameworku sieciowym Symfony model odgrywa ważną rolę. To są podmioty gospodarcze. Są dostarczane przez klientów lub pobierane z wewnętrznej bazy danych, przetwarzane zgodnie z regułami biznesowymi i utrwalane z powrotem w bazie danych. Są to dane przedstawione przez Poglądy. W tym rozdziale poznajmy modele i ich interakcję z systemem zaplecza.
Model bazy danych
Musimy zmapować nasze modele do elementów relacyjnej bazy danych zaplecza, aby bezpiecznie i wydajnie pobierać i utrwalać modele. To mapowanie można wykonać za pomocą narzędzia do mapowania relacyjnego obiektu (ORM). Symfony dostarcza oddzielny pakiet,DoctrineBundle, który integruje Symfony z narzędziem ORM do bazy danych PHP innej firmy, Doctrine.
Doktryna ORM
Domyślnie framework Symfony nie dostarcza żadnego komponentu do pracy z bazami danych. Ale ściśle integruje się zDoctrine ORM. Doctrine zawiera kilka bibliotek PHP używanych do przechowywania baz danych i mapowania obiektów.
Poniższy przykład pomoże ci zrozumieć, jak działa Doctrine, jak skonfigurować bazę danych oraz jak zapisywać i odzyskiwać dane.
Przykład doktryny ORM
W tym przykładzie najpierw skonfigurujemy bazę danych i utworzymy obiekt Studenta, a następnie wykonamy w nim pewne operacje.
Aby to zrobić, musimy wykonać następujące kroki.
Krok 1: Utwórz aplikację Symfony
Utwórz aplikację Symfony, dbsample za pomocą następującego polecenia.
symfony new dbsample
Krok 2: Skonfiguruj bazę danych
Ogólnie informacje o bazie danych są konfigurowane w pliku „app / config / parameters.yml”.
Otwórz plik i dodaj następujące zmiany.
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
Teraz Doctrine ORM może połączyć się z bazą danych.
Krok 3: Utwórz bazę danych
Wydaj następujące polecenie, aby wygenerować bazę danych „Studentsdb”. Ten krok służy do wiązania bazy danych w Doctrine ORM.
php bin/console doctrine:database:create
Po wykonaniu polecenia automatycznie generuje pustą bazę danych „Studentsdb”. Na ekranie możesz zobaczyć następującą odpowiedź.
Created database `studentsdb` for connection named default
Krok 4: Informacje o mapie
Informacje o mapowaniu to nic innego jak „metadane”. Jest to zbiór reguł, które dokładnie informują Doctrine ORM, w jaki sposób klasa Student i jej właściwości są mapowane do określonej tabeli bazy danych.
Cóż, te metadane można określić w wielu różnych formatach, w tym YAML, XML lub możesz bezpośrednio przekazać klasę Studenta za pomocą adnotacji. Jest zdefiniowany w następujący sposób.
Student.php
Dodaj następujące zmiany w pliku.
<?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;
}
Tutaj nazwa tabeli jest opcjonalna. Jeśli nazwa tabeli nie zostanie określona, zostanie ona określona automatycznie na podstawie nazwy klasy jednostki.
Krok 5: Powiązanie jednostki
Doctrine tworzy dla Ciebie proste klasy encji. Pomaga budować każdą jednostkę.
Wydaj następujące polecenie, aby wygenerować jednostkę.
php bin/console doctrine:generate:entities AppBundle/Entity/Student
Następnie zobaczysz następujący wynik, a jednostka zostanie zaktualizowana.
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;
}
}
Krok 6: Walidacja mapy
Po utworzeniu jednostek należy sprawdzić poprawność mapowań za pomocą następującego polecenia.
php bin/console doctrine:schema:validate
To da następujący wynik -
[Mapping] OK - The mapping files are correct.
[Database] FAIL - The database schema is not in sync with the current mapping file
Ponieważ nie utworzyliśmy tabeli uczniów, jednostka nie jest zsynchronizowana. Utwórzmy tabelę uczniów za pomocą polecenia Symfony w następnym kroku.
Krok 7: Utwórz schemat
Doctrine może automatycznie tworzyć wszystkie tabele bazy danych potrzebne dla jednostki Studenta. Można to zrobić za pomocą następującego polecenia.
php bin/console doctrine:schema:update --force
Po wykonaniu polecenia możesz zobaczyć następującą odpowiedź.
Updating database schema...
Database schema updated successfully! "1" query was executed
To polecenie porównuje wygląd bazy danych z jej rzeczywistym wyglądem i wykonuje instrukcje SQL potrzebne do zaktualizowania schematu bazy danych do miejsca, w którym powinien być.
Teraz ponownie sprawdź poprawność schematu za pomocą następującego polecenia.
php bin/console doctrine:schema:validate
To da następujący wynik -
[Mapping] OK - The mapping files are correct.
[Database] OK - The database schema is in sync with the mapping files
Krok 8: Getter i setter
Jak widać w sekcji Bind an Entity, poniższe polecenie generuje wszystkie metody pobierające i ustawiające dla klasy Student.
$ php bin/console doctrine:generate:entities AppBundle/Entity/Student
Krok 9: Utrwalaj obiekty w bazie danych
Teraz zmapowaliśmy jednostkę Student do odpowiedniej tabeli Student. Powinniśmy być teraz w stanie utrwalić obiekty Studentów w bazie danych. Dodaj następującą metodę do StudentController pakietu.
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());
}
}
Tutaj uzyskaliśmy dostęp do menedżera doktryny za pomocą metody getManager () poprzez getDoctrine () kontrolera podstawowego, a następnie utrwaliliśmy bieżący obiekt za pomocą metody persist () menedżera doktryny. persist() dodaje polecenie do kolejki, ale plik flush() metoda wykonuje rzeczywistą pracę (utrwalanie obiektu ucznia).
Krok 10: Pobierz obiekty z bazy danych
Utwórz funkcję w StudentController, która wyświetli szczegóły ucznia.
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));
}
Krok 11: Utwórz widok
Stwórzmy widok, który wskazuje na wyświetlaną akcję. Przejdź do katalogu views i utwórz plik „display.html.twig”. Dodaj następujące zmiany w pliku.
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>
Wynik można uzyskać, żądając adresu URL „http: // localhost: 8000 / student / display” w przeglądarce.
Na ekranie wyświetli się następujący wynik -
Krok 12: Zaktualizuj obiekt
Aby zaktualizować obiekt w StudentController, utwórz akcję i dodaj następujące zmiany.
/**
* @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!');
}
Teraz poproś o adres URL „http: // localhost: 8000 / Student / update / 1”, a otrzymasz następujący wynik.
Na ekranie wyświetli się następujący wynik -
Krok 13: Usuń obiekt
Usuwanie obiektu jest podobne i wymaga wywołania metody remove () menedżera encji (doktryny).
Można to zrobić za pomocą następującego polecenia.
/**
* @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 dostarcza różne wbudowane znaczniki do łatwej i bezpiecznej obsługi formularzy HTML. Komponent Form Symfony wykonuje proces tworzenia i walidacji formularza. Łączy model i warstwę widoku. Udostępnia zestaw elementów formularza do tworzenia pełnoprawnego formularza HTML z predefiniowanych modeli. W tym rozdziale szczegółowo omówiono Formularze.
Pola formularza
API frameworka Symfony obsługuje dużą liczbę typów pól. Przyjrzyjmy się szczegółowo każdemu z typów pól.
FormType
Służy do generowania formularza we frameworku Symfony. Jego składnia jest następująca -
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);
Tutaj, $studentinfo jest bytem typu Student. createFormBuildersłuży do tworzenia formularza HTML. add jest używana doadd elementy wejściowe wewnątrz formularza. title odnosi się do własności tytułu studenta. TextType::classodnosi się do pola tekstowego html. Symfony dostarcza klasy dla wszystkich elementów html.
TextType
Pole TextType reprezentuje najbardziej podstawowe pole tekstu wejściowego. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\TextType;
$builder->add(‘name’, TextType::class);
Tutaj nazwa jest mapowana z jednostką.
TextareaType
Renderuje element HTML textarea. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
$builder->add('body', TextareaType::class, array(
'attr' => array('class' => 'tinymce'),
));
EmailType
Pole EmailType to pole tekstowe, które jest renderowane za pomocą tagu HTML5 email. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\EmailType;
$builder->add('token', EmailType::class, array(
'data' => 'abcdef', ));
PasswordType
Pole PasswordType renderuje pole tekstowe hasła wejściowego. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
$bulder->add('password', PasswordType::class);
RangeType
Pole RangeType to suwak renderowany za pomocą znacznika zakresu HTML5. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\RangeType;
// ...
$builder->add('name', RangeType::class, array(
'attr' => array(
'min' => 100,
'max' => 200
)
));
PercentType
PercentType renderuje wejściowe pole tekstowe i specjalizuje się w obsłudze danych procentowych. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\PercentType;
// ...
$builder->add('token', PercentType::class, array(
'data' => 'abcdef',
));
DateType
Renderuje format daty. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\DateType;
// ...
$builder->add(‘joined’, DateType::class, array(
'widget' => 'choice',
));
Tutaj Widget jest podstawowym sposobem renderowania pola.
Pełni następującą funkcję.
choice- Renderuje trzy wybrane wejścia. Kolejność zaznaczeń jest określona w opcji formatu.
text - Renderuje trzy pola tekstowe (miesiąc, dzień, rok).
single_text- Renderuje pojedyncze dane wejściowe typu date. Dane wejściowe użytkownika są sprawdzane na podstawie opcji formatu.
CheckboxType
Tworzy pojedyncze pole wyboru do wprowadzania danych. Powinno to być zawsze używane dla pola, które ma wartość logiczną. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
// ...
$builder-<add(‘sports’, CheckboxType::class, array(
'label' =< ‘Are you interested in sports?’,
'required' =< false,
));
RadioType
Tworzy pojedynczy przycisk opcji. Jeśli przycisk radiowy jest zaznaczony, pole zostanie ustawione na określoną wartość. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\RadioType;
// ...
$builder->add('token', RadioType::class, array(
'data' => 'abcdef',
));
Należy pamiętać, że nie można odznaczyć opcji Przyciski radiowe, wartość zmienia się tylko wtedy, gdy zostanie zaznaczony inny przycisk radiowy o tej samej nazwie.
RepeatedType
Jest to specjalna „grupa” pól, która tworzy dwa identyczne pola, których wartości muszą być zgodne. Jego składnia jest następująca -
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'),
));
Służy to głównie do sprawdzania hasła lub adresu e-mail użytkownika.
ButtonType
Prosty przycisk, który można kliknąć. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\ButtonType;
// ...
$builder->add('save', ButtonType::class, array(
'attr' => array('class' => 'save'),
));
ResetType
Przycisk, który resetuje wszystkie pola do ich wartości początkowych. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\ResetType;
// ...
$builder->add('save', ResetType::class, array(
'attr' => array('class' => 'save'),
));
ChoiceType
Pole wielofunkcyjne umożliwia użytkownikowi „wybranie” jednej lub kilku opcji. Może być renderowany jako znacznik wyboru, przyciski opcji lub pola wyboru. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
// ...
$builder->add(‘gender’, ChoiceType::class, array(
'choices' => array(
‘Male’ => true,
‘Female’ => false,
),
));
SubmitType
Przycisk przesyłania służy do przesyłania danych formularza. Jego składnia jest następująca -
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
// ...
$builder->add('save', SubmitType::class, array(
'attr' => array('class' => 'save'),
))
Funkcja pomocnika formularza
Funkcje pomocnicze formularzy to funkcje gałązek używane do łatwego tworzenia formularzy w szablonach.
form_start
Zwraca znacznik formularza HTML, który wskazuje prawidłową akcję, trasę lub adres URL. Jego składnia jest następująca -
{{ form_start(form, {'attr': {'id': 'form_person_edit'}}) }}
form_end
Zamyka tag formularza HTML utworzony za pomocą form_start. Jego składnia jest następująca -
{{ form_end(form) }}
textarea
Zwraca tag textarea, opcjonalnie opakowany za pomocą wbudowanego edytora JavaScript obsługującego tekst sformatowany.
pole wyboru
Zwraca znacznik wejściowy zgodny z XHTML z typem = „pole wyboru”. Jego składnia jest następująca -
echo checkbox_tag('choice[]', 1);
echo checkbox_tag('choice[]', 2);
echo checkbox_tag('choice[]', 3);
echo checkbox_tag('choice[]', 4);
input_password_tag
Zwraca znacznik wejściowy zgodny z XHTML z typem = „hasło”. Jego składnia jest następująca -
echo input_password_tag('password');
echo input_password_tag('password_confirm');
input_tag
Zwraca znacznik wejściowy zgodny z XHTML z type = „text”. Jego składnia jest następująca -
echo input_tag('name');
etykieta
Zwraca etykietę z określonym parametrem.
Przycisk radiowy
Zwraca znacznik wejściowy zgodny z XHTML z type = „radio”. Jego składnia jest następująca -
echo ' Yes '.radiobutton_tag(‘true’, 1);
echo ' No '.radiobutton_tag(‘false’, 0);
reset_tag
Zwraca znacznik wejściowy zgodny z XHTML z typem = „reset”. Jego składnia jest następująca -
echo reset_tag('Start Over');
Wybierz
Zwraca wybrany tag zawierający wszystkie kraje na świecie. Jego składnia jest następująca -
echo select_tag(
'url', options_for_select($url_list),
array('onChange' => 'Javascript:this.form.submit();'));
Zatwierdź
Zwraca znacznik wejściowy zgodny z XHTML z type = „submit”. Jego składnia jest następująca -
echo submit_tag('Update Record');
W następnej sekcji dowiemy się, jak utworzyć formularz za pomocą pól formularza.
Formularz wniosku studenckiego
Stwórzmy prosty formularz szczegółów Studenta, używając pól formularza Symfony. Aby to zrobić, powinniśmy postępować zgodnie z następującymi krokami -
Krok 1: Utwórz aplikację Symfony
Utwórz aplikację Symfony, formsample, używając następującego polecenia.
symfony new formsample
Jednostki są zwykle tworzone w katalogu „src / AppBundle / Entity /”.
Krok 2: Utwórz jednostkę
Utwórz plik „StudentForm.php” w katalogu „src / AppBundle / Entity /”. Dodaj następujące zmiany w pliku.
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;
}
}
Krok 3: Dodaj StudentController
Przejdź do katalogu „src / AppBundle / Controller”, utwórz plik „StudentController.php” i dodaj w nim następujący kod.
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(),
));
}
}
Krok 4: Renderuj widok
Przejdź do katalogu „app / Resources / views / student /”, utwórz plik „new.html.twig” i dodaj w nim następujące zmiany.
{% 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 %}
Teraz poproś o adres URL „http: // localhost: 8000 / student / new”, a otrzymasz następujący wynik.
Wynik
Walidacja to najważniejszy aspekt podczas projektowania aplikacji. Sprawdza przychodzące dane. W tym rozdziale szczegółowo opisano walidację formularzy.
Ograniczenia walidacji
Walidator jest przeznaczony do sprawdzania poprawności obiektów pod kątem ograniczeń. Jeśli walidujesz obiekt, po prostu zamapuj jedno lub więcej ograniczeń na jego klasę, a następnie przekaż je do usługi walidatora. Domyślnie podczas walidacji obiektu sprawdzane są wszystkie ograniczenia odpowiedniej klasy, aby zobaczyć, czy faktycznie spełniają. Symfony obsługuje następujące, godne uwagi ograniczenia walidacji.
NotBlank
Sprawdza, czy właściwość nie jest pusta. Jego składnia jest następująca -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\NotBlank()
*/
protected $studentName;
}
To ograniczenie NotBlank zapewnia, że właściwość studentName nie powinna być pusta.
Nie jest zerem
Sprawdza, czy wartość nie jest dokładnie równa null. Jego składnia jest następująca -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\NotNull()
*/
protected $studentName;
}
Sprawdza, czy wartość jest prawidłowym adresem e-mail. Jego składnia jest następująca -
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;
}
IsNull
Sprawdza, czy wartość jest dokładnie równa null. Jego składnia jest następująca -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\IsNull()
*/
protected $studentName;
}
Długość
Sprawdza, czy dana długość łańcucha zawiera się między pewną wartością minimalną i maksymalną. Jego składnia jest następująca -
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;
}
Zasięg
Sprawdza, czy podana liczba zawiera się między pewną liczbą minimalną i maksymalną. Jego składnia jest następująca -
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;
}
Data
Sprawdza, czy wartość jest prawidłową datą. Ma prawidłowy format RRRR-MM-DD. Jego składnia jest następująca -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\Date()
*/
protected $joinedAt;
}
Wybór
To ograniczenie służy do upewnienia się, że dana wartość jest jedną z podanego zestawu prawidłowych wyborów. Można go również użyć do sprawdzenia, czy każdy element w tablicy elementów jest jednym z tych ważnych wyborów. Jego składnia jest następująca -
namespace AppBundle\Entity;
use Symfony\Component\Validator\Constraints as Assert;
class Student {
/**
* @Assert\Choice(choices = {"male", "female"}, message = "Choose a valid gender.")
*/
protected $gender;
}
Hasło użytkownika
To sprawdza, czy wartość wejściowa jest równa bieżącemu hasłu uwierzytelnionego użytkownika. Jest to przydatne w przypadku, gdy użytkownicy mogą zmienić swoje hasło, ale ze względów bezpieczeństwa muszą wprowadzić stare hasło. Jego składnia jest następująca -
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;
}
To ograniczenie sprawdza, czy stare hasło jest zgodne z bieżącym hasłem użytkownika.
Przykład walidacji
Napiszmy prosty przykład aplikacji, aby zrozumieć koncepcję walidacji.
Step 1 - Utwórz aplikację walidacyjną.
Utwórz aplikację Symfony, validationsample, używając następującego polecenia.
symfony new validationsample
Step 2 - Utwórz podmiot o nazwie, FormValidation w pliku “FormValidation.php” pod “src/AppBundle/Entity/”informator. Dodaj następujące zmiany w pliku.
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 - Utwórz plik validateActionmetoda w StudentController. Przejdź do katalogu“src/AppBundle/Controller”, Stwórz “studentController.php” file i dodaj w nim następujący kod.
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(),
));
}
Tutaj utworzyliśmy formularz przy użyciu klas Form, a następnie obsłużyliśmy formularz. Jeśli formularz został przesłany i jest prawidłowy, zostanie wyświetlony komunikat potwierdzony przez formularz. W przeciwnym razie wyświetlany jest domyślny formularz.
Step 4- Utwórz widok dla powyższej akcji w StudentController. Przejdź do katalogu“app/Resources/views/student/”. Stwórz“validate.html.twig” plik i dodaj w nim następujący kod.
{% 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 %}
Tutaj użyliśmy tagów formularza do stworzenia formularza.
Step 5 - Na koniec uruchom aplikację, http://localhost:8000/student/validate.
Wynik: strona początkowa
Wynik: strona końcowa
Składnik Symfony Form zapewnia FileTypeklasa do obsługi elementu wejściowego pliku. Umożliwia łatwe przesyłanie zdjęć, dokumentów itp. Nauczmy się, jak stworzyć prostą aplikację z wykorzystaniem funkcji FileType.
Step 1 - Utwórz nową aplikację, fileuploadsample za pomocą następującego polecenia.
symfony new fileuploadsample
Step 2 - Stwórz podmiot, Student, posiadające imię i nazwisko, wiek i zdjęcie, jak pokazano w poniższym kodzie.
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;
}
}
Tutaj określiliśmy File dla właściwości zdjęcia.
Step 3 - Utwórz kontroler ucznia, StudentController i nową metodę addAction, jak pokazano w poniższym kodzie.
<?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(),
));
}
}
}
Tutaj stworzyliśmy formularz dla podmiotu studenckiego i załatwiliśmy wniosek. Gdy formularz jest przesłany przez użytkownika i jest prawidłowy, to za pomocą parametru przenieśliśmy przesłany plik do naszego katalogu uploaduphotos_directory.
Step 4 - Utwórz widok, new.html.twig, używając następujących tagów formularza.
{% 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 - Ustaw parametr, photos_directory w pliku konfiguracyjnym parametrów w następujący sposób.
aplikacja / config / config.xml
parameters: photos_directory: '%kernel.root_dir%/../web/uploads/photos'
Step 6- Teraz uruchom aplikację i otwórz http: // localhost: 8000 / student / new i prześlij zdjęcie. Przesłane zdjęcie zostanie przesłane do katalogu photos_directory i wyświetli się pomyślna wiadomość.
Wynik: strona początkowa
Wynik: strona przesyłania plików
AJAX to nowoczesna technologia w programowaniu internetowym. Zapewnia opcje asynchronicznego wysyłania i odbierania danych na stronie internetowej, bez odświeżania strony. W tym rozdziale nauczmy się programowania w Symfony AJAX.
Framework Symfony zapewnia opcje tożsamości, niezależnie od tego, czy typ żądania to AJAX, czy nie. Klasa request składnika Symfony HttpFoundation ma do tego celu metodę isXmlHttpRequest (). Jeśli zostanie wysłane żądanie AJAX, metoda isXmlHttpRequest () bieżącego obiektu żądania zwraca wartość true, w przeciwnym razie false.
Ta metoda służy do poprawnej obsługi żądań AJAX po stronie serwera.
if ($request->isXmlHttpRequest()) {
// Ajax request
} else {
// Normal request
}
Symfony udostępnia również klasę Response opartą na JSON, JsonResponse do tworzenia odpowiedzi w formacie JSON. Możemy połączyć te dwie metody, aby stworzyć prostą i czystą aplikację internetową opartą na AJAX.
AJAX - przykład roboczy
Dodajmy nową stronę, student/ajax w aplikacji studenta i spróbuj asynchronicznie pobrać informacje o uczniu.
Step 1 - Dodaj metodę ajaxAction w 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');
}
}
Tutaj, jeśli żądanie jest AJAX, pobieramy informacje o uczniach, kodujemy je jako JSON i zwracamy za pomocą JsonResponseobiekt. W przeciwnym razie po prostu renderujemy odpowiedni widok.
Step 2 - Utwórz plik widoku ajax.html.twig w katalogu widoków studentów, app/Resources/views/student/ i dodaj następujący kod.
{% 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 %}
Tutaj utworzyliśmy tag kotwicy (id: loadstudent), aby załadować informacje o uczniu za pomocą wywołania AJAX. Wywołanie AJAX odbywa się za pomocą JQuery. Zdarzenie dołączone do tagu loadstudent jest aktywowane, gdy użytkownik go kliknie. Następnie pobierze informacje o uczniu za pomocą wywołania AJAX i dynamicznie wygeneruje wymagany kod HTML.
Step 3- Na koniec uruchom aplikację, http://localhost:8000/student/ajax i kliknij zakotwiczenie Załaduj informacje o studentach.
Wynik: strona początkowa
Wynik: Strona z informacjami o uczniu
Komponent Symfony HttpFoundation zapewnia zarządzanie plikami cookie i sesjami w sposób obiektowy. Cookiezapewnia przechowywanie danych po stronie klienta i obsługuje tylko niewielką ilość danych. Zwykle jest to 2 KB na domenę i zależy to od przeglądarki.Sessionzapewnia przechowywanie danych po stronie serwera i obsługuje duże ilości danych. Zobaczmy, jak utworzyć plik cookie i sesję w aplikacji internetowej Symfony.
Ciastko
Symfony udostępnia klasę Cookie do tworzenia pozycji cookie. Stwórzmy kolor cookie, który wygasa po 24 godzinach z wartościąblue. Parametr konstruktora klasy cookie jest następujący.
- name (type: string) - nazwa ciasteczka
- value (type: string) - wartość ciasteczka
- expire (type: integer / string / datetime) - informacja o wygaśnięciu
- path (type: string) - ścieżka serwera, na którym znajduje się plik cookie
- domain (type: string) - adres domeny, w której plik cookie jest dostępny
- secure (type: boolean) - czy plik cookie ma być przesyłany w połączeniu HTTPS
- httpOnly (typ: boolean) - czy plik cookie jest dostępny tylko w protokole HTTP
use Symfony\Component\HttpFoundation\Cookie;
$cookie = new Cookie('color', 'green', strtotime('tomorrow'), '/',
'somedomain.com', true, true);
Symfony udostępnia również następującą opcję tworzenia ciasteczek w oparciu o ciągi znaków.
$cookie = Cookie::fromString('color = green; expires = Web, 4-May-2017 18:00:00 +0100;
path=/; domain = somedomain.com; secure; httponly');
Teraz utworzony plik cookie należy dołączyć do nagłówka obiektu odpowiedzi http w następujący sposób.
$response->headers->setCookie($cookie);
Aby uzyskać plik cookie, możemy użyć obiektu Request w następujący sposób.
$cookie = $request->cookie->get('color');
Tutaj, request->cookie jest typu PropertyBag i możemy nim manipulować za pomocą metod PropertyBag.
Sesja
Symfony dostarcza klasę Session implementującą interfejs SessionInterface. Oto ważne API sesji:
start - Rozpoczyna sesję.
Session $session = new Session();
$session->start();
invalidate - Czyści wszystkie dane sesji i ponownie generuje identyfikator sesji.
set - Przechowuje dane w sesji za pomocą klucza.
$session->set('key', 'value');
Możemy użyć dowolnych danych w wartości sesji, być prostą liczbą całkowitą do złożonych obiektów.
get - Pobiera dane z sesji za pomocą klucza.
$val = $session->get('key');
remove - Usuwa klucz z sesji.
clear - Usuwa dane sesji.
FlashBag
Session udostępnia inną przydatną funkcję o nazwie FlashBag. Jest to specjalny kontener wewnątrz sesji przechowujący dane tylko podczas przekierowywania strony. Jest to przydatne w przekierowaniach http. Przed przekierowaniem na stronę dane można zapisać we FlashBag zamiast w zwykłym kontenerze sesji, a zapisane dane będą dostępne w następnym żądaniu (przekierowanej stronie). Następnie dane zostaną automatycznie unieważnione.
$session->getFlashBag()->add('key', 'value'); $session->getFlashBag()->get('key');
Internationalization (i18n) i Localization (l10n)pomagają zwiększyć objęcie klientów aplikacją internetową. Symfony zapewnia doskonały komponent tłumaczeniowy do tego celu. Nauczmy się, jak korzystać z komponentu Tłumaczenie w tym rozdziale.
Włącz tłumaczenie
Domyślnie framework sieciowy Symfony wyłącza komponent Translation. Aby to włączyć, dodaj sekcję tłumacza w pliku konfiguracyjnym app / config / config.yml.
framework: translator: { fallbacks: [en] }
Plik tłumaczenia
Komponent tłumaczenia tłumaczy tekst przy użyciu pliku zasobów tłumaczeniowych. Plik zasobów może być napisany w PHP, XML i YAML. Domyślna lokalizacja pliku zasobów toapp/Resources/translations. Potrzebuje jednego pliku zasobów na język. Napiszmy plik zasobów,messages.fr.yml dla języka francuskiego.
I love Symfony: J'aime Symfony
I love %name%: J'aime %name%
Tekst po lewej stronie jest w języku angielskim, a tekst po prawej stronie w języku francuskim. Druga linia pokazuje użycie symbolu zastępczego. Informacje zastępcze można dodawać dynamicznie podczas korzystania z tłumaczenia.
Stosowanie
Domyślnie domyślne ustawienia regionalne systemu użytkownika zostaną ustawione przez framework sieciowy Symfony. Jeśli domyślne ustawienia regionalne nie są skonfigurowane w aplikacji sieci Web, nastąpi powrót do języka angielskiego. Lokalizację można również ustawić w adresie URL strony internetowej.
http://www.somedomain.com/en/index
http://www.somedomain.com/fr/index
Użyjmy w naszym przykładzie ustawień regionalnych opartych na adresach URL, aby łatwo zrozumieć koncepcję tłumaczenia. Utwórz nową funkcję,translationSample z trasą /{_locale}/translation/samplew DefaultController (src / AppBundle / Controller / DefaultController.php). {_locale} to specjalne słowo kluczowe w Symfony do określenia domyślnych ustawień regionalnych.
/**
* @Route("/{_locale}/translation/sample", name="translation_sample")
*/
public function translationSample() {
$translated = $this->get('translator')->trans('I love Symfony');
return new Response($translated);
}
Tutaj użyliśmy metody tłumaczenia, trans, który tłumaczy treść na aktualne ustawienia regionalne. W tym przypadku bieżące ustawienia regionalne są pierwszą częścią adresu URL. Teraz uruchom aplikację i załaduj stronę,http://localhost:8000/en/translation/sample w przeglądarce.
Rezultatem będzie „I love Symfony” w języku angielskim. Teraz załaduj stronęhttp://localhost:8000/fr/translation/samplew przeglądarce. Teraz tekst zostanie przetłumaczony na francuski w następujący sposób.
Podobnie, szablon gałązki ma {% trans %}blok, aby włączyć funkcję tłumaczenia również w widokach. Aby to sprawdzić, dodaj nową funkcję,translationTwigSample i odpowiedni widok pod adresem 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');
}
Widok
{% extends 'base.html.twig' %}
{% block body %}
{% trans with {'%name%': 'Symfony'} from "app" into "fr" %}I love %name% {% endtrans %}
{% endblock %}
Tutaj blok trans określa również symbol zastępczy. Wynik strony jest następujący.
Logowanie jest bardzo ważne w przypadku aplikacji internetowych. Aplikacje internetowe są używane jednocześnie przez setki do tysięcy użytkowników. Aby uzyskać podgląd wydarzeń wokół aplikacji internetowej, należy włączyć rejestrowanie. Bez logowania deweloper nie będzie w stanie znaleźć statusu aplikacji. Rozważmy, że klient końcowy zgłasza problem lub uczestnik projektu zgłasza problem z wydajnością, wtedy pierwszym narzędziem dla programisty jest rejestrowanie. Sprawdzając informacje w dzienniku, można dowiedzieć się o możliwej przyczynie problemu.
Symfony zapewnia doskonałą funkcję logowania poprzez integrację struktury rejestrowania Monolog. Monologjest de facto standardem logowania w środowisku PHP. Logowanie jest włączone w każdej aplikacji internetowej Symfony i jest dostarczane jako Usługa. Po prostu pobierz obiekt rejestratora za pomocą kontrolera podstawowego w następujący sposób.
$logger = $this->get('logger');
Po pobraniu obiektu rejestrującego możemy rejestrować informacje, ostrzeżenia i błędy przy jego użyciu.
$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!');
Plik konfiguracyjny aplikacji internetowej Symfony app/config/config.ymlma oddzielną sekcję dla struktury rejestratora. Można go użyć do aktualizacji działania struktury rejestratora.
Funkcja poczty e-mail jest najbardziej pożądaną funkcją we frameworku internetowym. Nawet prosta aplikacja będzie miała formularz kontaktowy, a szczegóły zostaną przesłane e-mailem do administracji systemu. Symfony integruje sięSwiftMailernajlepszy dostępny na rynku moduł poczty elektronicznej PHP. SwiftMailer to doskonała biblioteka poczty e-mail oferująca opcję wysyłania wiadomości e-mail przy użyciu starej szkoły sendmail do najnowszej aplikacji pocztowej w chmurze.
Rozumiemy koncepcję wysyłania poczty w Symfony, wysyłając prosty e-mail. Przed napisaniem funkcji mailera ustaw szczegóły konfiguracji mailera wapp/config/parameters.yml. Następnie utwórz nową funkcję,MailerSample w DefaultController i dodaj następujący kod.
/**
* @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");
}
Tutaj po prostu utworzyliśmy wiadomość za pomocą SwiftMailer i wyrenderował treść wiadomości przy użyciu Twigszablon. Następnie pobraliśmy komponent mailer z kontroleragetmetoda z kluczem „mailer”. Na koniec wysłaliśmy wiadomość za pomocąsend metoda i wydrukowała Mail send wiadomość.
Teraz uruchom stronę, http://localhost:8000/mailsample/send a wynik byłby następujący.
Test jednostkowy jest niezbędny do ciągłego rozwoju w dużych projektach. Testy jednostkowe automatycznie przetestują komponenty aplikacji i ostrzegają, gdy coś nie działa. Testowanie jednostkowe można przeprowadzić ręcznie, ale często jest ono zautomatyzowane.
PHPUnit
Framework Symfony integruje się z frameworkiem testów jednostkowych PHPUnit. Aby napisać test jednostkowy dla frameworka Symfony, musimy skonfigurować PHPUnit. Jeśli PHPUnit nie jest zainstalowany, pobierz go i zainstaluj. Jeśli jest poprawnie zainstalowany, zobaczysz następującą odpowiedź.
phpunit
PHPUnit 5.1.3 by Sebastian Bergmann and contributors
Test jednostkowy
Test jednostkowy to test na pojedynczą klasę PHP, nazywaną również jednostką.
Utwórz klasę Student w katalogu Libs / w AppBundle. Znajduje się na“src/AppBundle/Libs/Student.php”.
Student.php
namespace AppBundle\Libs;
class Student {
public function show($name) { return $name. “ , Student name is tested!”;
}
}
Teraz utwórz plik StudentTest w katalogu „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);
}
}
Uruchom test
Aby uruchomić test w katalogu, użyj następującego polecenia.
$ phpunit
Po wykonaniu powyższego polecenia zobaczysz następującą odpowiedź.
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.
Teraz uruchom testy w katalogu Libs w następujący sposób.
$ phpunit tests/AppBundle/Libs
Wynik
Time: 26 ms, Memory: 4.00Mb
OK (1 test, 1 assertion)
W tym rozdziale poznamy kilka zaawansowanych koncepcji we frameworku Symfony.
Pamięć podręczna HTTP
Buforowanie w aplikacji internetowej poprawia wydajność. Na przykład gorące produkty w aplikacji sieciowej koszyka na zakupy mogą być przechowywane w pamięci podręcznej przez ograniczony czas, dzięki czemu mogą być prezentowane klientowi w szybki sposób bez przechodzenia do bazy danych. Oto kilka podstawowych składników Cache.
Pozycja pamięci podręcznej
Pozycja pamięci podręcznej to pojedyncza jednostka informacji przechowywana jako para klucz / wartość. Plikkey powinien być ciągiem i valuemoże być dowolnym obiektem PHP. Obiekty PHP są przechowywane jako łańcuchy przez serializację i konwertowane z powrotem na obiekty podczas odczytu elementów.
Adapter pamięci podręcznej
Adapter pamięci podręcznej to rzeczywisty mechanizm przechowywania przedmiotu w sklepie. Magazyn może być pamięcią, systemem plików, bazą danych, redisem itp. Składnik Cache udostępnia plikAdapterInterfaceza pomocą którego adapter może przechowywać element pamięci podręcznej w sklepie zaplecza. Dostępnych jest wiele wbudowanych adapterów pamięci podręcznej. Niewiele z nich jest następujących -
Adapter Array Cache - elementy pamięci podręcznej są przechowywane w tablicy PHP.
Adapter pamięci podręcznej systemu plików - elementy pamięci podręcznej są przechowywane w plikach.
Adapter pamięci podręcznej plików PHP - elementy pamięci podręcznej są przechowywane jako pliki php.
Adapter pamięci podręcznej APCu - elementy pamięci podręcznej są przechowywane w pamięci współdzielonej przy użyciu rozszerzenia PHP APCu.
Adapter pamięci podręcznej Redis - elementy pamięci podręcznej są przechowywane na serwerze Redis.
Adapter pamięci podręcznej PDO i Doctrine DBAL - elementy pamięci podręcznej są przechowywane w bazie danych.
Chain Cache Adapter - łączy wiele adapterów pamięci podręcznej do celów replikacji.
Adapter pamięci podręcznej proxy - elementy pamięci podręcznej są przechowywane przy użyciu adaptera innej firmy, który implementuje interfejs CacheItemPoolInterface.
Pula pamięci podręcznej
Pula pamięci podręcznej to logiczne repozytorium elementów pamięci podręcznej. Pule pamięci podręcznej są implementowane przez adaptery pamięci podręcznej.
Prosta aplikacja
Stwórzmy prostą aplikację, aby zrozumieć koncepcję pamięci podręcznej.
Step 1 - Utwórz nową aplikację, cache-example.
cd /path/to/app
mkdir cache-example
cd cache-example
Step 2 - Zainstaluj komponent pamięci podręcznej.
composer require symfony/cache
Step 3 - Utwórz adapter systemu plików.
require __DIR__ . '/vendor/autoload.php';
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter();
Step 4 - Utwórz element pamięci podręcznej za pomocą getItem i setmetoda adaptera. getItem pobiera element pamięci podręcznej za pomocą swojego klucza. jeśli klucz nie jest trwały, tworzy nowy element. set metoda przechowuje rzeczywiste dane.
$usercache = $cache->getitem('item.users');
$usercache->set(['jon', 'peter']); $cache->save($usercache);
Step 5 - Uzyskaj dostęp do elementu pamięci podręcznej za pomocą getItem, isHit i getmetoda. isHit informuje o dostępności elementu pamięci podręcznej, a metoda get dostarcza rzeczywiste dane.
$userCache = $cache->getItem('item.users'); if(!$userCache->isHit()) {
echo "item.users is not available";
} else {
$users = $userCache->get();
var_dump($users);
}
Step 6 - Usuń element pamięci podręcznej za pomocą deleteItem metoda.
$cache->deleteItem('item.users');
Pełna lista kodów jest następująca.
<?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');
?>
Wynik
array(2) {
[0]=>
string(3) "jon"
[1]=>
string(5) "peter"
}
Odpluskwić
Debugowanie jest jedną z najczęstszych czynności podczas tworzenia aplikacji. Symfony dostarcza oddzielny komponent ułatwiający proces debugowania. Możemy włączyć narzędzia debugowania Symfony, po prostu wywołując plikenable metoda klasy Debug.
use Symfony\Component\Debug\Debug
Debug::enable()
Symfony udostępnia dwie klasy, ErrorHandler i ExceptionHandlerdo celów debugowania. Podczas gdy ErrorHandler przechwytuje błędy PHP i konwertuje je na wyjątki, ErrorException lub FatalErrorException, ExceptionHandler wyłapuje nieprzechwycone wyjątki PHP i przekształca je w użyteczną odpowiedź PHP. ErrorHandler i ExceptionHandler są domyślnie wyłączone. Możemy to włączyć za pomocą metody register.
use Symfony\Component\Debug\ErrorHandler;
use Symfony\Component\Debug\ExceptionHandler;
ErrorHandler::register();
ExceptionHandler::register();
W aplikacji internetowej Symfony rozszerzenie debug environmentjest udostępniany przez DebugBundle. Zarejestruj pakiet w AppKernel'sregisterBundles metoda, aby ją włączyć.
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle();
}
Profiler
Tworzenie aplikacji wymaga światowej klasy narzędzia do profilowania. Narzędzie do profilowania zbiera wszystkie informacje o aplikacji w czasie wykonywania, takie jak czas wykonania, czas wykonania poszczególnych modułów, czas aktywności bazy danych, wykorzystanie pamięci itp. Aplikacja internetowa potrzebuje znacznie więcej informacji, takich jak czas żądania, czas potrzebny do utworzenia odpowiedzi itp. oprócz powyższych wskaźników.
Symfony domyślnie włącza wszystkie takie informacje w aplikacji internetowej. Symfony dostarcza oddzielny pakiet do profilowania sieci o nazwieWebProfilerBundle. Pakiet profilera internetowego można włączyć w aplikacji internetowej, rejestrując pakiet w metodzie registerBundles w AppKernel.
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) {
$bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
}
Komponent profilu internetowego można skonfigurować w obszarze web_profile section pliku konfiguracyjnego aplikacji, app/config/config.xml
web_profiler:
toolbar: false
position: bottom
Aplikacja Symfony wyświetla profilowane dane na dole strony jako odrębną sekcję.
Symfony zapewnia również łatwy sposób dodawania niestandardowych szczegółów o stronie w danych profilu za pomocą DataCollectorInterface interfacei szablon gałązki. Krótko mówiąc, Symfony umożliwia programistom sieciowym tworzenie światowej klasy aplikacji poprzez dostarczanie świetnego frameworka do profilowania z względną łatwością.
Bezpieczeństwo
Jak wspomniano wcześniej, Symfony zapewnia solidną strukturę bezpieczeństwa poprzez swój komponent bezpieczeństwa. Element zabezpieczający dzieli się na cztery podkomponenty w następujący sposób.
- symfony / security-core - Podstawowe funkcje bezpieczeństwa.
- symfony / security-http - Zintegrowana funkcja bezpieczeństwa w protokole HTTP.
- symfony / security-csrf - Ochrona przed fałszowaniem żądań między witrynami w aplikacji internetowej.
- symfony / security-acl - Zaawansowana struktura bezpieczeństwa oparta na liście kontroli dostępu.
Proste uwierzytelnianie i autoryzacja
Poznajmy koncepcję uwierzytelniania i autoryzacji za pomocą prostej aplikacji demonstracyjnej.
Step 1 - Utwórz nową aplikację internetową securitydemo za pomocą następującego polecenia.
symfony new securitydemo
Step 2- Włącz funkcję zabezpieczeń w aplikacji przy użyciu pliku konfiguracji zabezpieczeń. Konfiguracja związana z bezpieczeństwem jest umieszczona w osobnym pliku,security.yml. Domyślna konfiguracja jest następująca.
security:
providers:
in_memory:
memory: ~
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
#http_basic: ~
#form_login: ~
Domyślna konfiguracja umożliwia dostawcę zabezpieczeń opartego na pamięci i anonimowy dostęp do wszystkich stron. Sekcja zapory sieciowej wyklucza pliki pasujące do wzorca,^/(_(profiler|wdt)|css|images|js)/z ram bezpieczeństwa. Domyślny wzorzec obejmuje arkusze stylów, obrazy i skrypty JavaScript (oraz narzędzia programistyczne, takie jak profiler).
Step 3 - Włącz system uwierzytelniania oparty na protokole HTTP, dodając opcję http_basic w sekcji głównej w następujący sposób.
security:
# ...
firewalls:
# ...
main:
anonymous: ~
http_basic: ~
#form_login: ~
Step 4- Dodaj użytkowników w sekcji dostawcy pamięci. Dodaj także role dla użytkowników.
security:
providers:
in_memory:
memory:
users:
myuser:
password: user
roles: 'ROLE_USER'
myadmin:
password: admin
roles: 'ROLE_ADMIN'
Dodaliśmy dwóch użytkowników, użytkownika w roli ROLE_USER i administratora w roli ROLE_ADMIN.
Step 5- Dodaj koder, aby uzyskać pełne informacje o aktualnie zalogowanym użytkowniku. Celem kodera jest uzyskanie pełnych szczegółów bieżącego obiektu użytkownika z żądania internetowego.
security:
# ...
encoders:
Symfony\Component\Security\Core\User\User: bcrypt
# ...
Symfony zapewnia interfejs, UserInterface aby uzyskać szczegółowe informacje o użytkowniku, takie jak nazwa użytkownika, role, hasło itp. Musimy zaimplementować interfejs zgodnie z naszymi wymaganiami i skonfigurować go w sekcji kodera.
Na przykład weźmy pod uwagę, że dane użytkownika znajdują się w bazie danych. Następnie musimy utworzyć nową klasę User i zaimplementować metody UserInterface, aby uzyskać dane użytkownika z bazy danych. Gdy dane są dostępne, system bezpieczeństwa wykorzystuje je, aby zezwolić / odmówić użytkownikowi. Symfony zapewnia domyślną implementację użytkownika dla dostawcy pamięci. Algorytm służy do odszyfrowania hasła użytkownika.
Step 6 - Zaszyfruj hasło użytkownika za pomocą bcryptalgorytm i umieść go w pliku konfiguracyjnym. Odkąd używaliśmybcryptalgorytm, obiekt użytkownika próbuje odszyfrować hasło podane w pliku konfiguracyjnym, a następnie próbuje dopasować je do hasła wprowadzonego przez użytkownika. Aplikacja konsoli Symfony udostępnia proste polecenie zaszyfrowania hasła.
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 - Użyj polecenia, aby wygenerować zaszyfrowane hasło i zaktualizować je w pliku konfiguracyjnym.
# 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- Teraz zastosuj zabezpieczenia do jakiejś sekcji aplikacji. Na przykład ogranicz sekcję administratora do użytkowników pełniących rolę, ROLE_ADMIN.
security:
# ...
firewalls:
# ...
default:
# ...
access_control:
# require ROLE_ADMIN for /admin*
- { path: ^/admin, roles: 'ROLE_ADMIN' }
Step 9 - Dodaj stronę administratora w DefaultController w następujący sposób.
/**
* @Route("/admin")
*/
public function adminLandingAction() {
return new Response('<html><body>This is admin section.</body></html>');
}
Step 10- Na koniec wejdź na stronę administratora, aby sprawdzić konfigurację zabezpieczeń w przeglądarce. Przeglądarka zapyta o nazwę użytkownika i hasło i zezwoli tylko na skonfigurowanych użytkowników.
Wynik
Przepływ pracy
Przepływ pracy to zaawansowana koncepcja mająca zastosowanie w wielu aplikacjach korporacyjnych. W aplikacji e-commerce proces dostarczania produktu to przepływ pracy. Produkt jest najpierw fakturowany (tworzenie zamówienia), kupowany ze sklepu i pakowany (pakowanie / gotowy do wysyłki) i wysyłany do użytkownika. W przypadku jakichkolwiek problemów produkt wraca od użytkownika, a zamówienie zostaje cofnięte. Kolejność przepływu akcji jest bardzo ważna. Na przykład nie możemy dostarczyć produktu bez fakturowania.
Komponent Symfony zapewnia obiektowy sposób definiowania przepływu pracy i zarządzania nim. Każdy krok w procesie jest nazywanyplace i nazywa się czynnością wymaganą do przejścia z jednego miejsca do drugiego transition. Zbiór miejsc i przejście w celu utworzenia przepływu pracy nosi nazwęWorkflow definition.
Zrozummy pojęcie workflow, tworząc prostą aplikację do zarządzania urlopami.
Step 1 - Utwórz nową aplikację, workflow-example.
cd /path/to/dev
mkdir workflow-example
cd workflow-example
composer require symfony/workflow
Step 2 - Utwórz nową klasę, Leave mający applied_by, leave_on i status atrybuty.
class Leave {
public $applied_by; public $leave_on;
public $status;
}
Tutaj zastosowane_by odnosi się do pracowników, którzy chcą odejść. Leave_on odnosi się do daty urlopu. status odnosi się do statusu urlopu.
Step 3 - Zarządzanie urlopami ma cztery miejsca, zastosowane, w toku i zatwierdzone / odrzucone.
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']);
Tutaj utworzyliśmy nową definicję przy użyciu DefinitionBuilder i dodane miejsca za pomocą addPlaces metoda.
Step 4 - Zdefiniuj działania wymagane do przeniesienia się z jednego miejsca w drugie.
$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'));
Tutaj mamy trzy przejścia, to_process, approve i reject. przejście to_process akceptuje wniosek o urlop i przenosi miejsce z zastosowanego do in_process. zatwierdzić przejście zatwierdza wniosek o urlop i przenosi miejsce na zatwierdzone. Podobnie, odrzucenie przejścia powoduje odrzucenie wniosku o urlop i przeniesienie miejsca na odrzucone. Wszystkie przejścia stworzyliśmy metodą addTransition.
Step 5 - Zbuduj definicję za pomocą metody budowania.
$definition = $builder->build();
Step 6 - Opcjonalnie definicję można zrzucić w formacie graphviz dot, który można przekonwertować na plik obrazu w celach referencyjnych.
$dumper = new GraphvizDumper(); echo $dumper->dump($definition);
Step 7 - Stwórz magazyn oznaczeń, który służy do przechowywania aktualnych miejsc / statusu obiektu.
$marking = new SingleStateMarkingStore('status');
Tutaj użyliśmy SingleStateMarkingStoreclass, aby utworzyć znak i zaznacza bieżący stan we właściwości status obiektu. W naszym przykładzie obiektem jest Leave.
Step 8 - Utwórz przepływ pracy, używając definicji i oznaczania.
$leaveWorkflow = new Workflow($definition, $marking);
Tutaj użyliśmy Workflow klasę, aby utworzyć przepływ pracy.
Step 9 - Dodaj przepływ pracy do rejestru struktury przepływu pracy za pomocą Registry klasa.
$registry = new Registry();
$registry->add($leaveWorkflow, Leave::class);
Step 10 - Na koniec użyj przepływu pracy, aby sprawdzić, czy dane przejście jest stosowane przy użyciu can metoda, a jeśli tak, applyprzejście metodą zastosuj. Po zastosowaniu przejścia stan obiektu zmienia się z jednego miejsca w drugie.
$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";
Pełne kodowanie jest następujące -
<?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";
?>
Wynik
Can we approve the leave now?
Can we approve the start process now? 1
Can we approve the leave now? 1
in_process
approved
W każdej nowoczesnej aplikacji usługa REST jest jednym z podstawowych podstawowych elementów konstrukcyjnych. Niezależnie od tego, czy jest to aplikacja internetowa, czy zgrabna aplikacja mobilna, front-end jest zwykle dobrze zaprojektowanym interfejsem dla usług REST zaplecza. Edycja Symfony REST zapewnia gotowy szablon do uruchomienia naszej aplikacji internetowej opartej na REST.
Dowiemy się, jak zainstalować szablonową aplikację REST przy użyciu edycji Symfony REST.
Step 1 - Pobierz edycję Symfony REST za pomocą następującego polecenia.
composer create-project gimler/symfony-rest-edition --stability=dev path/to/install
Spowoduje to pobranie edycji Symfony REST.
Step 2- Spróbuj go skonfigurować, zadając kilka pytań. Na wszystkie pytania wybierz odpowiedź domyślną z wyjątkiem bazy danych. W przypadku bazy danych wybierz pdo_sqlite. Może być konieczne włączenie rozszerzenia sqlite PHP, jeśli nie jest jeszcze zainstalowane.
Step 3 - Teraz uruchom aplikację za pomocą następującego polecenia.
php app/console server:run
Step 4 - Na koniec otwórz aplikację w przeglądarce, używając adresu http: // localhost: 8000 /.
To da następujący wynik -
System zarządzania treścią jest jednym z największych rynków w scenariuszu aplikacji webowych. Dostępnych jest wiele frameworków dla systemu zarządzania treścią, w praktycznie wszystkich językach pod słońcem. Większość frameworków jest łatwa w obsłudze jako klient końcowy, ale bardzo ciężka w obsłudze jako programista i odwrotnie.
Symfony zapewnia prostą i łatwą strukturę dla programisty na początek. Posiada również wszystkie podstawowe cechy oczekiwane przez klienta końcowego. Krótko mówiąc, to programista jest odpowiedzialny za zapewnienie klientom końcowym wspaniałych wrażeń.
Zobaczmy, jak zainstalować szablon aplikacji CMS przy użyciu edycji Symfony CMF.
Step 1 - Pobierz piaskownicę Symfony CMF za pomocą następującego polecenia.
composer create-project symfony-cmf/sandbox cmf-sandbox
Spowoduje to pobranie Symfony CMF.
Step 2- Spróbuj go skonfigurować, zadając kilka pytań. Na wszystkie pytania wybierz odpowiedź domyślną z wyjątkiem bazy danych. W przypadku bazy danych wybierz pdo_sqlite. Może być konieczne włączenie rozszerzenia sqlite PHP, jeśli nie jest jeszcze zainstalowane.
Step 3 - Utwórz bazę danych demonstracyjnych za pomocą aplikacji konsoli w następujący sposób.
php app/console doctrine:database:create
Step 4 - Załaduj dane demonstracyjne do bazy danych za pomocą następującego polecenia.
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 - Teraz uruchom aplikację za pomocą następującego polecenia.
php app/console server:run
Step 6 - Na koniec otwórz aplikację w przeglądarce, używając adresu http: // localhost: 8000 /.
Wytworzy następujący wynik -
W tym rozdziale dowiemy się, jak stworzyć kompletną wersję opartą na MVC BookStore Applicationw Symfony Framework. Oto kroki.
Krok 1: Utwórz projekt
Utwórzmy nowy projekt o nazwie „BookStore” w Symfony za pomocą następującego polecenia.
symfony new BookStore
Krok 2: Utwórz kontroler i trasę
Utwórz BooksController w katalogu „src / AppBundle / Controller”. Jest zdefiniowany w następujący sposób.
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!');
}
}
Teraz stworzyliśmy BooksController, a następnie utwórz widok do renderowania akcji.
Krok 3: Utwórz widok
Utwórzmy nowy folder o nazwie „Książki” w katalogu „app / Resources / views /”. W folderze utwórz plik „author.html.twig” i dodaj następujące zmiany.
author.html.twig
<h3> Simple book store application</h3>
Teraz wyrenderuj widok w klasie BooksController. Jest zdefiniowany w następujący sposób.
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');
}
}
Na razie stworzyliśmy podstawowy kontroler BooksController, a wynik jest renderowany. Wynik można sprawdzić w przeglądarce, korzystając z adresu URL „http: // localhost: 8000 / books / author”.
Krok 4: Konfiguracja bazy danych
Skonfiguruj bazę danych w pliku „app / config / parameters.yml”.
Otwórz plik i dodaj następujące zmiany.
parametr.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
Teraz Doctrine może połączyć się z twoją bazą danych „booksdb”.
Krok 5: Utwórz bazę danych
Wydaj następujące polecenie, aby wygenerować bazę danych „booksdb”. Ten krok jest używany do wiązania bazy danych w Doctrine.
php bin/console doctrine:database:create
Po wykonaniu polecenia automatycznie generuje pustą bazę danych „booksdb”. Na ekranie możesz zobaczyć następującą odpowiedź.
To da następujący wynik -
Created database `booksdb` for connection named default
Krok 6: Mapowanie informacji
Utwórz klasę encji Book w katalogu Entity, który znajduje się w „src / AppBundle / Entity”.
Możesz bezpośrednio przekazać klasę Book za pomocą adnotacji. Jest zdefiniowany w następujący sposób.
Book.php
Dodaj następujący kod w pliku.
<?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;
}
Tutaj nazwa tabeli jest opcjonalna.
Jeśli nazwa tabeli nie zostanie określona, zostanie ona określona automatycznie na podstawie nazwy klasy jednostki.
Krok 7: Powiązanie jednostki
Doctrine tworzy dla Ciebie proste klasy encji. Pomaga budować każdą jednostkę.
Wydaj następujące polecenie, aby wygenerować jednostkę.
php bin/console doctrine:generate:entities AppBundle/Entity/Book
Następnie zobaczysz następujący wynik, a jednostka zostanie zaktualizowana.
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;
}
}
Krok 8: Walidacja mapowania
Po utworzeniu jednostek należy sprawdzić poprawność mapowań za pomocą następującego polecenia.
php bin/console doctrine:schema:validate
To da następujący wynik -
[Mapping] OK - The mapping files are correct
[Database] FAIL - The database schema is not in sync with the current mapping file.
Ponieważ nie utworzyliśmy tabeli Książki, jednostka nie jest zsynchronizowana. W następnym kroku stwórzmy tabelę Książki za pomocą polecenia Symfony.
Krok 9: Tworzenie schematu
Doctrine może automatycznie tworzyć wszystkie tabele bazy danych potrzebne dla encji Book. Można to zrobić za pomocą następującego polecenia.
php bin/console doctrine:schema:update --force
Po wykonaniu polecenia zobaczysz następującą odpowiedź.
Updating database schema...
Database schema updated successfully! "1" query was executed
Teraz ponownie sprawdź poprawność schematu za pomocą następującego polecenia.
php bin/console doctrine:schema:validate
To da następujący wynik -
[Mapping] OK - The mapping files are correct.
[Database] OK - The database schema is in sync with the mapping files.
Krok 10: Getter i Setter
Jak widać w sekcji Bind an Entity, poniższe polecenie generuje wszystkie metody pobierające i ustawiające dla klasy Book.
$ php bin/console doctrine:generate:entities AppBundle/Entity/Book
Krok 11: Pobieranie obiektów z bazy danych
Utwórz metodę w BooksController, która wyświetli szczegóły książek.
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));
}
Krok 12: Utwórz widok
Stwórzmy widok, który wskazuje na wyświetlaną akcję. Przejdź do katalogu views i utwórz plik „display.html.twig”. Dodaj następujące zmiany w pliku.
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 %}
Wynik można uzyskać, żądając adresu URL „http: // localhost: 8000 / books / display” w przeglądarce.
Wynik
Krok 13: Dodaj formularz książki
Stwórzmy funkcję dodania książki do systemu. Utwórz nową stronę, metodę newAction w BooksController w następujący sposób.
// 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(),));
}
Krok 14: Utwórz widok formularza książki
Stwórzmy widok, który wskazuje na nową akcję. Przejdź do katalogu views i utwórz plik „new.html.twig”. Dodaj następujące zmiany w pliku.
{% 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 %}
Wyświetli następujący ekran jako dane wyjściowe -
Krok 15: Zbierz informacje o książce i zapisz je
Zmieńmy metodę newAction i dołączmy kod obsługujący przesyłanie formularza. Przechowuj również informacje o książce w bazie danych.
/**
* @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(),
));
}
}
Gdy książka zostanie zapisana w bazie danych, przekieruj do strony wyświetlania książki.
Krok 16: Aktualizacja książki
Aby zaktualizować książkę, utwórz akcję, updateAction i dodaj następujące zmiany.
/**
* @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(),
));
}
}
Tutaj przetwarzamy dwie funkcjonalności. Jeśli żądanie zawiera tylko identyfikator, pobieramy go z bazy danych i pokazujemy w formie książki. A jeśli żądanie zawiera pełne informacje o książce, aktualizujemy szczegóły w bazie danych i przekierowujemy na stronę wyświetlania książki.
Krok 17: Usuwanie obiektu
Usunięcie obiektu wymaga wywołania metody remove () menedżera encji (doktryny).
Można to zrobić za pomocą następującego kodu.
/**
* @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');
}
Tutaj usunęliśmy książkę i przekierowaliśmy na stronę wyświetlania książek.
Krok 18: Uwzględnij funkcję Dodaj / Edytuj / Usuń na stronie wyświetlania
Teraz zaktualizuj blok ciała w widoku wyświetlania i dołącz linki dodaj / edytuj / usuń w następujący sposób.
{% 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 %}
Wyświetli następujący ekran jako dane wyjściowe -
Symfony składa się z zestawu komponentów PHP, frameworka aplikacji, społeczności i filozofii. Symfony jest niezwykle elastyczny i zdolny do spełnienia wszystkich wymagań zaawansowanych użytkowników, profesjonalistów i jest idealnym wyborem dla wszystkich początkujących z PHP.