Symfony — Введение
Веб-фреймворк PHP — это набор классов, который помогает разрабатывать веб-приложения. Symfony — это инфраструктура MVC с открытым исходным кодом для быстро развивающихся современных веб-приложений. Symfony — это полнофункциональный веб-фреймворк. Он содержит набор повторно используемых компонентов PHP. Вы можете использовать любые компоненты Symfony в приложениях независимо от платформы.
Symfony обладает огромным количеством функциональных возможностей и активным сообществом. Он имеет гибкую конфигурацию с использованием YAML, XML или аннотаций. Symfony интегрируется с независимой библиотекой и модулем PHP. Symfony в основном вдохновлен средами веб-приложений Ruby on Rails, Django и Spring. Компоненты Symfony используются во многих проектах с открытым исходным кодом, включая Composer, Drupal и phpBB.
Платформа Symfony состоит из нескольких компонентов, таких как компонент HttpFoundation, который понимает HTTP и предлагает хороший объект запроса и ответа, используемый другими компонентами. Другие являются просто вспомогательными компонентами, такими как Validator, который помогает проверять данные. Компонент ядра — это сердце системы. Ядро в основном является «основным классом», который управляет средой и отвечает за обработку http-запроса.
Хорошо организованная структура Symfony, чистый код и хорошие методы программирования облегчают веб-разработку. Symfony очень гибок, используется для создания микро-сайтов и обработки корпоративных приложений с миллиардами соединений.
Symfony Framework — Особенности
Symfony предназначен для оптимизации разработки веб-приложений и расширяет возможности с каждым выпуском.
Некоторые из характерных особенностей Symfony Framework следующие:
- Система на основе модели-представления-контроллера
- Высокопроизводительный PHP-фреймворк
- Гибкая маршрутизация URI
- Код многоразовый и простой в обслуживании
- Управление сессиями
- Регистрация ошибок
- Полнофункциональные классы баз данных с поддержкой нескольких платформ
- Поддерживает огромное и активное сообщество
- Набор развязанных и многоразовых компонентов
- Стандартизация и совместимость приложений
- Защита от подделки межсайтовых запросов и других атак
- Шаблонный движок Twig
Symfony предлагает разработчикам большую гибкость. Он имеет отличные возможности для отладки, читаемости кода и разработки расширяемых программ.
Symfony — это полнофункциональный веб-фреймворк; это очень эффективный инструмент для создания веб-приложений. Многочисленные компании предлагают услуги Symfony своим клиентам.
Ниже приведены некоторые преимущества, которые вы получаете, используя Symfony Framework.
-
Микрофрейм — Symfony может использоваться для разработки определенной функциональности. Вам не нужно перестраивать или устанавливать весь фреймворк.
-
Сокращает время разработки.
-
Очень зрелый движок шаблонов и быстро доставляет контент пользователям.
-
Совместимость и расширение — Программисты могут легко расширять все классы каркаса.
Микрофрейм — Symfony может использоваться для разработки определенной функциональности. Вам не нужно перестраивать или устанавливать весь фреймворк.
Сокращает время разработки.
Очень зрелый движок шаблонов и быстро доставляет контент пользователям.
Совместимость и расширение — Программисты могут легко расширять все классы каркаса.
Symfony Framework — Приложения
Компоненты Symfony можно использовать как часть других приложений, таких как Drupal, Laravel, phpBB, Behat, Doctrine и Joomla.
-
Drupal 8 — Drupal — это PHP-фреймворк с открытым исходным кодом для управления контентом. Drupal 8 использует основные уровни Symfony и расширяет его, чтобы обеспечить поддержку модулей Drupal.
-
Thelia — Thelia — это решение для электронной коммерции на основе Symfony. Первоначально Thelia была написана на PHP-коде и MySQL, однако она отставала в создании более быстрых приложений. Чтобы преодолеть этот недостаток, Thelia интегрировалась с Symfony для разработки приложений с возможностью индивидуальной настройки.
-
Dailymotion — Dailymotion — один из крупнейших в мире независимых сайтов о видео-развлечениях, базирующийся во Франции. Как только они решили перенести среду с открытым исходным кодом в большое сообщество, разработчики Dailymotion решили использовать функции компонентов Symfony для его гибкости.
Drupal 8 — Drupal — это PHP-фреймворк с открытым исходным кодом для управления контентом. Drupal 8 использует основные уровни Symfony и расширяет его, чтобы обеспечить поддержку модулей Drupal.
Thelia — Thelia — это решение для электронной коммерции на основе Symfony. Первоначально Thelia была написана на PHP-коде и MySQL, однако она отставала в создании более быстрых приложений. Чтобы преодолеть этот недостаток, Thelia интегрировалась с Symfony для разработки приложений с возможностью индивидуальной настройки.
Dailymotion — Dailymotion — один из крупнейших в мире независимых сайтов о видео-развлечениях, базирующийся во Франции. Как только они решили перенести среду с открытым исходным кодом в большое сообщество, разработчики Dailymotion решили использовать функции компонентов Symfony для его гибкости.
Symfony — Установка
В этой главе объясняется, как установить Symfony Framework на ваш компьютер. Установка фреймворка Symfony очень проста и легка. У вас есть два метода для создания приложений в среде Symfony. Первый метод — это использование Symfony Installer, приложения для создания проекта в среде Symfony. Второй метод — это композиторская установка. Давайте подробно рассмотрим каждый из этих методов в следующих разделах.
Системные Требования
Прежде чем перейти к установке, вам необходимо выполнить следующие системные требования.
- Веб-сервер (любой из следующих)
- WAMP (Windows)
- ЛАМПА (Linux)
- XAMP (мультиплатформенный)
- MAMP (Macintosh)
- Nginx (мультиплатформенный)
- Microsoft IIS (Windows)
- PHP встроенный веб-сервер разработки (мультиплатформенный)
- Операционная система: кроссплатформенная
- Поддержка браузера: IE (Internet Explorer 8+), Firefox, Google Chrome, Safari, Opera
- Совместимость PHP: PHP 5.4 или более поздняя версия. Чтобы получить максимальную выгоду, используйте последнюю версию.
Для этого урока мы будем использовать встроенный веб-сервер разработки PHP.
Установщик Symfony
Symfony Installer используется для создания веб-приложений в среде Symfony. Теперь давайте настроим установщик Symfony с помощью следующей команды.
$ 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
Теперь вы установили установщик Symfony на свой компьютер.
Создайте свое первое приложение Symfony
Следующий синтаксис используется для создания приложения Symfony в последней версии.
Синтаксис
symfony new app_name
Здесь app_name — это имя вашего нового приложения. Вы можете указать любое имя, которое вы хотите.
пример
symfony new HelloWorld
После выполнения вышеуказанной команды вы увидите следующий ответ.
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
Эта команда создает новый каталог с именем «firstapp /», который содержит пустой проект последней версии платформы Symfony.
Установить конкретную версию
Если вам нужно установить конкретную версию Symfony, используйте следующую команду.
symfony new app_name 2.8 symfony new app_name 3.1
Установка на основе Composer
Вы можете создавать приложения Symfony с помощью Composer. Надеюсь, вы установили композитор на свой компьютер. Если композитор не установлен, скачайте и установите его.
Следующая команда используется для создания проекта с использованием композитора.
$ composer create-project symfony/framework-standard-edition app_name
Если вам нужно указать конкретную версию, вы можете указать в приведенной выше команде.
Запуск приложения
Перейдите в каталог проекта и запустите приложение, используя следующую команду.
cd HelloWorld php bin/console server:run
После выполнения вышеупомянутой команды откройте браузер и запросите URL http: // localhost: 8000 / . Это дает следующий результат.
Результат
Symfony — Архитектура
Symfony — это коллекция высококачественных компонентов и комплектов. Компоненты представляют собой набор классов, обеспечивающих единую базовую функциональность. Например, компонент Cache обеспечивает функциональность кеша, которую можно добавить в любое приложение. Компоненты являются строительными блоками приложения Symfony. Symfony имеет более 30 компонентов высокого качества, которые используются во многих PHP-фреймворках, таких как Laravel, Silex и т. Д.
Пакеты похожи на плагин, но просты в создании и использовании. На самом деле, приложение Symfony само по себе является пакетом, состоящим из других пакетов. В одном пакете может использоваться любое количество компонентов Symfony, а также сторонних компонентов для предоставления таких функций, как веб-структура, доступ к базе данных и т. Д. Базовая веб-структура ядра Symfony представляет собой пакет с именем FrameworkBundle, и существует пакет с именем FrameworkExtraBundle, который предоставляет более сложные варианты написания веб-приложения.
Взаимосвязь между компонентами, пакетами и приложением Symfony указана на следующей диаграмме.
Веб-фреймворк
Symfony в основном предназначен для написания качественных веб-приложений с относительной легкостью. Он предоставляет различные варианты написания различных типов веб-приложений от простого веб-сайта до расширенных веб-сервисов на основе REST. Symfony предоставляет веб-фреймворк в виде отдельных пакетов. Общие комплекты, используемые в веб-инфраструктуре Symfony:
- FrameworkBundle
- FrameworkExtraBundle
- DoctrineBundle
Веб-фреймворк Symfony основан на архитектуре Model-View-Controller (MVC). Модель представляет структуру наших хозяйствующих субъектов. Просмотр показывает модели для пользователя в лучшем виде в зависимости от ситуации. Контроллер обрабатывает все запросы от пользователя, выполняет фактическую работу, взаимодействуя с моделью, и, наконец, предоставляет представлению необходимые данные для его отображения пользователю.
Веб-инфраструктура Symfony предоставляет все высокоуровневые функции, необходимые для приложения уровня предприятия. Ниже приведен простой рабочий процесс веб-приложения Symfony.
Рабочий процесс состоит из следующих шагов.
Шаг 1. Пользователь отправляет запрос в приложение через браузер, например, http://www.symfonyexample.com/index.
Шаг 2 — Браузер отправит запрос на веб-сервер, скажем, веб-сервер Apache.
Шаг 3 — Веб-сервер направит запрос в базовый PHP, который, в свою очередь, отправит его веб-платформе Symfony.
Шаг 4 — HttpKernel является основным компонентом веб-фреймворка Symfony. HttpKernel разрешает контроллер данного запроса с использованием компонента маршрутизации и передает запрос целевому контроллеру.
Шаг 5 — Вся бизнес-логика происходит в целевом контроллере.
Шаг 6 — Контроллер будет взаимодействовать с моделью, которая, в свою очередь, взаимодействует с источником данных через Doctrine ORM.
Шаг 7 — Как только контроллер завершает процесс, он генерирует ответ сам или через View Engine и отправляет его обратно на веб-сервер.
Шаг 8. Наконец, ответ будет отправлен веб-сервером в запрошенный браузер.
Symfony — Компоненты
Как обсуждалось ранее, компоненты Symfony представляют собой автономную библиотеку PHP, предоставляющую особую функцию, которая может использоваться в любом приложении PHP. Полезные новые компоненты вводятся в каждом выпуске Symfony. В настоящее время в платформе Symfony более 30 компонентов высокого качества. Давайте узнаем об использовании компонентов Symfony в этой главе.
Установка компонента Symfony
Компоненты Symfony можно легко установить с помощью команды composer. Следующая общая команда может быть использована для установки любого компонента Symfony.
cd /path/to/project/dir composer require symfony/<component_name>
Давайте создадим простое php-приложение и попробуем установить компонент Filesystem .
Шаг 1 — Создайте папку для приложения, пример файловой системы
cd /path/to/dev/folder mdkir filesystem-example cd filesystem-example
Шаг 2 — Установите компонент Файловая система, используя следующую команду.
composer require symfony/filesystem
Шаг 3 — Создайте файл main.php и введите следующий код.
<?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; } ?>
Первая строка очень важна, которая загружает все необходимые классы из всех компонентов, установленных с помощью команды Composer. Следующие строки используют класс файловой системы.
Шаг 4 — Запустите приложение с помощью следующей команды, и оно создаст новую папку sample-dir и файл test.txt под ним.
php main.php
Детали компонентов Symfony
Symfony предоставляет компоненты, начиная от простых функций, например, файловой системы, и заканчивая расширенными функциями, например, событиями, контейнерными технологиями и внедрением зависимостей. Сообщите нам обо всех компонентах один за другим в следующих разделах.
Файловая система
Компонент файловой системы предоставляет базовую системную команду, связанную с файлами и каталогами, например, создание файла, создание папки, существование файла и т. Д. Компонент файловой системы можно установить с помощью следующей команды.
composer require symfony/filesystem
искатель
Компонент Finder предоставляет свободные классы для поиска файлов и каталогов по указанному пути. Он обеспечивает простой способ перебора файлов в пути. Компонент Finder можно установить с помощью следующей команды.
composer require symfony/finder
Приставка
Компонент консоли предоставляет различные варианты для простого создания команд, которые могут быть выполнены в терминале. Symfony широко использует компонент Command для предоставления различных функций, таких как создание нового приложения, создание пакета и т. Д. Даже сборка PHP на веб-сервере может быть вызвана с помощью команды Symfony, сервер php bin / console: запустите, как показано в разделе установки , Компонент Console можно установить с помощью следующей команды.
composer require symfony/console
Давайте создадим простое приложение и создадим команду HelloCommand с использованием компонента Console и вызовем его.
Шаг 1 — Создайте проект с помощью следующей команды.
cd /path/to/project composer require symfony/console
Шаг 2 — Создайте файл main.php и включите следующий код.
<?php require __DIR__ . '/vendor/autoload.php'; use Symfony\Component\Console\Application; $app = new Application(); $app->run(); ?>
Класс приложения устанавливает необходимые функциональные возможности простого консольного приложения.
Шаг 3 — Запустите приложение php main.php , которое даст следующий результат.
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
Шаг 4 — Создайте класс с именем HelloCommand, расширяющий класс Command, в самом main.php .
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 { }
Приложение использует следующие четыре класса, доступные в компоненте Command .
-
Команда — используется для создания новой команды
-
InputInterface — используется для установки пользовательских входов
-
InputArgument — используется для получения пользовательских данных
-
OutputInterface — используется для вывода вывода на консоль
Команда — используется для создания новой команды
InputInterface — используется для установки пользовательских входов
InputArgument — используется для получения пользовательских данных
OutputInterface — используется для вывода вывода на консоль
Шаг 5 — Создайте функцию configure () и задайте имя, описание и текст справки.
protected function configure() { $this ->setName('app:hello') ->setDescription('Sample command, hello') ->setHelp('This command is a sample command') }
Шаг 6 — Создайте входной аргумент user для команды и установите его как обязательный.
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'); }
Шаг 7 — Создайте функцию execute () с двумя аргументами InputArgument и OutputArgument .
protected function execute(InputInterface $input, OutputInterface $output) { }
Шаг 8 — Используйте InputArgument, чтобы получить информацию о пользователе, введенную пользователем, и распечатать ее на консоли, используя OutputArgument .
protected function execute(InputInterface $input, OutputInterface $output) { $name = $input->getArgument('name'); $output->writeln('Hello, ' . $name); }
Шаг 9 — Зарегистрируйте HelloCommand в приложении, используя метод add класса Application .
$app->add(new HelloCommand());
Полная заявка заключается в следующем.
<?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(); } ?>
Шаг 10 — Теперь запустите приложение, используя следующую команду, и результатом будет Hello, Jon, как и ожидалось.
php main.php app:hello Jon
Symfony поставляется с предварительно созданным двоичным файлом, называемым console, в каталоге bin любого веб-приложения Symfony, который можно использовать для вызова команд в приложении.
Процесс
Компонент процесса предоставляет опции для запуска любой системной команды в подпроцессе безопасным и эффективным способом. Компонент процесса может быть установлен с помощью следующей команды.
composer require symfony/process
ClassLoader
Компонент ClassLoader обеспечивает реализацию для стандартного загрузчика классов PSR-0 и PSR-4 . Может использоваться для автоматической загрузки классов. Это будет амортизироваться в ближайшее время. Загрузчик классов на основе Composer предпочтительнее этого компонента. Компонент ClassLoader можно установить с помощью следующей команды.
composer require symfony/class-loader
PropertyAccess
Компонент PropertyAccess предоставляет различные параметры для чтения и записи данных объекта и массива с использованием строковой нотации. Например, массив Product с ключевой ценой может быть доступен динамически с помощью строки [price] .
$product = array( 'name' => 'Cake' 'price' => 10 ); var priceObj = $propertyAccesserObj->getValue($product, '[price]');
Компонент PropertyAccess можно установить с помощью следующей команды.
composer require symfony/property-access
PropertyInfo
Компонент PropertyInfo похож на компонент PropertyAccess, однако он работает только с объектами PHP и предоставляет гораздо больше функциональных возможностей.
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" } */
Компонент PropertyInfo можно установить с помощью следующей команды.
composer require symfony/property-info
EventDispatcher
Компонент EventDispatcher обеспечивает программирование на основе событий в PHP. Это позволяет объектам общаться друг с другом, отправляя события и слушая их. Мы научимся создавать события и слушать их в главе «События и слушатели событий».
Компонент EventDispatcher можно установить с помощью следующей команды.
composer require symfony/event-dispatcher
Внедрение зависимости
Компонент DependencyInjection предоставляет простой и эффективный механизм для создания объекта с его зависимостью. Когда проект расширяется, он имеет много классов с глубокой зависимостью, которые должны быть обработаны правильно. В противном случае проект провалится. DependencyInjection предоставляет простой и надежный контейнер для обработки зависимости. Мы узнаем о контейнерах и концепции внедрения зависимостей в главе Service Container.
Компонент DependencyInjection можно установить с помощью следующей команды.
composer require symfony/dependency-injection
Serializer
Компонент Serializer предоставляет возможность конвертировать объект PHP в определенный формат, такой как XML, JSON, Binary и т. Д., А затем позволяет преобразовывать его обратно в исходный объект без потери данных.
Компонент Serializer можно установить с помощью следующей команды.
composer require symfony/serializer
конфиг
Компонент Config предоставляет опции для загрузки, анализа, чтения и проверки конфигураций типа XML, YAML, PHP и ini. Он также предоставляет различные опции для загрузки деталей конфигурации из базы данных. Это один из важных компонентов, полезных для настройки веб-приложения в четкой и лаконичной форме. Компонент Config может быть установлен с помощью следующей команды.
composer require symfony/config
ExpressionLanguage
Компонент ExpessionLanguage предоставляет полноценный механизм выражений. Выражения являются однострочными и предназначены для возврата значения. Механизм выражений позволяет легко компилировать, анализировать и получать значения из выражения. Он позволяет одному или нескольким выражениям использоваться в среде конфигурации (файле) программистом, не являющимся PHP, как говорит системный администратор. Компонент ExpressionLanguage можно установить с помощью следующей команды.
composer require symfony/expression-language
OptionsResolver
Компонент OptionsResolver предоставляет способ проверки системы опций, используемой в нашей системе. Например, настройки базы данных помещаются в массив, dboption с хостом, именем пользователя, паролем и т. Д. В качестве ключей. Вам необходимо проверить записи перед использованием его для подключения к базе данных. OptionsResolver упрощает эту задачу, предоставляя простой класс OptionsResolver и распознаватель методов, который разрешает настройку базы данных и, если есть какие-либо проблемы с проверкой, сообщает об этом.
$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);
Компонент OptionsResolver можно установить с помощью следующей команды.
composer require symfony/options-resolver
Dotenv
Компонент Dotenv предоставляет различные опции для анализа файлов .env и определенной в них переменной, чтобы они были доступны через getenv (), $ _ENV или $ _SERVER . Компонент Dotenv можно установить с помощью следующей команды.
composer require symfony/dotenv
кэш
Компонент Cache обеспечивает расширенную реализацию PSR-6 . Его можно использовать для добавления кеша в наше веб-приложение. Поскольку он следует PSR-6 , его легко начать, и его можно легко использовать вместо другого компонента кэша на основе PSR-6. Компонент кэша может быть установлен с помощью следующей команды.
composer require symfony/cache
международный
Компонент Intl является заменой библиотеки для расширения C Intl. Компонент Intl можно установить с помощью следующей команды.
composer require symfony/intl
Перевод
Компонент перевода предоставляет различные варианты интернационализации нашего приложения. Обычно сведения о переводе с разных языков хранятся в файле, по одному файлу на каждый язык, и загружаются динамически во время выполнения приложения. Существуют разные форматы для написания файла перевода. Компонент перевода предоставляет различные варианты загрузки любого типа формата, такого как обычный файл PHP, CSV, INI, JSON, Yaml, файл ресурсов ICU и т. Д. Компонент перевода можно установить с помощью следующей команды.
composer require symfony/translation
Workflow
Компонент Workflow предоставляет расширенные инструменты для обработки конечного автомата. Предоставляя эту функциональность простым и объектно-ориентированным способом, компонент Workflow позволяет относительно легко программировать на PHP. Мы узнаем об этом подробно в главе Advanced Concept.
Компонент рабочего процесса можно установить с помощью следующей команды.
composer require symfony/workflow
YAML
Компонент Yaml предоставляет параметр, который анализирует формат файла YAML и преобразует его в PHP-массивы. Он также может записывать YAML-файл из простого массива php. Компонент Yaml можно установить с помощью следующей команды.
composer require symfony/yaml
Ldap
Компонент Ldap предоставляет PHP-классы для подключения к серверу LDAP или Active Directory и аутентификации пользователя на его основе. Предоставляет возможность подключения к контроллеру домена Windows. Компонент Ldap можно установить с помощью следующей команды.
composer require symfony/ldap
отлаживать
Компонент отладки предоставляет различные опции для включения отладки в среде PHP. Обычно отладка PHP-кода является сложной задачей, но компонент отладки предоставляет простые классы, чтобы упростить процесс отладки и сделать его чистым и структурированным. Отладочный компонент можно установить с помощью следующей команды.
composer require symfony/debug
Секундомер
Компонент Секундомер предоставляет класс Секундомер для профилирования нашего кода PHP. Простое использование заключается в следующем.
use Symfony\Component\Stopwatch\Stopwatch; $stopwatch = new Stopwatch(); $stopwatch->start('somename'); // our code to profile $profiled_data = $stopwatch->stop('somename'); echo $profiled_data->getPeriods()
Компонент секундомера можно установить с помощью следующей команды.
composer require symfony/stopwatch
VarDumper
Компонент VarDumper обеспечивает лучшую функцию dump () . Просто включите компонент VarDumper и используйте функцию dump, чтобы получить улучшенную функциональность. Компонент VarDumper можно установить с помощью следующей команды.
composer require symfony/var-dumper
BrowserKit
Компонент BrowserKit предоставляет абстрактный клиентский интерфейс браузера. Его можно использовать для программного тестирования веб-приложения. Например, он может запросить форму, ввести пример данных и отправить его, чтобы найти любую проблему в форме программным путем. Компонент BrowserKit можно установить с помощью следующей команды.
composer require symfony/browser-kit
PHPUnit Bridge
Компонент PHPUnit Bridge предоставляет множество возможностей для улучшения среды тестирования PHPUnit. Компонент PHPUnit Bridge можно установить с помощью следующей команды.
composer require symfony/phpunit-bridge
Актив
Компонент актива обеспечивает общую обработку активов в веб-приложении. Он генерирует URL для таких ресурсов, как CSS, HTML, JavaScript, а также выполняет поддержку версий. Мы подробно рассмотрим компонент актива в главе View Engine. Компонент актива можно установить с помощью следующей команды.
composer require symfony/asset
CSSSelector
Компонент CssSelector предоставляет возможность конвертировать селекторы на основе CSS в выражение XPath. Веб-разработчик знает выражение Selectors на основе CSS больше, чем выражение XPath, но наиболее эффективным выражением для поиска элемента в документах HTML и XML является выражение XPath .
CssSelector позволяет разработчику записывать выражение в селекторах CSS , однако компонент преобразует его в выражение XPath перед его выполнением. Таким образом, разработчик имеет преимущество в простоте CSS-селекторов и эффективности выражения XPath.
Компонент CssSelector можно установить с помощью следующей команды.
composer require symfony/css-selector
DomCrawler
Компонент DomCrawler предоставляет различные варианты поиска элемента в документе HTML и XML с использованием концепции DOM. Он также предоставляет возможность использовать выражение XPath для поиска элемента. Компонент DomCrawler можно использовать вместе с компонентом CssSelector для использования селекторов CSS вместо выражения XPath. Компонент DomCrawler можно установить с помощью следующей команды.
composer require symfony/dom-crawler
форма
Компонент формы позволяет легко создавать формы в веб-приложении. Мы подробно изучим программирование форм в главе Форма. Компонент формы можно установить с помощью следующей команды.
composer require symfony/form
HttpFoundation
Компонент HttpFoundation предоставляет объектно-ориентированный уровень для спецификации HTTP. По умолчанию PHP предоставляет подробные HTTP-запросы и ответы в виде объектов на основе массива, таких как $ _GET, $ _POST, $ _FILES, $ _SESSION и т. Д. Функцию, основанную на HTTP, такую как установка файла cookie, можно выполнить с помощью простой простой функции setCookie ( ) HttpFoundation предоставляет все функции, связанные с HTTP, в небольшом наборе классов, таких как Request, Response, RedirectResponse и т. Д. Об этих классах мы узнаем в следующих главах.
Компонент HttpFoundation можно установить с помощью следующей команды.
composer require symfony/http-foundation
HttpKernel
Компонент HttpKernel является основным компонентом веб-установки Symfony. Он предоставляет все функции, необходимые для веб-приложения — от получения объекта Request до отправки объекта Response . Полная архитектура веб-приложения Symfony предоставляется HttpKernel, как описано в архитектуре веб-инфраструктуры Symfony.
Компонент HttpKernel можно установить с помощью следующей команды.
composer require symfony/http-kernel
маршрутизация
Компонент маршрутизации отображает HTTP-запрос на заранее определенный набор переменных конфигурации. Маршрутизация решает, какая часть нашего приложения должна обрабатывать запрос. Мы узнаем больше о маршрутизации в главе «Маршрутизация».
Компонент маршрутизации может быть установлен с помощью следующей команды.
composer require symfony/filesystem
шаблонирование
Компонент шаблонов обеспечивает необходимую инфраструктуру для построения эффективной системы шаблонов. Symfony использует компонент Templating для реализации своего движка View. Мы узнаем больше о компоненте Templating в главе движка View.
Шаблонный компонент может быть установлен с помощью следующей команды.
composer require symfony/templating
Validator
Компонент Validator обеспечивает реализацию спецификации проверки bean-компонента JSR-303 . Его можно использовать для проверки формы в веб-среде. Мы узнаем больше о Validator в главе Validation.
Компонент валидатора можно установить с помощью следующей команды.
composer require symfony/validator
Безопасность
Компонент безопасности обеспечивает полную систему безопасности для нашего веб-приложения, будь то базовая аутентификация HTTP, дайджест-аутентификация HTTP, интерактивная аутентификация на основе форм, вход в систему сертификации X.509 и т. Д. Он также обеспечивает механизм авторизации на основе роли пользователя через встроенную систему ACL. , Мы узнаем более подробно в главе «Расширенная концепция».
Компонент безопасности может быть установлен с помощью следующей команды.
composer require symfony/security
Symfony — Сервисный контейнер
В любом приложении объекты имеют тенденцию увеличиваться с ростом приложения. По мере увеличения объектов зависимость между объектами также увеличивается. Зависимость объекта должна быть обработана правильно для успешного приложения.
Как уже говорилось в главе «Компоненты», Symfony предоставляет простой и эффективный компонент DependencyInjection для обработки зависимости объекта. Служебный контейнер — это контейнер объектов с правильно разрешенной зависимостью между ними. Давайте узнаем, как использовать компонент DependencyInjection в этой главе.
Давайте создадим класс Greeter . Цель класса Greeter — приветствовать пользователя, как показано в следующем примере.
$greeter = new Greeter('Hi'); $greeter->greet('Jon'); // print "Hi, Jon"
Полный код класса Greeter выглядит следующим образом.
class Greeter { private $greetingText; public function __construct($greetingText) { $this->greetingText = $greetingText; } public function greet($name) { echo $this->greetingText . ", " . $name . "\r\n"; } }
Теперь давайте добавим класс Greeter в сервисный контейнер. Symfony предоставляет ContainerBuilder для создания нового контейнера. Как только контейнер создан, класс Greeter может быть зарегистрирован в нем с помощью метода register контейнера.
use Symfony\Component\DependencyInjection\ContainerBuilder; $container = new ContainerBuilder(); $container ->register('greeter', 'Greeter') ->addArgument('Hi');
Здесь мы использовали статический аргумент для указания текста приветствия, Привет. Symfony также обеспечивает динамическую настройку параметров. Чтобы использовать динамический параметр, нам нужно выбрать имя и указать его между%, а параметр можно установить с помощью метода setParameter контейнера.
$container = new ContainerBuilder(); $container ->register('greeter', 'Greeter') ->addArgument('%greeter.text%'); $container->setParameter('greeter.text', 'Hi');
Мы зарегистрировали класс Greeter с правильной настройкой. Теперь мы можем попросить контейнер предоставить правильно сконфигурированный объект Greeter, используя метод get контейнера.
$greeter = $container->get('greeter'); $greeter->greet('Jon'); // prints "Hi, Jon"
Мы успешно зарегистрировали класс, добавили его в контейнер, извлекли его из контейнера и использовали. Теперь давайте создадим другой класс User , который использует класс Greeter и посмотрим, как его зарегистрировать.
class User { private $greeter; public $name; public $age; public function setGreeter(\Greeter $greeter) { $this->greeter = $greeter; } public function greet() { $this->greeter->greet($this->name); } }
Класс User получает класс Greeter, используя один из его метода setter, setGreeter . Для этого сценария Symfony предоставляет метод addMethodCall и класс Reference для ссылки на другой класс, как показано в следующем коде.
use Symfony\Component\DependencyInjection\Reference; $container ->register('user', 'User') ->addMethodCall('setGreeter', array(new Reference('greeter')));
Наконец, мы зарегистрировали два класса, Greeter и User, имеющие тесные связи между ними. Теперь мы можем безопасно извлечь объект User с правильно настроенным классом Greeter из контейнера, как показано в следующем коде.
$container->setParameter('greeter.text', 'Hi'); $user = $container->get('user'); $user->name = "Jon"; $user->age = 20; $user->greet(); // Prints "Hi, Jon"
Мы видели, как настроить объект в контейнере, используя сам PHP. Symfony предоставляет и другие механизмы. Это файлы конфигурации XML и YAML. Давайте посмотрим, как настроить контейнер с использованием YAML. Для этого установите компоненты symfony / config и symfony / yaml вместе с компонентами symfony / dependency -jection .
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
Конфигурация YAML будет записана в отдельном файле services.yml . Конфигурация YAML состоит из двух разделов, параметров и сервисов . Раздел Parameters определяет все обязательные параметры. Раздел Сервисы определяет все объекты. Раздел служб дополнительно разделен на несколько разделов, а именно: класс, аргументы и вызовы . Класс указывает фактический класс. Аргументы определяют аргументы конструктора. Наконец, вызовы определяют методы установки. На другой класс можно ссылаться с помощью символа @, @greeter.
parameters: greeter.text: 'Hello' services: greeter: class: Greeter arguments: ['%greeter.text%'] user: class: User calls: - [setGreeter, ['@greeter']]
Теперь services.yml может быть загружен и настроен с использованием FileLoader и YamlFileLoader, как показано в следующем коде.
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();
Полный список кодов выглядит следующим образом.
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']]
Веб-фреймворк Symfony широко использует компонент внедрения зависимостей. Все компоненты связаны централизованным сервисным контейнером. Веб-фреймворк Symfony предоставляет контейнер во всем его контроллере через свойство контейнера . Через него мы можем зарегистрировать весь объект, например, регистратор, почтовик и т. Д.
$logger = $this->container->get('logger'); $logger->info('Hi');
Чтобы найти объект, зарегистрированный в контейнере, используйте следующую команду.
cd /path/to/app php bin/console debug:container
В приветственном веб-приложении, созданном в главе по установке, содержится около 200+ объектов.
Symfony — События и EventListener
Symfony обеспечивает программирование на основе событий через свой компонент EventDispatcher . Любое корпоративное приложение нуждается в программировании на основе событий для создания настраиваемого приложения. События являются одним из основных инструментов взаимодействия объектов друг с другом. Без событий объект не взаимодействует эффективно.
Процесс программирования, основанного на событиях, можно обобщить следующим образом: — объект, называемый источником события, просит центральный диспетчерский объект зарегистрировать событие, например, user.registered. Один или несколько объектов, называемых слушателем, запрашивают у центрального объекта диспетчера, что он хочет прослушать определенное событие, например, user.registered. В какой-то момент времени исходный объект Event просит центральный диспетчерский объект отправить событие, скажем, user.registered вместе с объектом Event вместе с необходимой информацией. Центральный диспетчер информирует все объекты слушателя о событии, например, user.registered и его объект Event *.
В программировании на основе событий у нас есть четыре типа объектов: источник события, прослушиватель событий, даже диспетчер событий и само событие.
Давайте напишем простое приложение, чтобы понять концепцию.
Шаг 1 — Создайте проект, пример события-диспетчера .
cd /path/to/dir mkdir event-dispatcher-example cd event-dispatcher-example composer require symfony/event-dispatcher
Шаг 2 — Создать класс .User .
class User { public $name; public $age; } $user = new User(); $user->name = "Jon"; $user->age = 25
Шаг 3 — Создать событие 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);
Здесь UserRegisteredEvent имеет доступ к объекту User . Название мероприятия — user.registered .
Шаг 4 — Создайте слушателя, UserListener .
class UserListener { public function onUserRegistrationAction(Event $event) { $user = $event->getUser(); echo $user->name . "\r\n"; echo $user->age . "\r\n"; } } $listener = new UserListener();
Шаг 5 — Создайте объект диспетчера событий.
use Symfony\Component\EventDispatcher\EventDispatcher; $dispatcher = new EventDispatcher();
Шаг 6 — Соедините слушатель и событие, используя объект диспетчера и его метод, addListener .
$dispatcher ->addListener( UserRegisteredEvent::NAME, array($listener, 'onUserRegistrationAction'));
Мы также можем добавить анонимную функцию в качестве прослушивателя событий, как показано в следующем коде.
$dispatcher ->addListener( UserRegisteredEvent::NAME, function(Event $event) { $user = $event->getUser(); echo $user->name . "\r\n"; });
Шаг 7 — Наконец, запустить / отправить событие, используя метод диспетчера событий, dispatch .
$dispatcher->dispatch(UserRegisteredEvent::NAME, $event);
Полный список кодов выглядит следующим образом.
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); ?>
Результат
Jon Jon 25
Веб-фреймворк Symfony имеет много событий, и можно зарегистрировать прослушиватель этих событий и запрограммировать его соответствующим образом. Одним из примеров события является kernel.exception, а соответствующее событие — GetResponseForExceptionEvent , которое содержит объект ответа (вывод веб-запроса). Это используется для перехвата исключения и изменения ответа с помощью общей информации об ошибке, а не для отображения ошибки времени выполнения для пользователей.
Symfony — Выражение
Как мы уже говорили ранее, язык выражений является одной из характерных особенностей приложения Symfony. Выражение Symfony в основном создается для использования в среде конфигурации. Это позволяет непрограммисту настраивать веб-приложение без особых усилий. Давайте создадим простое приложение для проверки выражения.
Шаг 1 — Создать проект, выражение-язык-пример .
cd /path/to/dir mkdir expression-language-example cd expression-language-example composer require symfony/expression-language
Шаг 2 — Создайте объект выражения.
use Symfony\Component\ExpressionLanguage\ExpressionLanguage; $language = new ExpressionLanguage();
Шаг 3 — Проверьте простое выражение.
echo "Evaluated Value: " . $language->evaluate('10 + 12') . "\r\n" ; echo "Compiled Code: " . $language->compile('130 % 34') . "\r\n" ;
Шаг 4 — Выражение Symfony настолько мощное, что может перехватывать объект PHP и его свойства также на языке выражений.
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";
Здесь выражения product.price и product.price> 5 пересекают цену свойства объекта $ product и оценивают результат.
Полное кодирование выглядит следующим образом.
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"; ?>
Результат
Evaluated Value: 22 Compiled Code: (130 % 34) Product price is 10 Is Product price higher than 5: 1
Symfony — Связки
Пакет Symfony — это набор файлов и папок, организованных в определенной структуре. Пакеты моделируются таким образом, чтобы их можно было повторно использовать в нескольких приложениях. Само основное приложение упаковано в пакет и обычно называется AppBundle .
Пакет может быть упакован специально для приложения, такого как AdminBundle (раздел администратора), BlogBundle (блог сайта) и т. Д. Такие пакеты не могут совместно использоваться приложением. Вместо этого мы можем смоделировать определенную часть приложения, такую как блоги, как универсальный пакет, так что мы можем просто скопировать пакет из одного приложения в другое приложение для повторного использования функциональности блога.
Структура расслоения
Основная структура пучка заключается в следующем.
-
Контроллер — Все контроллеры должны быть размещены здесь.
-
DependencyInjection — Здесь необходимо разместить весь код и конфигурацию, связанные с внедрением зависимостей.
-
Resources / config — конфигурации, связанные с пакетом, находятся здесь.
-
Ресурсы / Представление — Связанные шаблоны представления помещены здесь.
-
Ресурсы / общедоступные — здесь размещены связанные с пакетом таблицы стилей, скрипты Java, изображения и т. Д.
-
Тесты — файлы связанных с модулем тестов находятся здесь.
Контроллер — Все контроллеры должны быть размещены здесь.
DependencyInjection — Здесь необходимо разместить весь код и конфигурацию, связанные с внедрением зависимостей.
Resources / config — конфигурации, связанные с пакетом, находятся здесь.
Ресурсы / Представление — Связанные шаблоны представления помещены здесь.
Ресурсы / общедоступные — здесь размещены связанные с пакетом таблицы стилей, скрипты Java, изображения и т. Д.
Тесты — файлы связанных с модулем тестов находятся здесь.
Создание пакета
Давайте создадим простой пакет TutorialspointDemoBundle в нашем приложении HelloWorld .
Шаг 1 — Выберите пространство имен. Пространство имен пакета должно включать имя поставщика и имя пакета. В нашем случае это Tutorialspoint \ DemoBundle .
Шаг 2 — Создайте пустой класс, TutorialspointDemoBundle , расширив класс Bundle и поместите его в каталог src / Tutorialspoint / DemoBundle .
namespace Tutorialspoint\DemoBundle; use Symfony\Component\HttpKernel\Bundle\Bundle; class TutorialspointDemoBundle extends Bundle { }
Шаг 3 — Зарегистрируйте класс в списке пакетов, поддерживаемых приложением в классе AppKernel .
public function registerBundles() { $bundles = array( // ... // register your bundle new Tutorialspoint\DemoBundle\TutorialspointDemoBundle(), ); return $bundles; }
Это все, что нужно для создания пустого пакета, а все остальные понятия такие же, как и у приложения. Symfony также предоставляет консольную команду generate: bundle для упрощения процесса создания нового пакета, который заключается в следующем.
php bin/console generate:bundle --namespace = Tutorialspoint/DemoBundle
Результат
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 :).
Создание простого веб-приложения
В этой главе объясняется, как создать простое приложение в среде Symfony. Как уже говорилось ранее, вы знаете, как создать новый проект в Symfony.
Мы можем взять пример «студенческих» деталей. Давайте начнем с создания проекта с именем «student» с помощью следующей команды.
symfony new student
После выполнения команды создается пустой проект.
контроллер
Symfony основан на паттерне разработки Model-View-Controller (MVC). MVC — это программный подход, который отделяет логику приложения от представления. Контроллер играет важную роль в Symfony Framework. Все веб-страницы в приложении должны обрабатываться контроллером.
Класс DefaultController находится в «src / AppBundle / Controller» . Там вы можете создать свой собственный класс Controller.
Перейдите в папку «src / AppBundle / Controller» и создайте новый класс StudentController .
Ниже приведен основной синтаксис для класса StudentController .
StudentController.php
namespace AppBundle\Controller; use Symfony\Component\HttpFoundation\Response; class StudentController { }
Теперь вы создали StudentController. В следующей главе мы подробнее обсудим контроллер.
Создать маршрут
Как только Контроллер был создан, нам нужно направить на конкретную страницу. Маршрутизация отображает URI запроса на метод конкретного контроллера.
Ниже приведен основной синтаксис для маршрутизации.
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!'); } }
В приведенном выше синтаксисе @Route («/ student / home») является маршрутом. Он определяет шаблон URL для страницы.
homeAction () — это метод действия, в котором вы можете построить страницу и вернуть объект Response.
Мы подробно рассмотрим маршрутизацию в следующей главе. Теперь запросите URL «http: // localhost: 8000 / student / home», и он даст следующий результат.
Результат
Symfony — Контроллеры
Контроллер отвечает за обработку каждого запроса, поступающего в приложение Symfony. Контроллер читает информацию из запроса. Затем создает и возвращает объект ответа клиенту.
Согласно Symfony, класс DefaultController находится в «src / AppBundle / Controller» . Это определяется следующим образом.
DefaultController.php
<?php namespace AppBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Response; class DefaultController extends Controller { }
Здесь компонент HttpFoundation определяет объектно-ориентированный уровень для спецификации HTTP, а FrameworkBundle содержит большую часть «базовой» функциональности инфраструктуры.
Объект запроса
Класс Request является объектно-ориентированным представлением сообщения HTTP-запроса.
Создание объекта запроса
Запрос может быть создан с помощью метода createFromGlobals () .
use Symfony\Component\HttpFoundation\Request; $request = Request::createFromGlobals();
Вы можете смоделировать запрос, используя Globals. Вместо того чтобы создавать запрос на основе глобальных переменных PHP, вы также можете имитировать запрос.
$request = Request::create( '/student', 'GET', array('name' => 'student1') );
Здесь метод create () создает запрос на основе URI, метода и некоторых параметров.
Переопределение объекта запроса
Вы можете переопределить глобальные переменные PHP, используя метод overrideGlobals () . Это определяется следующим образом.
$request->overrideGlobals();
Доступ к объекту запроса
Доступ к веб-странице можно получить в контроллере (метод действия) с помощью метода getRequest () базового контроллера.
$request = $this->getRequest();
Идентификация объекта запроса
Если вы хотите идентифицировать запрос в вашем приложении, метод PathInfo вернет уникальный идентификатор URL запроса. Он определяется следующим образом.
$request->getPathInfo();
Объект ответа
Единственное требование к контроллеру — вернуть объект Response. Объект Response содержит всю информацию из данного запроса и отправляет ее обратно клиенту.
Ниже приведен простой пример.
пример
use Symfony\Component\HttpFoundation\Response; $response = new Response(‘Default'.$name, 10);
Вы можете определить объект Response в JSON следующим образом.
$response = new Response(json_encode(array('name' => $name))); $response->headers->set('Content-Type', 'application/json');
Конструктор ответа
Конструктор содержит три аргумента —
- Содержание ответа
- Код статуса
- Массив заголовков HTTP
Ниже приведен основной синтаксис.
use Symfony\Component\HttpFoundation\Response; $response = new Response( 'Content', Response::HTTP_OK, array('content-type' => 'text/html') );
Например, вы можете передать аргумент содержимого как,
$response->setContent(’Student details’);
Точно так же вы можете передать и другие аргументы.
Отправка ответа
Вы можете отправить ответ клиенту, используя метод send () . Это определяется следующим образом.
$response->send();
Чтобы перенаправить клиента на другой URL, вы можете использовать класс RedirectResponse .
Это определяется следующим образом.
use Symfony\Component\HttpFoundation\RedirectResponse; $response = new RedirectResponse('http://tutorialspoint.com/');
FrontController
Один файл PHP, который обрабатывает каждый запрос, поступающий в ваше приложение. FrontController выполняет маршрутизацию разных URL-адресов во внутренние части приложения.
Ниже приведен основной синтаксис 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();
Здесь функция in_array () ищет в массиве конкретное значение.
Symfony — Маршрутизация
Маршрутизация отображает URI запроса на метод конкретного контроллера. В общем, любой URI состоит из следующих трех частей:
- Имя хоста
- Сегмент пути
- Сегмент запросов
Например, в URI / URL http://www.tutorialspoint.com/index?q=data, www.tutorialspoint.com — сегмент имени хоста, index — сегмент пути, а q = data — сегмент запроса. Как правило, маршрутизация проверяет сегмент страницы с набором ограничений. Если какое-либо ограничение совпадает, то оно возвращает набор значений. Одним из основных значений является контроллер.
Аннотации
Аннотация играет важную роль в настройке приложения Symfony. Аннотация упрощает конфигурацию, объявляя конфигурацию в самом кодировании. Аннотация — это не что иное, как предоставление метаинформации о классе, методах и свойствах. Маршрутизация широко использует аннотации. Несмотря на то, что маршрутизация может быть выполнена без аннотации, аннотация значительно упрощает маршрутизацию.
Ниже приведен пример аннотации.
/** * @Route(“/student/home”) */ public function homeAction() { // ... }
Концепции маршрутизации
Рассмотрим класс StudentController, созданный в проекте «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() { } }
Здесь маршрутизация выполняется в два этапа. Если вы идете в / student / home , первый маршрут совпадает, затем выполняется homeAction () . В противном случае, если вы перейдете в / student / about , второй маршрут будет найден, а затем выполняется aboutAction () .
Добавление подстановочных знаков
Предположим, у вас есть нумерованный список записей о студентах с такими URL-адресами, как / student / 2 и / student / 3 для страниц 2 и 3 соответственно. Затем, если вы хотите изменить путь к маршруту, вы можете использовать форматы подстановочных знаков.
пример
// 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) { // ... } }
Здесь \ d + является регулярным выражением, которое соответствует цифре любой длины.
Назначить заполнитель
Вы можете назначить значение заполнителя в маршрутизации. Это определяется следующим образом.
// 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) { // ... } }
Здесь, если вы перейдете к / student, маршрут student_about будет соответствовать, и $ page по умолчанию будет иметь значение 1.
Перенаправление на страницу
Если вы хотите перенаправить пользователя на другую страницу, используйте методы redirectToRoute () и redirect () .
public function homeAction() { // redirect to the "homepage" route return $this->redirectToRoute('homepage'); // redirect externally \return $this->redirect('http://example.com/doc'); }
Генерация URL
Чтобы сгенерировать URL, рассмотрите имя маршрута, имя студента и подстановочный знак, имена студентов, используемые в пути для этого маршрута. Полный список для создания URL-адреса определяется следующим образом.
class StudentController extends Controller { public function aboutAction($name) { // ... // /student/student-names $url = $this->generateUrl( ‘student_name’, array(‘name’ => ’student-names’) ); } }
StudentController
Рассмотрим простой пример маршрутизации в классе StudentController следующим образом.
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>' ); } }
Теперь запросите URL «http: // localhost: 8000 / student / home», и он даст следующий результат.
Точно так же вы можете создать другой маршрут для aboutAction () .
Symfony — Просмотр движка
Уровень представления — это уровень представления приложения MVC. Он отделяет логику приложения от логики представления.
Когда контроллеру необходимо сгенерировать HTML, CSS или любой другой контент, он направляет задачу в механизм шаблонов.
Шаблоны
Шаблоны — это, в основном, текстовые файлы, используемые для создания любых текстовых документов, таких как HTML, XML и т. Д. Он используется для экономии времени и уменьшения количества ошибок.
По умолчанию шаблоны могут находиться в двух разных местах:
app / Resources / views / — Каталог представлений приложения может содержать макеты и шаблоны вашего приложения. Он также переопределяет сторонние шаблоны пакетов.
vendor / path / to / Bundle / Resources / views / — Каждый сторонний пакет содержит свои шаблоны в своем каталоге «Resources / views /».
Twig Engine
Symfony использует мощный язык шаблонов, который называется Twig . Twig позволяет очень легко создавать краткие и удобочитаемые шаблоны. Шаблоны Twig просты и не будут обрабатывать теги PHP. Twig выполняет управление пробелами, изолированную среду и автоматическое экранирование HTML.
Синтаксис
Twig содержит три типа специального синтаксиса —
-
{{…}} — печатает переменную или результат выражения в шаблон.
-
{% …%} — тег, который управляет логикой шаблона. Он в основном используется для выполнения функции.
-
{# … #} — Синтаксис комментариев. Используется для добавления однострочных или многострочных комментариев.
{{…}} — печатает переменную или результат выражения в шаблон.
{% …%} — тег, который управляет логикой шаблона. Он в основном используется для выполнения функции.
{# … #} — Синтаксис комментариев. Используется для добавления однострочных или многострочных комментариев.
Базовый шаблон ветки находится в «app / Resources / views / base.html.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'); } }
Здесь метод render () визуализирует шаблон и помещает это содержимое в объект Response.
Теперь перейдите в каталог «views» и создайте папку «student», а внутри этой папки создайте файл «home.html.twig». Добавьте следующие изменения в файл.
home.html.twig
//app/Resources/views/student/home.html.twig <h3>Student application!</h3>
Вы можете получить результат, запросив URL «http: // localhost: 8000 / student / home».
По умолчанию Twig поставляется с длинным списком тегов, фильтров и функций. Давайте пройдемся по одному подробно.
Теги
Twig поддерживает следующие важные теги —
Делать
Тег do выполняет функции, аналогичные регулярному выражению, за исключением того, что он ничего не печатает. Его синтаксис выглядит следующим образом —
{% do 5 + 6 %}
Включают
Оператор include включает шаблон и возвращает отображаемое содержимое этого файла в текущее пространство имен. Его синтаксис выглядит следующим образом —
{% include 'template.html' %}
Расширяет
Тег extends может использоваться для расширения шаблона из другого. Его синтаксис выглядит следующим образом —
{% extends "template.html" %}
блок
Блок действует как заполнитель и заменяет содержимое. Имена блоков состоят из буквенно-цифровых символов и символов подчеркивания. Например,
<title>{% block title %}{% endblock %}</title>
встраивать
Тег embed выполняет комбинацию включений и расширений. Это позволяет вам включать содержимое другого шаблона. Это также позволяет вам переопределить любой блок, определенный внутри включенного шаблона, например, при расширении шаблона. Его синтаксис выглядит следующим образом —
{% embed “new_template.twig” %} {# These blocks are defined in “new_template.twig" #} {% block center %} Block content {% endblock %} {% endembed %}
Фильтр
Разделы фильтров позволяют применять обычные фильтры Twig к блоку данных шаблона. Например,
{% filter upper %} symfony framework {% endfilter %}
Здесь текст будет изменен на верхний регистр.
За
Для цикла извлекает каждый элемент в последовательности. Например,
{% for x in 0..10 %} {{ x }} {% endfor %}
Если
Оператор if в Twig похож на PHP. Выражение оценивается как истинное или ложное. Например,
{% if value == true %} <p>Simple If statement</p> {% endif %}
фильтры
Веточка содержит фильтры. Он используется для изменения содержимого перед его отображением. Ниже приведены некоторые из известных фильтров.
длина
Фильтр длины возвращает длину строки. Его синтаксис выглядит следующим образом —
{% if name|length > 5 %} ... {% endif %}
ниже
Нижний фильтр преобразует значение в нижний регистр. Например,
{{ 'SYMFONY'|lower }}
Это дало бы следующий результат —
symfony
Точно так же вы можете попробовать заглавные буквы.
замещать
Фильтр замены форматирует данную строку, заменяя заполнители. Например,
{{ "tutorials point site %si% and %te%."|replace({'%si%': web, '%te%': "site"}) }}
Это даст следующий результат —
tutorials point website
заглавие
Фильтр заголовков возвращает версию значения заголовка. Например,
{{ 'symfony framework '|title }}
Это даст следующий результат —
Symfony Framework
Сортировать
Фильтр сортировки сортирует массив. Его синтаксис выглядит следующим образом —
{% for user in names|sort %} ... {% endfor %}
Отделка
Фильтр обрезки удаляет пробелы (или другие символы) с начала и конца строки. Например,
{{ ' Symfony! '|trim }}
Это даст следующий результат —
Symfony!
функции
Twig поддерживает функции. Используется для получения конкретного результата. Ниже приведены некоторые важные функции Twig.
атрибут
Функция атрибута может использоваться для доступа к «динамическому» атрибуту переменной. Его синтаксис выглядит следующим образом —
{{ attribute(object, method) }} {{ attribute(object, method, arguments) }} {{ attribute(array, item) }}
Например,
{{ attribute(object, method) is defined ? 'Method exists' : 'Method does not exist' }}
постоянная
Функция Constant возвращает постоянное значение для указанной строки. Например,
{{ constant('Namespace\\Classname::CONSTANT_NAME') }}
цикл
Функция цикла циклически обрабатывает массив значений. Например,
{% set months = [‘Jan’, ‘Feb’, ‘Mar’] %} {% for x in 0..12 %} { cycle(months, x) }} {% endfor %}
Дата
Преобразует аргумент в дату, чтобы разрешить сравнение даты. Например,
<p>Choose your location before {{ 'next Monday'|date('M j, Y') }}</p>
Это даст следующий результат —
Choose your location before May 15, 2017
Аргумент должен быть в одном из поддерживаемых PHP форматов даты и времени.
Вы можете передать часовой пояс в качестве второго аргумента.
свалка
Функция dump выводит информацию о переменной шаблона. Например,
{{ dump(user) }}
Максимум
Функция max возвращает наибольшее значение последовательности. Например,
{{ max(1, 5, 9, 11, 15) }}
Min
Функция min возвращает наименьшее значение последовательности. Например,
{{ min(1, 3, 2) }}
Включают
Функция include возвращает отображаемое содержимое шаблона. Например,
{{ include('template.html') }}
случайный
Случайная функция генерирует случайное значение. Например,
{{ random([‘Jan’, ‘Feb’, ‘Mar’, ‘Apr’]) }} {# example output: Jan #}
Спектр
Функция Range возвращает список, содержащий арифметическую последовательность целых чисел. Например,
{% for x in range(1, 5) %} {{ x }}, {% endfor %}
Это даст следующий результат —
1,2,3,4,5
Макеты
Макет представляет общие части нескольких представлений, например, заголовок страницы и нижний колонтитул.
Наследование шаблонов
Шаблон может быть использован другим. Мы можем добиться этого, используя концепцию наследования шаблонов. Наследование шаблонов позволяет создавать базовый шаблон «макета», который содержит все общие элементы веб-сайта, определенные как блоки.
Давайте рассмотрим простой пример, чтобы понять больше о наследовании шаблонов.
пример
Рассмотрим базовый шаблон, расположенный в «app / Resources / views / base.html.twig». Добавьте следующие изменения в файл.
base.html.twig
<!DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title>{% block title %}Parent template Layout{% endblock %}</title> </head> </html>
Теперь перейдите к файлу шаблона индекса, расположенному в «app / Resources / views / default / index.html.twig» . Добавьте в него следующие изменения.
index.html.twig
{% extends 'base.html.twig' %} {% block title %}Child template Layout{% endblock %}
Здесь тег {% extends%} информирует шаблонизатор о необходимости сначала оценить базовый шаблон, который устанавливает макет и определяет блок. Затем дочерний шаблон отображается. Дочерний шаблон может расширять базовый макет и перезаписывать блок заголовка. Теперь запросите URL «http: // localhost: 8000», и вы сможете получить его результат.
активы
Актив управляет созданием URL-адресов и управлением версиями веб-ресурсов, таких как таблицы стилей CSS, файлы JavaScript и файлы изображений.
JavaScript
Чтобы включить файлы JavaScript, используйте тег javascripts в любом шаблоне.
{# Include javascript #} {% block javascripts %} {% javascripts '@AppBundle/Resources/public/js/*' %} <script src="{{ asset_url }}"></script> {% endjavascripts %} {% endblock %}
Stylesheets
Чтобы включить файлы стилей, используйте тег стилей в любом шаблоне.
{# include style sheet #} {% block stylesheets %} {% stylesheets 'bundles/app/css/*' filter = 'cssrewrite' %} <link rel = "stylesheet" href="{{ asset_url }}" /> {% endstylesheets %} {% endblock %}
Изображений
Чтобы включить изображение, вы можете использовать тег изображения. Это определяется следующим образом.
{% image '@AppBundle/Resources/public/images/example.jpg' %} <img src = "{{ asset_url }}" alt = "Example" /> {% endimage %}
Сложные активы
Вы можете объединить много файлов в один. Это помогает уменьшить количество HTTP-запросов и повышает производительность внешнего интерфейса.
{% javascripts '@AppBundle/Resources/public/js/*' '@AcmeBarBundle/Resources/public/js/form.js' '@AcmeBarBundle/Resources/public/js/calendar.js' %} <script src = "{{ asset_url }}"></script> {% endjavascripts %}
Symfony — Учение ОРМ
В веб-фреймворке Symfony модель играет важную роль. Они являются субъектами предпринимательской деятельности. Они либо предоставляются клиентами, либо извлекаются из внутренней базы данных, обрабатываются в соответствии с бизнес-правилами и сохраняются обратно в базу данных. Это данные, представленные представлениями. Давайте узнаем о моделях и как они взаимодействуют с серверной системой в этой главе.
Модель базы данных
Нам необходимо сопоставить наши модели с внутренними элементами реляционной базы данных, чтобы безопасно и эффективно извлекать и сохранять модели. Это отображение может быть сделано с помощью инструмента Object Relational Mapping (ORM). Symfony предоставляет отдельный пакет DoctrineBundle , который интегрирует Symfony с сторонним инструментом ORM базы данных PHP, Doctrine .
Учение ОРМ
По умолчанию платформа Symfony не предоставляет никаких компонентов для работы с базами данных. Но он тесно интегрируется с доктриной ORM . Doctrine содержит несколько библиотек PHP, используемых для хранения базы данных и отображения объектов.
Следующий пример поможет вам понять, как работает Doctrine, как настроить базу данных и как сохранить и извлечь данные.
Пример доктрины ORM
В этом примере мы сначала настроим базу данных и создадим объект Student, а затем выполним в нем некоторые операции.
Для этого нам необходимо придерживаться следующих шагов.
Шаг 1. Создайте приложение Symfony
Создайте приложение Symfony, dbsample, используя следующую команду.
Symfony новый образец
Шаг 2. Настройка базы данных
Обычно информация о базе данных настраивается в файле «app / config / parameters.yml».
Откройте файл и добавьте следующие изменения.
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
Теперь Doctrine ORM может подключаться к базе данных.
Шаг 3: Создать базу данных
Выполните следующую команду для создания базы данных «studentdb». Этот шаг используется для привязки базы данных в Doctrine ORM.
php bin/console doctrine:database:create
После выполнения команды она автоматически генерирует пустую базу данных «studentdb». Вы можете увидеть следующий ответ на вашем экране.
Created database `studentsdb` for connection named default
Шаг 4: Информация о карте
Информация о сопоставлении — это не что иное, как «метаданные». Это набор правил, которые информируют Doctrine ORM о том, как класс Student и его свойства отображаются в конкретную таблицу базы данных.
Ну, эти метаданные могут быть указаны в нескольких различных форматах, включая YAML, XML или вы можете напрямую передать класс 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; }
Здесь имя таблицы необязательно. Если имя таблицы не указано, оно будет определено автоматически на основе имени класса сущности.
Шаг 5: Привязать сущность
Доктрина создает простые классы сущностей для вас. Это поможет вам построить любую сущность.
Выполните следующую команду для создания объекта.
php bin/console doctrine:generate:entities AppBundle/Entity/Student
Тогда вы увидите следующий результат, и сущность будет обновлена.
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; } }
Шаг 6: Проверка карты
После создания сущностей вы должны проверить сопоставления с помощью следующей команды.
php bin/console doctrine:schema:validate
Это даст следующий результат —
[Mapping] OK - The mapping files are correct. [Database] FAIL - The database schema is not in sync with the current mapping file
Поскольку мы не создали таблицу студентов, сущность не синхронизирована. Давайте создадим таблицу студентов с помощью команды Symfony на следующем шаге.
Шаг 7: Создать схему
Doctrine может автоматически создавать все таблицы базы данных, необходимые для сущности Student. Это можно сделать с помощью следующей команды.
php bin/console doctrine:schema:update --force
После выполнения команды вы можете увидеть следующий ответ.
Updating database schema... Database schema updated successfully! "1" query was executed
Эта команда сравнивает, как должна выглядеть ваша база данных, с тем, как она на самом деле выглядит, и выполняет операторы SQL, необходимые для обновления схемы базы данных до того места, где она должна быть.
Теперь снова проверьте схему, используя следующую команду.
php bin/console doctrine:schema:validate
Это даст следующий результат —
[Mapping] OK - The mapping files are correct. [Database] OK - The database schema is in sync with the mapping files
Шаг 8: Получатель и установщик
Как видно из раздела «Привязать объект», следующая команда создает все методы получения и установки для класса Student.
$ php bin/console doctrine:generate:entities AppBundle/Entity/Student
Шаг 9. Сохранение объектов в базе данных.
Теперь мы сопоставили сущность Student с соответствующей таблицей Student. Теперь мы должны иметь возможность сохранять объекты Student в базе данных. Добавьте следующий метод к StudentController пакета.
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()); } }
Здесь мы получили доступ к менеджеру доктрин с помощью метода getManager () через getDoctrine () базового контроллера, а затем сохранили текущий объект с помощью метода persist () менеджера доктрин. Метод persist () добавляет команду в очередь, но метод flush () выполняет реальную работу (сохраняя объект студента).
Шаг 10: выбор объектов из базы данных
Создайте функцию в StudentController, которая будет отображать сведения об ученике.
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)); }
Шаг 11: создайте представление
Давайте создадим представление, которое указывает на действие отображения. Перейдите в каталог представлений и создайте файл «display.html.twig». Добавьте следующие изменения в файл.
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>
Вы можете получить результат, запросив URL «http: // localhost: 8000 / student / display» в браузере.
Он выдаст следующий вывод на экран —
Шаг 12: обнови объект
Чтобы обновить объект в StudentController, создайте действие и добавьте следующие изменения.
/** * @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!'); }
Теперь запросите URL «http: // localhost: 8000 / Student / update / 1», и он даст следующий результат.
Он выдаст следующий вывод на экран —
Шаг 13: Удалить объект
Удаление объекта аналогично и требует вызова метода remove () менеджера сущностей (доктрины).
Это можно сделать с помощью следующей команды.
/** * @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 — Формы
Symfony предоставляет различные встроенные теги для простой и безопасной обработки HTML-форм. Компонент Symfony Form выполняет процесс создания и проверки формы. Он соединяет модель и видовой слой. Он предоставляет набор элементов формы для создания полноценной HTML-формы из предопределенных моделей. Эта глава подробно объясняет формы.
Поля формы
API Symfony Framework поддерживает большую группу типов полей. Давайте подробно рассмотрим каждый из типов полей.
FormType
Он используется для генерации формы в рамках Symfony. Его синтаксис выглядит следующим образом —
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);
Здесь $ studentinfo является сущностью типа Student. createFormBuilder используется для создания формы HTML. Метод add используется для добавления элементов ввода внутри формы. название относится к собственности студента титул. TextType :: class ссылается на текстовое поле html. Symfony предоставляет классы для всех HTML-элементов.
TextType
Поле TextType представляет собой самое основное поле ввода текста. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\TextType; $builder->add(‘name’, TextType::class);
Здесь имя сопоставлено с сущностью.
TextareaType
Визуализирует HTML-элемент textarea. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\TextareaType; $builder->add('body', TextareaType::class, array( 'attr' => array('class' => 'tinymce'), ));
EmailType
Поле EmailType — это текстовое поле, отображаемое с использованием тега электронной почты HTML5. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\EmailType; $builder->add('token', EmailType::class, array( 'data' => 'abcdef', ));
PasswordType
Поле PasswordType отображает текстовое поле ввода пароля. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\PasswordType; $bulder->add('password', PasswordType::class);
RangeType
Поле RangeType — это слайдер, который отображается с использованием тега диапазона HTML5. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\RangeType; // ... $builder->add('name', RangeType::class, array( 'attr' => array( 'min' => 100, 'max' => 200 ) ));
PercentType
PercentType отображает текстовое поле ввода и специализируется на обработке процентных данных. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\PercentType; // ... $builder->add('token', PercentType::class, array( 'data' => 'abcdef', ));
DateType
Визуализирует формат даты. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\DateType; // ... $builder->add(‘joined’, DateType::class, array( 'widget' => 'choice', ));
Здесь Widget — это основной способ визуализации поля.
Он выполняет следующую функцию.
-
Выбор — представляет три выбранных входа. Порядок выбора определяется в опции формата.
-
text — отображает три поля ввода типа text (месяц, день, год).
-
single_text — визуализирует один тип ввода даты. Ввод пользователя проверяется на основе параметра формата.
Выбор — представляет три выбранных входа. Порядок выбора определяется в опции формата.
text — отображает три поля ввода типа text (месяц, день, год).
single_text — визуализирует один тип ввода даты. Ввод пользователя проверяется на основе параметра формата.
CheckboxType
Создает один флажок ввода. Это всегда следует использовать для поля, имеющего логическое значение. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\CheckboxType; // ... $builder-<add(‘sports’, CheckboxType::class, array( 'label' =< ‘Are you interested in sports?’, 'required' =< false, ));
RadioType
Создает одну радиокнопку. Если выбран переключатель, поле будет установлено на указанное значение. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\RadioType; // ... $builder->add('token', RadioType::class, array( 'data' => 'abcdef', ));
Обратите внимание, что переключатели не могут быть отключены, значение изменяется только тогда, когда установлен другой переключатель с тем же именем.
RepeatedType
Это специальное поле «группа», которое создает два одинаковых поля, значения которых должны совпадать. Его синтаксис выглядит следующим образом —
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'), ));
В основном это используется для проверки пароля пользователя или электронной почты.
ButtonType
Простая нажимаемая кнопка. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\ButtonType; // ... $builder->add('save', ButtonType::class, array( 'attr' => array('class' => 'save'), ));
ResetType
Кнопка, которая сбрасывает все поля к своим начальным значениям. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\ResetType; // ... $builder->add('save', ResetType::class, array( 'attr' => array('class' => 'save'), ));
ChoiceType
Многоцелевое поле используется, чтобы позволить пользователю «выбрать» один или несколько параметров. Он может отображаться как тег выбора, переключатели или флажки. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\ChoiceType; // ... $builder->add(‘gender’, ChoiceType::class, array( 'choices' => array( ‘Male’ => true, ‘Female’ => false, ), ));
SubmitType
Кнопка отправки используется для отправки данных формы. Его синтаксис выглядит следующим образом —
use Symfony\Component\Form\Extension\Core\Type\SubmitType; // ... $builder->add('save', SubmitType::class, array( 'attr' => array('class' => 'save'), ))
Форма Помощник Функция
Вспомогательные функции формы — это функции веток, которые используются для простого создания форм в шаблонах.
form_start
Возвращает тег формы HTML, который указывает на допустимое действие, маршрут или URL. Его синтаксис выглядит следующим образом —
{{ form_start(form, {'attr': {'id': 'form_person_edit'}}) }}
form_end
Закрывает тег формы HTML, созданный с помощью form_start. Его синтаксис выглядит следующим образом —
{{ form_end(form) }}
TextArea
Возвращает тег textarea, опционально обернутый встроенным редактором JavaScript с расширенным набором текста.
флажок
Возвращает XHTML-совместимый тег ввода с type = «checkbox». Его синтаксис выглядит следующим образом —
echo checkbox_tag('choice[]', 1); echo checkbox_tag('choice[]', 2); echo checkbox_tag('choice[]', 3); echo checkbox_tag('choice[]', 4);
input_password_tag
Возвращает XHTML-совместимый тег ввода с type = «password». Его синтаксис выглядит следующим образом —
echo input_password_tag('password'); echo input_password_tag('password_confirm');
input_tag
Возвращает XHTML-совместимый входной тег с type = «text». Его синтаксис выглядит следующим образом —
echo input_tag('name');
этикетка
Возвращает тег метки с указанным параметром.
переключатель
Возвращает XHTML-совместимый тег ввода с type = «radio». Его синтаксис выглядит следующим образом —
echo ' Yes '.radiobutton_tag(‘true’, 1); echo ' No '.radiobutton_tag(‘false’, 0);
reset_tag
Возвращает XHTML-совместимый входной тег с type = «reset». Его синтаксис выглядит следующим образом —
echo reset_tag('Start Over');
Выбрать
Возвращает тег выбора, заполненный всеми странами мира. Его синтаксис выглядит следующим образом —
echo select_tag( 'url', options_for_select($url_list), array('onChange' => 'Javascript:this.form.submit();'));
Отправить
Возвращает XHTML-совместимый тег ввода с type = «submit». Его синтаксис выглядит следующим образом —
echo submit_tag('Update Record');
В следующем разделе мы узнаем, как создать форму, используя поля формы.
Студенческая анкета
Давайте создадим простую форму сведений об ученике, используя поля формы Symfony. Для этого мы должны придерживаться следующих шагов —
Шаг 1. Создайте приложение Symfony
Создайте приложение Symfony, formample , используя следующую команду.
symfony new formsample
Объекты обычно создаются в каталоге «src / AppBundle / Entity /».
Шаг 2: Создать сущность
Создайте файл «StudentForm.php» в каталоге «src / AppBundle / Entity /». Добавьте следующие изменения в файл.
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; } }
Шаг 3: Добавьте StudentController
Перейдите в каталог «src / AppBundle / Controller», создайте файл «StudentController.php» и добавьте в него следующий код.
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(), )); } }
Шаг 4: визуализация представления
Перейдите в каталог «app / Resources / views / student /», создайте файл «new.html.twig» и добавьте в него следующие изменения.
{% 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 %}
Теперь запросите URL «http: // localhost: 8000 / student / new», и он выдаст следующий результат.
Результат
Symfony — валидация
Валидация является наиболее важным аспектом при разработке приложения. Он проверяет поступающие данные. В этой главе подробно описывается проверка формы.
Ограничения валидации
Валидатор предназначен для проверки объектов на соответствие ограничениям. Если вы проверяете объект, просто сопоставьте одно или несколько ограничений его классу, а затем передайте его в службу проверки. По умолчанию при проверке объекта будут проверяться все ограничения соответствующего класса, чтобы увидеть, действительно ли они проходят. Symfony поддерживает следующие известные ограничения проверки.
NotBlank
Проверяет, что свойство не пустое. Его синтаксис выглядит следующим образом —
namespace AppBundle\Entity; use Symfony\Component\Validator\Constraints as Assert; class Student { /** * @Assert\NotBlank() */ protected $studentName; }
Это ограничение NotBlank гарантирует, что свойство studentName не должно быть пустым.
Ненулевой
Проверяет, что значение не строго равно нулю. Его синтаксис выглядит следующим образом —
namespace AppBundle\Entity; use Symfony\Component\Validator\Constraints as Assert; class Student { /** * @Assert\NotNull() */ protected $studentName; }
Эл. адрес
Проверяет, что значение является действительным адресом электронной почты. Его синтаксис выглядит следующим образом —
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; }
Нулевой
Проверяет, что значение точно равно нулю. Его синтаксис выглядит следующим образом —
namespace AppBundle\Entity; use Symfony\Component\Validator\Constraints as Assert; class Student { /** * @Assert\IsNull() */ protected $studentName; }
длина
Проверяет, что заданная длина строки находится между некоторым минимальным и максимальным значением. Его синтаксис выглядит следующим образом —
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; }
Спектр
Проверяет, что данное число находится между некоторым минимальным и максимальным числом. Его синтаксис выглядит следующим образом —
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; }
Дата
Проверяет, что значение является действительной датой. Это соответствует действительному формату ГГГГ-ММ-ДД. Его синтаксис выглядит следующим образом —
namespace AppBundle\Entity; use Symfony\Component\Validator\Constraints as Assert; class Student { /** * @Assert\Date() */ protected $joinedAt; }
Выбор
Это ограничение используется для гарантии того, что данное значение является одним из заданного набора допустимых вариантов. Он также может использоваться для проверки того, что каждый элемент в массиве элементов является одним из этих допустимых вариантов. Его синтаксис выглядит следующим образом —
namespace AppBundle\Entity; use Symfony\Component\Validator\Constraints as Assert; class Student { /** * @Assert\Choice(choices = {"male", "female"}, message = "Choose a valid gender.") */ protected $gender; }
Пользовательский пароль
Это подтверждает, что входное значение равно паролю текущего аутентифицированного пользователя. Это полезно в форме, где пользователи могут изменить свой пароль, но для безопасности необходимо ввести свой старый пароль. Его синтаксис выглядит следующим образом —
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; }
Это ограничение подтверждает, что старый пароль соответствует текущему паролю пользователя.
Пример валидации
Давайте напишем простой пример приложения, чтобы понять концепцию валидации.
Шаг 1 — Создайте приложение для проверки.
Создайте приложение Symfony, пример проверки , используя следующую команду.
symfony new validationsample
Шаг 2 — Создайте сущность с именем FormValidation в файле «FormValidation.php» в каталоге «src / AppBundle / Entity /» . Добавьте следующие изменения в файл.
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; } }
Шаг 3 — Создайте метод validateAction в StudentController. Перейдите в каталог «src / AppBundle / Controller» , создайте файл «studentController.php» и добавьте в него следующий код.
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(), )); }
Здесь мы создали форму с использованием классов Form, а затем обработали форму. Если форма отправлена и является действительной, отображается сообщение с подтвержденной формой. В противном случае отображается форма по умолчанию.
Шаг 4 — Создайте представление для созданного выше действия в StudentController. Перейдите в каталог «app / Resources / views / student /» . Создайте файл «validate.html.twig» и добавьте в него следующий код.
{% 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 %}
Здесь мы использовали теги формы для создания формы.
Шаг 5 — Наконец, запустите приложение, http: // localhost: 8000 / student / validate .
Результат: Начальная страница
Результат: финальная страница
Symfony — загрузка файлов
Компонент Symfony Form предоставляет класс FileType для обработки элемента ввода файла. Он позволяет легко загружать изображения, документы и т. Д. Давайте узнаем, как создать простое приложение с помощью функции FileType.
Шаг 1 — Создайте новое приложение fileuploadsample с помощью следующей команды.
symfony new fileuploadsample
Шаг 2 — Создайте сущность « Студент» с именем, возрастом и фотографией, как показано в следующем коде.
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; } }
Здесь мы указали файл для свойства фото.
Шаг 3 — Создайте контроллер ученика, StudentController и новый метод addAction, как показано в следующем коде.
<?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(), )); } } }
Здесь мы создали форму для студента и обработали запрос. Когда форма отправлена пользователем и она действительна, мы переместили загруженный файл в каталог загрузки с помощью параметра photos_directory .
Шаг 4 — Создайте представление new.html.twig , используя следующие теги формы.
{% 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 %}
Шаг 5 — Установите параметр photos_directory в файле конфигурации параметров следующим образом.
приложение / Config / config.xml
parameters: photos_directory: '%kernel.root_dir%/../web/uploads/photos'
Шаг 6 — Теперь запустите приложение, откройте http: // localhost: 8000 / student / new и загрузите фотографию. Загруженная фотография будет загружена в каталог photos_, и будет показано успешное сообщение.
Результат: Начальная страница
Результат: Страница загрузки файла
Symfony — Ajax Control
AJAX — это современная технология в веб-программировании. Он предоставляет опции для отправки и получения данных на веб-странице асинхронно, без обновления страницы. Давайте изучим программирование Symfony AJAX в этой главе.
Платформа Symfony предоставляет опции для идентификации того, является ли тип запроса AJAX или нет. Класс запроса компонента Symfony HttpFoundation имеет метод isXmlHttpRequest () для этой цели. Если сделан запрос AJAX, метод isXmlHttpRequest () объекта текущего запроса возвращает true, в противном случае — false.
Этот метод используется для правильной обработки AJAX-запроса на стороне сервера.
if ($request->isXmlHttpRequest()) { // Ajax request } else { // Normal request }
Symfony также предоставляет основанный на JSON класс Response JsonResponse для создания ответа в формате JSON. Мы можем объединить эти два метода, чтобы создать простое и понятное веб-приложение на основе AJAX.
AJAX — рабочий пример
Давайте добавим новую страницу student / ajax в приложение для студентов и попытаемся получить информацию о студентах асинхронно.
Шаг 1 — Добавьте метод ajaxAction в 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'); } }
Здесь, если запрос AJAX, мы выбираем информацию об ученике, кодируем ее как JSON и возвращаем ее, используя объект JsonResponse . В противном случае мы просто визуализируем соответствующий вид.
Шаг 2 — Создайте файл представления ajax.html.twig в каталоге представлений учеников, app / Resources / views / student / и добавьте следующий код.
{% 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 %}
Здесь мы создали тег привязки (id: loadstudent) для загрузки информации об ученике с помощью вызова AJAX. Вызов AJAX выполняется с использованием JQuery. Событие, прикрепленное к тегу loadstudent, активируется, когда пользователь щелкает по нему. Затем он извлекает информацию об ученике с помощью вызова AJAX и динамически генерирует необходимый HTML-код.
Шаг 3. Наконец, запустите приложение, http: // localhost: 8000 / student / ajax и щелкните вкладку «Загрузить информацию о студенте».
Результат: Начальная страница
Результат: страница с информацией о студентах
Symfony — Cookies и управление сессиями
Компонент Symfony HttpFoundation обеспечивает управление файлами cookie и сеансами объектно-ориентированным способом. Cookie обеспечивает хранение данных на стороне клиента и поддерживает только небольшой объем данных. Обычно это 2 КБ на домен, и это зависит от браузера. Сеанс обеспечивает хранение данных на стороне сервера и поддерживает большое количество данных. Давайте посмотрим, как создать cookie и сеанс в веб-приложении Symfony.
печенье
Symfony предоставляет класс Cookie для создания элемента cookie. Давайте создадим цвет cookie, срок действия которого истекает через 24 часа со значением blue . Параметр конструктора класса cookie выглядит следующим образом.
- имя (тип: строка) — имя файла cookie
- значение (тип: строка) — значение cookie
- expire (тип: целое число / строка / дата / время) — информация об истечении срока действия
- путь (тип: строка) — путь к серверу, на котором доступен файл cookie
- домен (тип: строка) — адрес домена, в котором доступен файл cookie
- secure (type: boolean) — нужно ли передавать cookie в HTTPS-соединении
- httpOnly (тип: логическое значение) — доступен ли файл cookie только по протоколу HTTP
use Symfony\Component\HttpFoundation\Cookie; $cookie = new Cookie('color', 'green', strtotime('tomorrow'), '/', 'somedomain.com', true, true);
Symfony также предоставляет следующую возможность создания файлов cookie на основе строк.
$cookie = Cookie::fromString('color = green; expires = Web, 4-May-2017 18:00:00 +0100; path=/; domain = somedomain.com; secure; httponly');
Теперь созданный файл cookie необходимо прикрепить к заголовку объекта ответа http следующим образом.
$response->headers->setCookie($cookie);
Чтобы получить cookie, мы можем использовать объект запроса следующим образом.
$cookie = $request->cookie->get('color');
Здесь request-> cookie имеет тип PropertyBag, и мы можем манипулировать им, используя методы PropertyBag.
сессия
Symfony предоставляет класс Session, реализующий интерфейс SessionInterface. Важный сеанс API заключается в следующем,
start — запускает сеанс
Session $session = new Session(); $session->start();
invalidate — очищает все данные сеанса и восстанавливает идентификатор сеанса.
set — сохраняет данные в сеансе с помощью ключа.
$session->set('key', 'value');
Мы можем использовать любые данные в значении сеанса, быть простым целым числом для сложных объектов.
get — получает данные из сеанса, используя ключ.
$val = $session->get('key');
удалить — удаляет ключ из сеанса.
clear — удаляет данные сеанса
FlashBag
Сессия предоставляет еще одну полезную функцию под названием FlashBag . Это специальный контейнер внутри сессии, содержащий данные только во время перенаправления страницы. Это полезно в http перенаправлениях. Перед перенаправлением на страницу данные могут быть сохранены во FlashBag вместо обычного контейнера сеанса, и сохраненные данные будут доступны в следующем запросе (перенаправленная страница). Затем данные будут автоматически признаны недействительными.
$session->getFlashBag()->add('key', 'value'); $session->getFlashBag()->get('key');
Symfony — Интернационализация
Интернационализация (i18n) и локализация (l10n) помогают расширить охват клиентов веб-приложением. Symfony предоставляет отличный компонент перевода для этой цели. Давайте узнаем, как использовать компонент перевода в этой главе.
Включить перевод
По умолчанию веб-инфраструктура Symfony отключает компонент «Перевод». Чтобы включить его, добавьте раздел переводчика в файл конфигурации, app / config / config.yml.
framework: translator: { fallbacks: [en] }
Файл перевода
Компонент перевода переводит текст с использованием файла ресурса перевода. Файл ресурса может быть написан на PHP, XML и YAML. Расположение файла ресурсов по умолчанию — app / Resources / translations . Для каждого языка требуется один файл ресурсов. Давайте напишем файл ресурса messages.fr.yml для французского языка.
I love Symfony: J'aime Symfony I love %name%: J'aime %name%
Текст с левой стороны написан на английском, а с правой стороны — на французском. Вторая строка показывает использование заполнителя. Информация заполнителя может быть добавлена динамически при использовании перевода.
использование
По умолчанию языковой стандарт системы пользователя по умолчанию устанавливается веб-инфраструктурой Symfony. Если языковой стандарт по умолчанию не настроен в веб-приложении, он переключится на английский. Локаль также может быть указана в URL веб-страницы.
http://www.somedomain.com/en/index http://www.somedomain.com/fr/index
Давайте используем наш язык на основе URL в нашем примере, чтобы легко понять концепцию перевода. Создайте новую функцию translationSample с маршрутом / {_ locale} / translation / sample в DefaultController (src / AppBundle / Controller / DefaultController.php). {_locale} — это специальное ключевое слово в Symfony для указания локали по умолчанию.
/** * @Route("/{_locale}/translation/sample", name="translation_sample") */ public function translationSample() { $translated = $this->get('translator')->trans('I love Symfony'); return new Response($translated); }
Здесь мы использовали метод перевода trans , который переводит содержимое в текущую локаль. В этом случае текущая локаль является первой частью URL. Теперь запустите приложение и загрузите страницу, http: // localhost: 8000 / en / translation / sample, в браузере.
Результатом будет «Я люблю Symfony» на английском языке. Теперь загрузите страницу http: // localhost: 8000 / fr / translation / sample в браузере. Теперь текст будет переведен на французский язык следующим образом.
Аналогично, шаблон ветки имеет блок {% trans%}, чтобы включить функцию перевода в представлениях. Чтобы проверить это, добавьте новую функцию translationTwigSample и соответствующее представление в 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'); }
Посмотреть
{% extends 'base.html.twig' %} {% block body %} {% trans with {'%name%': 'Symfony'} from "app" into "fr" %}I love %name% {% endtrans %} {% endblock %}
Здесь блок trans также указывает местозаполнитель. Результат страницы следующий.
Symfony — ведение журнала
Ведение журнала очень важно для веб-приложения. Веб-приложения используются сотнями и тысячами пользователей одновременно. Чтобы получить предварительный просмотр событий вокруг веб-приложения, должна быть включена регистрация. Без входа в систему разработчик не сможет найти статус приложения. Давайте предположим, что конечный клиент сообщает о проблеме или владелец стека проектов сообщает о проблеме производительности, а затем первым инструментом для разработчика является регистрация. Проверяя данные журнала, можно получить представление о возможной причине проблемы.
Symfony обеспечивает отличную функцию ведения журнала, интегрируя среду ведения журнала Monolog. Monolog является стандартом де-факто для регистрации в среде PHP. Ведение журнала включено в каждом веб-приложении Symfony и предоставляется в качестве службы. Просто получите объект регистратора, используя базовый контроллер следующим образом.
$logger = $this->get('logger');
После того, как объект logger выбран, мы можем записывать информацию, предупреждения и ошибки, используя его.
$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!');
Файл конфигурации веб-приложения Symfony app / config / config.yml содержит отдельный раздел для каркаса логгера. Он может быть использован для обновления работы каркаса логгера.
Symfony — Управление электронной почтой
Функциональность электронной почты является наиболее востребованной функцией в веб-среде. Даже простое приложение будет иметь контактную форму, а детали будут отправлены системной администрации по электронной почте. Symfony интегрирует SwiftMailer , лучший модуль электронной почты PHP, доступный на рынке. SwiftMailer — это отличная библиотека электронной почты, позволяющая отправлять электронную почту с использованием старой школы sendmail в новейшее облачное почтовое приложение.
Давайте разберемся с концепцией рассылки в Symfony, отправив простое электронное письмо. Перед написанием функциональности почтовой программы, настройте детали конфигурации почтовой программы в app / config / parameters.yml . Затем создайте новую функцию MailerSample в DefaultController и добавьте следующий код.
/** * @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"); }
Здесь мы просто создали сообщение, используя компонент SwiftMailer, и визуализировали тело сообщения, используя шаблон Twig . Затем мы получили компонент mailer из метода get контроллера с ключом ‘mailer’. Наконец, мы отправили сообщение, используя метод отправки, и распечатали сообщение отправки почты .
Теперь запустите страницу http: // localhost: 8000 / mailsample / send, и результат будет следующим.
Symfony — модульное тестирование
Модульное тестирование необходимо для постоянного развития в крупных проектах. Модульные тесты автоматически протестируют компоненты вашего приложения и сообщат вам, когда что-то не работает. Модульное тестирование может быть выполнено вручную, но часто автоматизировано.
PHPUnit
Платформа Symfony интегрируется с платформой модульного тестирования PHPUnit. Чтобы написать модульный тест для платформы Symfony, нам нужно настроить PHPUnit. Если PHPUnit не установлен, скачайте и установите его. Если он установлен правильно, то вы увидите следующий ответ.
phpunit PHPUnit 5.1.3 by Sebastian Bergmann and contributors
Модульный тест
Модульный тест — это тест против одного класса PHP, также называемого модулем.
Создайте класс Student в каталоге Libs / AppBundle. Он находится по адресу «src / AppBundle / Libs / Student.php» .
Student.php
namespace AppBundle\Libs; class Student { public function show($name) { return $name. “ , Student name is tested!”; } }
Теперь создайте файл StudentTest в каталоге «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); } }
Запустить тест
Чтобы запустить тест в каталоге, используйте следующую команду.
$ phpunit
После выполнения вышеуказанной команды вы увидите следующий ответ.
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.
Теперь запустите тесты в каталоге Libs следующим образом.
$ phpunit tests/AppBundle/Libs
Результат
Time: 26 ms, Memory: 4.00Mb OK (1 test, 1 assertion)
Symfony — Продвинутые понятия
В этой главе мы узнаем о некоторых продвинутых концепциях в среде Symfony.
HTTP-кэш
Кэширование в веб-приложении повышает производительность. Например, горячие продукты в веб-приложении корзины покупок могут быть кэшированы в течение ограниченного времени, так что они могут быть представлены покупателю быстро, без попадания в базу данных. Ниже приведены некоторые основные компоненты кэша.
Cache Item
Элемент кэша — это единица информации, хранящаяся в виде пары ключ / значение. Ключ должен быть строкой, а значением может быть любой объект PHP. Объекты PHP хранятся в виде строки путем сериализации и преобразуются обратно в объекты при чтении элементов.
Кэш-адаптер
Адаптер кеша — это реальный механизм для хранения товара в магазине. Хранилище может быть памятью, файловой системой, базой данных, Redis и т. Д. Компонент Cache предоставляет интерфейс AdapterInterface, через который адаптер может хранить элемент кэша в внутреннем хранилище. Есть много встроенных адаптеров кеша. Немногие из них следующие:
-
Адаптер Array Cache — элементы кэша хранятся в массиве PHP.
-
Адаптер кеша файловой системы — элементы кеша хранятся в файлах.
-
Адаптер кэша файлов PHP — элементы кэша хранятся в виде файлов php.
-
APCu Cache Adapter — элементы кэша хранятся в общей памяти с использованием расширения PHP APCu.
-
Redis Cache Adapter — элементы кэша хранятся на сервере Redis.
-
PDO и Doctrine DBAL Cache Adapter — элементы кэша хранятся в базе данных.
-
Цепной адаптер кэша — объединяет несколько адаптеров кэша для целей репликации.
-
Proxy Cache Adapter — элементы кэша хранятся с использованием стороннего адаптера, который реализует CacheItemPoolInterface.
Адаптер Array Cache — элементы кэша хранятся в массиве PHP.
Адаптер кеша файловой системы — элементы кеша хранятся в файлах.
Адаптер кэша файлов PHP — элементы кэша хранятся в виде файлов php.
APCu Cache Adapter — элементы кэша хранятся в общей памяти с использованием расширения PHP APCu.
Redis Cache Adapter — элементы кэша хранятся на сервере Redis.
PDO и Doctrine DBAL Cache Adapter — элементы кэша хранятся в базе данных.
Цепной адаптер кэша — объединяет несколько адаптеров кэша для целей репликации.
Proxy Cache Adapter — элементы кэша хранятся с использованием стороннего адаптера, который реализует CacheItemPoolInterface.
Кеш-пул
Cache Pool — логическое хранилище элементов кеша. Пулы кеша реализуются адаптерами кеша.
Простое приложение
Давайте создадим простое приложение, чтобы понять концепцию кеша.
Шаг 1 — Создайте новое приложение, пример кеша .
cd /path/to/app mkdir cache-example cd cache-example
Шаг 2 — Установите компонент кеша.
composer require symfony/cache
Шаг 3 — Создайте адаптер файловой системы.
require __DIR__ . '/vendor/autoload.php'; use Symfony\Component\Cache\Adapter\FilesystemAdapter; $cache = new FilesystemAdapter();
Шаг 4 — Создайте элемент кэша, используя getItem и установите метод адаптера. getItem извлекает элемент кэша, используя его ключ. если ключ не присутствует, он создает новый элемент. Метод set хранит фактические данные.
$usercache = $cache->getitem('item.users'); $usercache->set(['jon', 'peter']); $cache->save($usercache);
Шаг 5 — Получите доступ к элементу кэша, используя getItem, isHit и метод get . isHit информирует о доступности элемента кэша, а метод get предоставляет фактические данные.
$userCache = $cache->getItem('item.users'); if(!$userCache->isHit()) { echo "item.users is not available"; } else { $users = $userCache->get(); var_dump($users); }
Шаг 6 — Удалить элемент кэша, используя метод deleteItem .
$cache->deleteItem('item.users');
Полный список кодов выглядит следующим образом.
<?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'); ?>
Результат
array(2) { [0]=> string(3) "jon" [1]=> string(5) "peter" }
отлаживать
Отладка является одним из наиболее частых действий при разработке приложения. Symfony предоставляет отдельный компонент для облегчения процесса отладки. Мы можем включить средства отладки Symfony, просто вызвав метод enable класса Debug.
use Symfony\Component\Debug\Debug Debug::enable()
Symfony предоставляет два класса, ErrorHandler и ExceptionHandler для отладки. В то время как ErrorHandler ловит ошибки PHP и преобразует их в исключения, ErrorException или FatalErrorException, ExceptionHandler перехватывает необработанные исключения PHP и преобразует их в полезный ответ PHP. ErrorHandler и ExceptionHandler по умолчанию отключены. Мы можем включить его с помощью метода register.
use Symfony\Component\Debug\ErrorHandler; use Symfony\Component\Debug\ExceptionHandler; ErrorHandler::register(); ExceptionHandler::register();
В веб-приложении Symfony среда отладки предоставляется DebugBundle. Зарегистрируйте пакет в методе registerBundles AppKernel, чтобы включить его.
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) { $bundles[] = new Symfony\Bundle\DebugBundle\DebugBundle(); }
Profiler
Для разработки приложения необходим инструмент профилирования мирового уровня. Инструмент профилирования собирает всю информацию о времени выполнения приложения, такую как время выполнения, время выполнения отдельных модулей, время, затрачиваемое на действия базы данных, использование памяти и т. Д. Веб-приложению требуется гораздо больше информации, например, время запроса, время, необходимое для создания ответа и т. д. в дополнение к вышеуказанным показателям.
Symfony разрешает всю такую информацию в веб-приложении по умолчанию. Symfony предоставляет отдельный пакет для веб-профилирования, который называется WebProfilerBundle . Пакет веб-профилировщика можно включить в веб-приложении, зарегистрировав пакет в методе registerBundles AppKernel.
if (in_array($this->getEnvironment(), ['dev', 'test'], true)) { $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle(); }
Компонент веб-профиля можно настроить в разделе web_profile файла конфигурации приложения , app / config / config.xml.
web_profiler: toolbar: false position: bottom
Приложение Symfony показывает профилированные данные в нижней части страницы в виде отдельного раздела.
Symfony также предоставляет простой способ добавления пользовательских данных о странице в данные профиля, используя интерфейс DataCollectorInterface и шаблон веточки. Короче говоря, Symfony позволяет веб-разработчику создавать приложения мирового уровня, предоставляя отличную среду профилирования с относительной простотой.
Безопасность
Как уже говорилось ранее, Symfony обеспечивает надежную структуру безопасности с помощью своего компонента безопасности. Компонент безопасности разделен на четыре подкомпонента следующим образом.
- symfony / security-core — базовая функциональность безопасности.
- symfony / security-http — встроенная функция безопасности в протоколе HTTP.
- symfony / security-csrf — защита от подделки межсайтовых запросов в веб-приложении.
- symfony / security-acl — расширенная структура безопасности на основе списка контроля доступа.
Простая аутентификация и авторизация
Давайте изучим концепцию аутентификации и авторизации с помощью простого демонстрационного приложения.
Шаг 1. Создайте новую демонстрацию безопасности веб-приложения с помощью следующей команды.
symfony new securitydemo
Шаг 2 — Включите функцию безопасности в приложении, используя файл конфигурации безопасности. Конфигурация, связанная с безопасностью, находится в отдельном файле security.yml . Конфигурация по умолчанию следующая.
security: providers: in_memory: memory: ~ firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: ~ #http_basic: ~ #form_login: ~
Конфигурация по умолчанию обеспечивает основанный на памяти провайдер безопасности и анонимный доступ ко всем страницам. Раздел брандмауэра исключает файлы, соответствующие шаблону, ^ / (_ (profiler | wdt) | css | images | js) / из структуры безопасности. Шаблон по умолчанию включает таблицы стилей, изображения и скрипты Java (а также инструменты разработки, такие как профилировщик).
Шаг 3 — Включите проверку подлинности системы на основе HTTP, добавив параметр http_basic в основной раздел следующим образом.
security: # ... firewalls: # ... main: anonymous: ~ http_basic: ~ #form_login: ~
Шаг 4 — Добавьте некоторых пользователей в раздел провайдера памяти. Также добавьте роли для пользователей.
security: providers: in_memory: memory: users: myuser: password: user roles: 'ROLE_USER' myadmin: password: admin roles: 'ROLE_ADMIN'
Мы добавили двух пользователей: пользователя в роли ROLE_USER и администратора в роли ROLE_ADMIN.
Шаг 5 — Добавьте кодировщик, чтобы получить полную информацию о текущем вошедшем в систему пользователе. Целью кодировщика является получение полной информации о текущем пользовательском объекте из веб-запроса.
security: # ... encoders: Symfony\Component\Security\Core\User\User: bcrypt # ...
Symfony предоставляет интерфейс UserInterface для получения таких сведений о пользователе, как имя пользователя, роли, пароль и т. Д. Нам необходимо реализовать интерфейс в соответствии с нашими требованиями и настроить его в разделе кодировщика.
Например, давайте рассмотрим, что пользовательские данные находятся в базе данных. Затем нам нужно создать новый класс User и реализовать методы UserInterface для получения сведений о пользователе из базы данных. Как только данные доступны, система безопасности использует их, чтобы разрешить / запретить пользователю. Symfony предоставляет реализацию User по умолчанию для провайдера памяти. Алгоритм используется для расшифровки пароля пользователя.
Шаг 6 — Зашифруйте пароль пользователя с помощью алгоритма bcrypt и поместите его в файл конфигурации. Поскольку мы использовали алгоритм bcrypt , объект User пытается расшифровать пароль, указанный в файле конфигурации, а затем пытается сопоставить его с паролем, введенным пользователем. Консольное приложение Symfony предоставляет простую команду для шифрования пароля.
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
Шаг 7 — Используйте команду для генерации зашифрованного пароля и обновления его в файле конфигурации.
# 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: ~
Шаг 8 — Теперь примените безопасность к некоторому разделу приложения. Например, ограничьте раздел администратора пользователями в роли ROLE_ADMIN.
security: # ... firewalls: # ... default: # ... access_control: # require ROLE_ADMIN for /admin* - { path: ^/admin, roles: 'ROLE_ADMIN' }
Шаг 9 — Добавьте страницу администратора в DefaultController следующим образом.
/** * @Route("/admin") */ public function adminLandingAction() { return new Response('<html><body>This is admin section.</body></html>'); }
Шаг 10 — Наконец, зайдите на страницу администратора, чтобы проверить настройки безопасности в браузере. Браузер запросит имя пользователя и пароль и разрешит доступ только настроенным пользователям.
Результат
Workflow
Рабочий процесс — это продвинутая концепция, которая используется во многих корпоративных приложениях. В приложении электронной коммерции процесс доставки продукта представляет собой рабочий процесс. Продукт сначала оплачивается (создание заказа), закупается в магазине и упаковывается (упаковка / готова к отправке) и отправляется пользователю. Если есть какие-либо проблемы, продукт возвращается от пользователя, и заказ отменяется. Порядок потока действий очень важен. Например, мы не можем доставить товар без выставления счетов.
Компонент Symfony предоставляет объектно-ориентированный способ определения и управления рабочим процессом. Каждый шаг в процессе называется местом, а действие, необходимое для перемещения из одного места в другое, называется переходом . Коллекция мест и переход к созданию рабочего процесса называется определением рабочего процесса .
Давайте разберемся с концепцией рабочего процесса, создав простое приложение для управления отпусками.
Шаг 1 — Создайте новое приложение, пример рабочего процесса .
cd /path/to/dev mkdir workflow-example cd workflow-example composer require symfony/workflow
Шаг 2 — Создайте новый класс, оставьте атрибуты apply_by, left_on и status .
class Leave { public $applied_by; public $leave_on; public $status; }
Здесь «application_by» относится к сотрудникам, которые хотят уйти. Оставить_он относится к дате отпуска. статус относится к статусу отпуска.
Шаг 3 — Управление отпуском имеет четыре места: применено, in_process и одобрено / отклонено.
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']);
Здесь мы создали новое определение с использованием DefinitionBuilder и добавили места с помощью метода addPlaces .
Шаг 4 — Определите действия, необходимые для перемещения из одного места в другое.
$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'));
Здесь у нас есть три перехода, to_process, одобрить и отклонить . Переход to_process принимает приложение выхода и перемещает место из примененного в in_process. Одобрить переход одобряет заявление на отпуск и перемещает место в утвержденный. Аналогично, отклонение перехода отклоняет заявку на отпуск и перемещает место в отклоненное. Мы создали все переходы, используя метод addTransition.
Шаг 5 — Постройте определение, используя метод сборки.
$definition = $builder->build();
Шаг 6 — Опционально, определение может быть выгружено в виде графического точечного формата, который может быть преобразован в файл изображения для справочных целей.
$dumper = new GraphvizDumper(); echo $dumper->dump($definition);
Шаг 7 — Создайте разметку магазина, в которой будут храниться текущие места / статус объекта.
$marking = new SingleStateMarkingStore('status');
Здесь мы использовали класс SingleStateMarkingStore для создания метки, и он помечает текущий статус в свойстве status объекта. В нашем примере объектом является объект Leave.
Шаг 8 — Создайте рабочий процесс, используя определение и маркировку.
$leaveWorkflow = new Workflow($definition, $marking);
Здесь мы использовали класс Workflow для создания рабочего процесса.
Шаг 9 — Добавьте рабочий процесс в реестр инфраструктуры рабочего процесса, используя класс Registry .
$registry = new Registry(); $registry->add($leaveWorkflow, Leave::class);
Шаг 10 — Наконец, используйте рабочий процесс, чтобы определить, применяется ли данный переход с помощью метода can, и, если это так, примените переход с помощью метода apply. Когда применяется переход, статус объекта перемещается из одного места в другое.
$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";
Полное кодирование выглядит следующим образом:
<?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"; ?>
Результат
Can we approve the leave now? Can we approve the start process now? 1 Can we approve the leave now? 1 in_process approved
Symfony — REST Edition
В любом современном приложении служба REST является одним из основных фундаментальных блоков. Будь то веб-приложение или удобное мобильное приложение, интерфейс обычно представляет собой хорошо разработанный интерфейс для внутренних служб REST. Редакция Symfony REST предоставляет готовый шаблон для запуска нашего веб-приложения на основе REST.
Давайте узнаем, как установить шаблон REST-приложения, используя Symfony REST edition.
Шаг 1 — Загрузите выпуск Symfony REST с помощью следующей команды.
composer create-project gimler/symfony-rest-edition --stability=dev path/to/install
Это загрузит редакцию Symfony REST.
Шаг 2 — Попробуйте настроить его, задав несколько вопросов. На все вопросы выберите ответ по умолчанию, кроме базы данных. Для базы данных выберите pdo_sqlite. Вам может понадобиться включить расширение sqlite в PHP, если оно еще не установлено.
Шаг 3 — Теперь запустите приложение, используя следующую команду.
php app/console server:run
Шаг 4 — Наконец, откройте приложение в браузере, используя http: // localhost: 8000 /.
Это даст следующий результат —
Symfony — издание CMF
Система управления контентом является одним из крупнейших рынков в сценарии веб-приложений. Для системы управления контентом доступно множество платформ, практически на всех языках под солнцем. Большинство фреймворков просты в работе для конечного пользователя, но очень трудны для работы в качестве разработчика и наоборот.
Symfony предоставляет разработчику простой и удобный фреймворк. Он имеет все основные функции, ожидаемые конечным пользователем. Короче говоря, ответственность за обеспечение конечного потребителя лежит на разработчику.
Давайте посмотрим, как установить шаблон приложения CMS с помощью редакции Symfony CMF.
Шаг 1 — Загрузите песочницу Symfony CMF с помощью следующей команды.
composer create-project symfony-cmf/sandbox cmf-sandbox
Это загрузит Symfony CMF.
Шаг 2 — Попробуйте настроить его, задав несколько вопросов. На все вопросы выберите ответ по умолчанию, кроме базы данных. Для базы данных выберите pdo_sqlite. Вам может понадобиться включить расширение sqlite в PHP, если оно еще не установлено.
Шаг 3 — Создайте демонстрационную базу данных с помощью консольного приложения следующим образом.
php app/console doctrine:database:create
Шаг 4 — Загрузите демонстрационные данные в базу данных, используя следующую команду.
php app/console doctrine:phpcr:init:dbal --force php app/console doctrine:phpcr:repository:init php app/console doctrine:phpcr:fixtures:load -n
Шаг 5 — Теперь запустите приложение, используя следующую команду.
php app/console server:run
Шаг 6 — Наконец, откройте приложение в браузере, используя http: // localhost: 8000 /.
Это даст следующий результат —
Symfony — рабочий пример
В этой главе мы узнаем, как создать полное приложение BookStore на основе MVC в Symfony Framework. Ниже приведены шаги.
Шаг 1: Создать проект
Давайте создадим новый проект с именем «BookStore» в Symfony с помощью следующей команды.
symfony new BookStore
Шаг 2: Создать контроллер и маршрут
Создайте BooksController в каталоге «src / AppBundle / Controller». Это определяется следующим образом.
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!'); } }
Теперь мы создали BooksController, затем создадим представление для визуализации действия.
Шаг 3: Создать представление
Давайте создадим новую папку с именем «Книги» в каталоге «app / Resources / views /». Внутри папки создайте файл «author.html.twig» и добавьте следующие изменения.
author.html.twig
<h3> Simple book store application</h3>
Теперь визуализируем представление в классе BooksController. Это определяется следующим образом.
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'); } }
На данный момент мы создали основной BooksController, и результат отображается. Вы можете проверить результат в браузере, используя URL-адрес «http: // localhost: 8000 / books / author».
Шаг 4: Конфигурация базы данных
Настройте базу данных в файле «app / config / parameters.yml».
Откройте файл и добавьте следующие изменения.
parameter.yml
# This file is auto-generated during the composer install parameters: database_driver: pdo_mysql database_host: localhost database_port: 3306 database_name: booksdb database_user: <database_username> database_password: <database_password> mailer_transport: smtp mailer_host: 127.0.0.1 mailer_user: null mailer_password: null secret: 0ad4b6d0676f446900a4cb11d96cf0502029620d doctrine: dbal: driver: pdo_mysql host: '%database_host%' dbname: '%database_name%' user: '%database_user%' password: '%database_password%' charset: utf8mb4
Теперь Doctrine может подключиться к вашей базе данных «booksdb».
Шаг 5: Создайте базу данных
Выполните следующую команду для создания базы данных «booksdb». Этот шаг используется для привязки базы данных в Doctrine.
php bin/console doctrine:database:create
После выполнения команды она автоматически генерирует пустую базу данных «booksdb». Вы можете увидеть следующий ответ на вашем экране.
Это даст следующий результат —
Created database `booksdb` for connection named default
Шаг 6: Отображение информации
Создайте класс сущности Book в каталоге Entity, который находится в «src / AppBundle / Entity».
Вы можете напрямую передать класс Книги, используя аннотации. Это определяется следующим образом.
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; }
Здесь имя таблицы необязательно.
Если имя таблицы не указано, оно будет определено автоматически на основе имени класса сущности.
Шаг 7: Привязать сущность
Доктрина создает простые классы сущностей для вас. Это поможет вам построить любую сущность.
Выполните следующую команду для создания объекта.
php bin/console doctrine:generate:entities AppBundle/Entity/Book
Тогда вы увидите следующий результат, и сущность будет обновлена.
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; } }
Шаг 8: Проверка соответствия
После создания сущностей вы должны проверить сопоставления с помощью следующей команды.
php bin/console doctrine:schema:validate
Это даст следующий результат —
[Mapping] OK - The mapping files are correct [Database] FAIL - The database schema is not in sync with the current mapping file.
Поскольку мы не создали таблицу Books, сущность не синхронизирована. Давайте создадим таблицу Books с помощью команды Symfony на следующем шаге.
Шаг 9: Создание схемы
Doctrine может автоматически создавать все таблицы базы данных, необходимые для сущности Book. Это можно сделать с помощью следующей команды.
php bin/console doctrine:schema:update --force
После выполнения команды вы увидите следующий ответ.
Updating database schema... Database schema updated successfully! "1" query was executed
Теперь снова проверьте схему, используя следующую команду.
php bin/console doctrine:schema:validate
Это даст следующий результат —
[Mapping] OK - The mapping files are correct. [Database] OK - The database schema is in sync with the mapping files.
Шаг 10: получатель и установщик
Как видно из раздела «Привязка сущности», следующая команда генерирует все методы получения и установки для класса Book.
$ php bin/console doctrine:generate:entities AppBundle/Entity/Book
Шаг 11: выбор объектов из базы данных
Создайте метод в BooksController, который будет отображать детали книг.
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)); }
Шаг 12: создайте представление
Давайте создадим представление, которое указывает на действие отображения. Перейдите в каталог представлений и создайте файл «display.html.twig». Добавьте следующие изменения в файл.
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 %}
Вы можете получить результат, запросив URL-адрес «http: // localhost: 8000 / books / display» в браузере.
Результат
Шаг 13: добавь форму книги
Давайте создадим функционал для добавления книги в систему. Создайте новую страницу, метод newAction в BooksController следующим образом.
// 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(),)); }
Шаг 14: создай представление для формы книги
Давайте создадим представление, которое указывает на новое действие. Перейдите в каталог views и создайте файл «new.html.twig». Добавьте следующие изменения в файл.
{% 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 %}
Он выведет следующий экран в качестве вывода —
Шаг 15: собери книжную информацию и сохрани ее
Давайте изменим метод newAction и включим код для обработки отправки формы. Также сохраните информацию о книге в базу данных.
/** * @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(), )); } }
Как только книга будет сохранена в базе данных, перенаправьте ее на страницу отображения книги.
Шаг 16: Обновление книги
Чтобы обновить книгу, создайте действие, updateAction и добавьте следующие изменения.
/** * @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(), )); } }
Здесь мы обрабатываем две функции. Если запрос содержит только идентификатор, мы извлекаем его из базы данных и показываем в виде книги. И, если запрос содержит полную информацию о книге, мы обновляем данные в базе данных и перенаправляем на страницу отображения книги.
Шаг 17: Удаление объекта
Для удаления объекта требуется вызов метода remove () менеджера сущностей (доктрины).
Это можно сделать с помощью следующего кода.
/** * @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'); }
Здесь мы удалили книгу и перенаправили на страницу отображения книги.
Шаг 18: Включить функцию добавления / редактирования / удаления на странице отображения
Теперь обновите блок тела в представлении дисплея и включите ссылки добавления / редактирования / удаления следующим образом.
{% 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 %}
Он выведет следующий экран в качестве вывода —
Symfony состоит из набора PHP-компонентов, инфраструктуры приложений, сообщества и философии. Symfony чрезвычайно гибок и способен удовлетворить все требования опытных пользователей, профессионалов и является идеальным выбором для всех начинающих с PHP.