Symfony - Ví dụ làm việc
Trong chương này, chúng ta sẽ học cách tạo một MVC hoàn chỉnh dựa trên BookStore Applicationtrong Symfony Framework. Sau đây là các bước.
Bước 1: Tạo dự án
Hãy tạo một dự án mới có tên “BookStore” trong Symfony bằng cách sử dụng lệnh sau.
symfony new BookStore
Bước 2: Tạo Bộ điều khiển và Định tuyến
Tạo BooksController trong thư mục “src / AppBundle / Controller”. Nó được định nghĩa như sau.
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!');
}
}
Bây giờ, chúng ta đã tạo một BooksController, tiếp theo là tạo một khung nhìn để hiển thị hành động.
Bước 3: Tạo chế độ xem
Hãy tạo một thư mục mới có tên là “Sách” trong thư mục “app / Resources / views /”. Bên trong thư mục, tạo một tệp “authorr.html.twig” và thêm các thay đổi sau.
tác giảr.html.twig
<h3> Simple book store application</h3>
Bây giờ, hiển thị dạng xem trong lớp BooksController. Nó được định nghĩa như sau.
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');
}
}
Hiện tại, chúng tôi đã tạo một BooksController cơ bản và kết quả được hiển thị. Bạn có thể kiểm tra kết quả trong trình duyệt bằng URL “http: // localhost: 8000 / books / author”.
Bước 4: Cấu hình cơ sở dữ liệu
Định cấu hình cơ sở dữ liệu trong tệp “app / config / parameter.yml”.
Mở tệp và thêm các thay đổi sau.
tham số.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
Bây giờ, Doctrine có thể kết nối với cơ sở dữ liệu của bạn “booksdb”.
Bước 5: Tạo cơ sở dữ liệu
Thực hiện lệnh sau để tạo cơ sở dữ liệu “booksdb”. Bước này được sử dụng để liên kết cơ sở dữ liệu trong Doctrine.
php bin/console doctrine:database:create
Sau khi thực hiện lệnh, nó sẽ tự động tạo ra một cơ sở dữ liệu “booksdb” trống. Bạn có thể thấy phản hồi sau trên màn hình của mình.
Nó sẽ tạo ra kết quả sau:
Created database `booksdb` for connection named default
Bước 6: Lập bản đồ thông tin
Tạo một lớp thực thể Sách bên trong thư mục Thực thể nằm tại “src / AppBundle / Entity”.
Bạn có thể trực tiếp vượt qua lớp Sách bằng cách sử dụng chú thích. Nó được định nghĩa như sau.
Book.php
Thêm mã sau vào tệp.
<?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;
}
Ở đây, tên bảng là tùy chọn.
Nếu tên bảng không được chỉ định, thì nó sẽ được xác định tự động dựa trên tên của lớp thực thể.
Bước 7: Ràng buộc một thực thể
Doctrine tạo các lớp thực thể đơn giản cho bạn. Nó giúp bạn xây dựng bất kỳ thực thể nào.
Đưa ra lệnh sau để tạo một thực thể.
php bin/console doctrine:generate:entities AppBundle/Entity/Book
Sau đó, bạn sẽ thấy kết quả sau và thực thể sẽ được cập nhật.
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;
}
}
Bước 8: Xác thực ánh xạ
Sau khi tạo các thực thể, bạn nên xác thực các ánh xạ bằng lệnh sau.
php bin/console doctrine:schema:validate
Nó sẽ tạo ra kết quả sau:
[Mapping] OK - The mapping files are correct
[Database] FAIL - The database schema is not in sync with the current mapping file.
Vì chúng tôi chưa tạo bảng Sách nên thực thể không đồng bộ. Hãy để chúng tôi tạo bảng Sách bằng lệnh Symfony trong bước tiếp theo.
Bước 9: Tạo lược đồ
Doctrine có thể tự động tạo tất cả các bảng cơ sở dữ liệu cần thiết cho thực thể Sách. Điều này có thể được thực hiện bằng cách sử dụng lệnh sau.
php bin/console doctrine:schema:update --force
Sau khi thực hiện lệnh, bạn sẽ thấy phản hồi sau.
Updating database schema...
Database schema updated successfully! "1" query was executed
Bây giờ, hãy xác thực lại lược đồ bằng lệnh sau.
php bin/console doctrine:schema:validate
Nó sẽ tạo ra kết quả sau:
[Mapping] OK - The mapping files are correct.
[Database] OK - The database schema is in sync with the mapping files.
Bước 10: Getter và Setter
Như đã thấy trong phần Bind an Entity, lệnh sau tạo tất cả getters và setters cho lớp Sách.
$ php bin/console doctrine:generate:entities AppBundle/Entity/Book
Bước 11: Tìm nạp đối tượng từ cơ sở dữ liệu
Tạo một phương thức trong BooksController sẽ hiển thị thông tin chi tiết của sách.
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));
}
Bước 12: Tạo chế độ xem
Hãy tạo một dạng xem trỏ đến hành động hiển thị. Di chuyển đến thư mục khung nhìn và tạo tệp “display.html.twig”. Thêm các thay đổi sau vào tệp.
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 %}
Bạn có thể nhận được kết quả bằng cách yêu cầu URL “http: // localhost: 8000 / books / display” trong trình duyệt.
Kết quả
Bước 13: Thêm Mẫu Sách
Hãy tạo một chức năng để thêm sách vào hệ thống. Tạo một trang mới, phương thức newAction trong BooksController như sau.
// 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(),));
}
Bước 14: Tạo dạng xem cho mẫu sách
Hãy tạo một dạng xem trỏ đến một hành động mới. Di chuyển đến thư mục views và tạo một tệp “new.html.twig”. Thêm các thay đổi sau vào tệp.
{% 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 %}
Nó sẽ tạo ra màn hình sau dưới dạng đầu ra:
Bước 15: Thu thập thông tin sách và lưu trữ
Hãy thay đổi phương thức newAction và bao gồm mã để xử lý việc gửi biểu mẫu. Đồng thời, lưu trữ thông tin sách vào cơ sở dữ liệu.
/**
* @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(),
));
}
}
Sau khi sách được lưu trữ vào cơ sở dữ liệu, hãy chuyển hướng đến trang hiển thị sách.
Bước 16: Cập nhật sách
Để cập nhật sách, hãy tạo một hành động, updateAction và thêm các thay đổi sau.
/**
* @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(),
));
}
}
Ở đây, chúng tôi đang xử lý hai chức năng. Nếu yêu cầu chỉ chứa id, thì chúng tôi tìm nạp nó từ cơ sở dữ liệu và hiển thị nó ở dạng sách. Và, nếu yêu cầu chứa đầy đủ thông tin sách, thì chúng tôi cập nhật thông tin chi tiết trong cơ sở dữ liệu và chuyển hướng đến trang hiển thị sách.
Bước 17: Xóa đối tượng
Việc xóa một đối tượng yêu cầu một lệnh gọi đến phương thức remove () của trình quản lý thực thể (học thuyết).
Điều này có thể được thực hiện bằng cách sử dụng mã sau.
/**
* @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');
}
Tại đây, chúng tôi đã xóa sách và chuyển hướng đến trang hiển thị sách.
Bước 18: Bao gồm chức năng Thêm / Chỉnh sửa / Xóa trong Trang hiển thị
Bây giờ, hãy cập nhật khối nội dung trong chế độ xem hiển thị và bao gồm các liên kết thêm / sửa / xóa như sau.
{% 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 %}
Nó sẽ tạo ra màn hình sau dưới dạng đầu ra:
Symfony bao gồm một tập hợp các thành phần PHP, một khuôn khổ ứng dụng, một cộng đồng và một triết lý. Symfony cực kỳ linh hoạt và có khả năng đáp ứng tất cả các yêu cầu của người dùng cao cấp, các chuyên gia và là sự lựa chọn lý tưởng cho tất cả những người mới bắt đầu với PHP.