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.