В этой главе мы узнаем, как создать полное приложение 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.