- Symfony 教程
- Symfony - 主页
- Symfony - 简介
- Symfony - 安装
- Symfony - 架构
- Symfony - 组件
- Symfony - 服务容器
- Symfony - 事件和事件监听器
- Symfony - 表达
- Symfony - 捆绑包
- 创建一个简单的 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 的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”并添加以下更改。
作者.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”在浏览器中检查结果。
第四步:数据库配置
在“app/config/parameters.yml”文件中配置数据库。
打开文件并添加以下更改。
参数.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 类。它的定义如下。
图书.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
图书.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.html.twig”。在文件中添加以下更改。
显示.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 %}
它将产生以下屏幕作为输出 -
第十五步:收集图书信息并存储
让我们更改 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 步:删除对象
删除对象需要调用实体(教义)管理器的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 初学者的理想选择。