Symfony - 工作示例
在本章中,我们将学习如何在 Symfony 框架中创建一个完整的基于 MVC 的 BookStore 应用程序。步骤如下。
步骤 1:创建项目
让我们使用以下命令在 Symfony 中创建一个名为"BookStore"的新项目。
symfony new BookStore
步骤 2:创建控制器和路由
在"src/AppBundle/Controller"目录中创建一个 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 { /** * @Route("/books/author") */ public function authorAction() { return new Response('Book store application!'); } }
现在,我们已经创建了一个 BooksController,接下来创建一个视图来呈现操作。
步骤 3:创建视图
让我们在"app/Resources/views/"目录中创建一个名为"Books"的新文件夹。在该文件夹中,创建文件"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:映射信息
在位于"src/AppBundle/Entity"的 Entity 目录中创建一个 Book 实体类。
您可以使用注释直接传递 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; }
此处,表名称是可选的。
如果未指定表名称,则将根据实体类的名称自动确定。
步骤 7:绑定实体
Doctrine 为您创建简单的实体类。它可以帮助您构建任何实体。
发出以下命令以生成实体。
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 表,因此实体不同步。让我们在下一步中使用 Symfony 命令创建 Books 表。
步骤 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:Getter 和 Setter
如绑定实体部分所示,以下命令为 Book 类生成所有 getter 和 setter。
$ 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:创建视图
让我们创建一个指向显示操作的视图。移至 views 目录并创建文件"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:添加图书表单
让我们创建一个将图书添加到系统中的功能。在 BooksController 中创建一个新页面,newAction 方法如下。
// 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(); // 告诉 Doctrine 你想要保存产品 $doct->persist($book); //执行查询(即 INSERT 查询) $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(); // 告诉 Doctrine 你想要保存产品 $doct->persist($book); //执行查询(即 INSERT 查询) $doct->flush(); return $this->redirectToRoute('app_book_display'); } else { return $this->render('books/new.html.twig', array( 'form' => $form->createView(), )); } }
在这里,我们处理两个功能。如果请求仅包含 id,则我们从数据库中提取它并将其显示在图书表单中。并且,如果请求包含完整的图书信息,则我们更新数据库中的详细信息并重定向到图书显示页面。
步骤 17:删除对象
删除对象需要调用实体(doctrine)管理器的 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 初学者的理想选择。