- Symfony 教程
- Symfony - 首页
- Symfony - 简介
- Symfony - 安装
- Symfony - 架构
- Symfony - 组件
- Symfony - 服务容器
- Symfony - 事件与事件监听器
- Symfony - 表达式
- Symfony - Bundles
- 创建简单的Web应用程序
- Symfony - 控制器
- Symfony - 路由
- Symfony - 视图引擎
- Symfony - Doctrine ORM
- Symfony - 表单
- Symfony - 验证
- Symfony - 文件上传
- Symfony - Ajax控制
- Cookie与会话管理
- Symfony - 国际化
- Symfony - 日志记录
- Symfony - 邮件管理
- Symfony - 单元测试
- Symfony - 高级概念
- Symfony - REST版本
- Symfony - CMF版本
- 完整的实战示例
- Symfony 有用资源
- Symfony - 快速指南
- Symfony - 有用资源
- Symfony - 讨论
Symfony - 实战示例
本章将学习如何在Symfony框架中创建一个完整的基于MVC的图书商店应用程序。以下是步骤。
步骤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“https://127.0.0.1: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:创建视图
让我们创建一个指向display操作的视图。移动到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“https://127.0.0.1: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(); // 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(), )); } }
在这里,我们正在处理两个功能。如果请求只包含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:在显示页面中包含添加/编辑/删除功能
现在,更新display视图中的body块,并包含添加/编辑/删除链接,如下所示。
{% 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 初学者的理想选择。