Symfony工作示例


在本章中,我们将学习如何在Symfony Framework中创建一个完整的基于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类生成所有获取者和设置者。

$ 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步:添加书形式

让我们创建一个功能来添加一本书到系统中。在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步:删除一个对象

删除对象需要调用实体(教条)管理器的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初学者的理想选择。