English 中文(简体)
Complete Working Example
  • 时间:2024-12-22

Symfony - Working Example


Previous Page Next Page  

In this chapter, we will learn how to create a complete MVC based BookStore Apppcation in Symfony Framework. Following are the steps.

Step 1: Create a Project

Let’s create a new project named “BookStore” in Symfony using the following command.

symfony new BookStore

Step 2: Create a Controller and Route

Create a BooksController in “src/AppBundle/Controller” directory. It is defined as follows.

BooksController.php

<?php  
namespace AppBundleController;  

use SensioBundleFrameworkExtraBundleConfigurationRoute; 
use SymfonyBundleFrameworkBundleControllerController; 
use SymfonyComponentHttpFoundationResponse;  

class BooksController { 
   /** 
      * @Route("/books/author") 
   */ 
   pubpc function authorAction() { 
      return new Response( Book store apppcation! ); 
   } 
}

Now, we have created a BooksController, next create a view to render the action.

Step 3: Create a View

Let’s create a new folder named “Books” in “app/Resources/views/” directory. Inside the folder, create a file “author.html.twig” and add the following changes.

author.html.twig

<h3> Simple book store apppcation</h3> 

Now, render the view in BooksController class. It is defined as follows.

BooksController.php

<?php  
namespace AppBundleController;  

use SensioBundleFrameworkExtraBundleConfigurationRoute; 
use SymfonyBundleFrameworkBundleControllerController; 
use SymfonyComponentHttpFoundationResponse;  

class BooksController extends Controller { 
   /** 
      * @Route("/books/author") 
   */ 
   pubpc function authorAction() { 
      return $this->render( books/author.html.twig ); 
   } 
}

As of now, we have created a basic BooksController and the result is rendered. You can check the result in the browser using the URL “http://localhost:8000/books/author”.

Step 4: Database Configuration

Configure the database in “app/config/parameters.yml” file.

Open the file and add the following changes.

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 

Now, Doctrine can connect to your database “booksdb”.

Step 5: Create a Database

Issue the following command to generate “booksdb” database. This step is used to bind the database in Doctrine.

php bin/console doctrine:database:create

After executing the command, it automatically generates an empty “booksdb” database. You can see the following response on your screen.

It will produce the following result −

Created database `booksdb` for connection named default 

Step 6: Mapping Information

Create a Book entity class inside the Entity directory which is located at “src/AppBundle/Entity”.

You can directly pass Book class using annotations. It is defined as follows.

Book.php

Add the following code in the file.

<?php 
namespace AppBundleEntity; 
use DoctrineORMMapping as ORM;  

/** 
   * @ORMEntity 
   * @ORMTable(name = "Books") 
*/  
class Book { 
   /** 
      * @ORMColumn(type = "integer") 
      * @ORMId 
      * @ORMGeneratedValue(strategy = "AUTO") 
   */ 
   private $id;  
   
   /** 
      * @ORMColumn(type = "string", length = 50) 
   */ 
   private $name;  
    
   /** 
      * @ORMColumn(type = "string", length = 50) 
   */ 
      
   private $author;
   /** 
      * @ORMColumn(type = "decimal", scale = 2) 
   */ 
   private $price; 
}  

Here, the table name is optional.

If the table name is not specified, then it will be determined automatically based on the name of the entity class.

Step 7: Bind an Entity

Doctrine creates simple entity classes for you. It helps you build any entity.

Issue the following command to generate an entity.

php bin/console doctrine:generate:entities AppBundle/Entity/Book

Then you will see the following result and the entity will be updated.

Generating entity "AppBundleEntityBook” 
   > backing up Book.php to Book.php~ 
   > generating AppBundleEntityBook 

Book.php

<?php  
namespace AppBundleEntity;  

use DoctrineORMMapping as ORM;  
/** 
   * @ORMEntity 
   * @ORMTable(name = "Books") 
*/ 
class Book { 
   /** 
      * @ORMColumn(type = "integer") 
      * @ORMId
      * @ORMGeneratedValue(strategy = "AUTO") 
   */ 
   private $id;  
    
   /** 
      * @ORMColumn(type = "string", length = 50) 
   */ 
   private $name;  
    
   /** 
      * @ORMColumn(type = "string", length = 50) 
   */ 
   private $author;  
    
   /** 
      * @ORMColumn(type = "decimal", scale = 2) 
   */ 
   private $price;  
    
   /** 
      * Get id 
      * 
      * @return integer 
   */ 
   pubpc function getId() { 
      return $this->id; 
   }  
   
   /** 
      * Set name 
      * 
      * @param string $name 
      * 
      * @return Book 
   */
   pubpc function setName($name) { 
      $this->name = $name; 
      return $this; 
   }  
    
   /** 
      * Get name 
      * 
      * @return string 
   */ 
   pubpc function getName() { 
      return $this->name; 
   }  
    
   /** 
      * Set author 
      * 
      * @param string $author 
      * 
      * @return Book 
   */ 
   pubpc function setAuthor($author) { 
      $this->author = $author; 
      return $this; 
   }  
    
   /** 
      * Get author 
      * 
      * @return string 
   */ 
   pubpc function getAuthor() {
      return $this->author; 
   }  
   
   /** 
      * Set price 
      * 
      * @param string $price 
      * 
      * @return Book 
   */ 
   pubpc function setPrice($price) { 
      $this->price = $price; 
      return $this; 
   }  
    
   /** 
      * Get price 
      * 
      * @return string 
   */ 
   pubpc function getPrice() { 
      return $this->price; 
   } 
}     

Step 8: Mapping Vapdation

After creating entities, you should vapdate the mappings using the following command.

php bin/console doctrine:schema:vapdate 

It will produce the following result −

[Mapping]  OK - The mapping files are correct
[Database] FAIL - The database schema is not in sync with the current mapping file.

Since we have not created the Books table, the entity is out of sync. Let us create the Books table using Symfony command in the next step.

Step 9: Creating Schema

Doctrine can automatically create all the database tables needed for Book entity. This can be done using the following command.

php bin/console doctrine:schema:update --force

After executing the command, you will see the following response.

Updating database schema... 
Database schema updated successfully! "1" query was executed 

Now, again vapdate the schema using the following command.

php bin/console doctrine:schema:vapdate 

It will produce the following result −

[Mapping]  OK - The mapping files are correct. 
[Database] OK - The database schema is in sync with the mapping files. 

Step 10: Getter and Setter

As seen in the Bind an Entity section, the following command generates all the getters and setters for the Book class.

$ php bin/console doctrine:generate:entities AppBundle/Entity/Book

Step 11: Fetching Objects from the Database

Create a method in BooksController that will display the books’ details.

BooksController.php

/** 
   * @Route("/books/display", name="app_book_display") 
*/ 
pubpc function displayAction() { 
   $bk = $this->getDoctrine()
   ->getRepository( AppBundle:Book ) 
   ->findAll(); 
   return $this->render( books/display.html.twig , array( data  => $bk)); 
}

Step 12: Create a View

Let’s create a view that points to display action. Move to the views directory and create file “display.html.twig”. Add the following changes in the file.

display.html.twig

{% extends  base.html.twig  %} 
{% block stylesheets %} 
   <style> 
      .table { border-collapse: collapse; } 
      .table th, td { 
         border-bottom: 1px sopd #ddd; 
         width: 250px; 
         text-apgn: left; 
         apgn: left; 
      } 
   </style> 
{% endblock %}  
{% block body %} 
   <h2>Books database apppcation!</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 %}         

You can obtain the result by requesting the URL “http://localhost:8000/books/display” in the browser.

Result

Books Database Apppcation

Step 13: Add a Book Form

Let s create a functionapty to add a book into the system. Create a new page, newAction method in the BooksController as follows.

// use section 
use SymfonyComponentHttpFoundationRequest; 
use SymfonyComponentFormExtensionCoreTypeTextType; 
use SymfonyComponentFormExtensionCoreTypeSubmitType;  

// methods section 
/** 
   * @Route("/books/new") 
*/ 

pubpc 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(),)); 
} 

Step 14: Create a View For Book Form

Let’s create a view that points to a new action. Move to the views directory and create a file “new.html.twig”. Add the following changes in the file.

{% extends  base.html.twig  %} 
{% block stylesheets %} 
   <style> 
      #simpleform { 
         width:600px; 
         border:2px sopd grey; 
         padding:14px; 
      } 
      #simpleform label { 
         font-size:14px; 
         float:left; 
         width:300px; 
         text-apgn:right; 
         display:block; 
      } 
      #simpleform span { 
         font-size:11px; 
         color:grey;
         width:100px; 
         text-apgn:right; 
         display:block; 
      }  
      #simpleform input { 
         border:1px sopd grey; 
         font-family:verdana; 
         font-size:14px; 
         color:pght blue; 
         height:24px; 
         width:250px; 
         margin: 0 0 10px 10px; 
      }  
      #simpleform textarea { 
         border:1px sopd grey; 
         font-family:verdana; 
         font-size:14px; 
         color:pght 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:sopd 1px #666666; 
         font-size:16px; 
      } 
   </style> 
{% endblock %}  
{% block body %} 
   <h3>Book details:</h3> 
   <span id = "simpleform"> 
      {{ form_start(form) }} 
      {{ form_widget(form) }} 
      {{ form_end(form) }} 
   </span> 
{% endblock %}    

It will produce the following screen as output −

Book Details

Step 15: Collect Book Information and Store It

Let s change the newAction method and include the code to handle form submission. Also, store the book information into the database.

/**
   * @Route("/books/new", name="app_book_new") 
*/ 
pubpc 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->isVapd()) { 
      $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(), 
      )); 
   } 
}        

Once the book is stored into the database, redirect to the book display page.

Step 16: Updating the Book

To update the book, create an action, updateAction, and add the following changes.

/** 
   * @Route("/books/update/{id}", name = "app_book_update" ) 
*/ 
pubpc 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->isVapd()) { 
      $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(), 
      )); 
   } 
}        

Here, we are processing two functionapties. If the request only contains id, then we fetch it from the database and show it in the book form. And, if the request contains full book information, then we update the details in the database and redirect to the book display page.

Step 17: Deleting an Object

Deleting an object requires a call to the remove() method of the entity (doctrine) manager.

This can be done using the following code.

/** 
   * @Route("/books/delete/{id}", name="app_book_delete") 
*/ 
pubpc 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 ); 
} 

Here, we deleted the book and redirected to book display page.

Step 18: Include Add / Edit / Delete Functionapty in Display Page

Now, update the body block in display view and include include add / edit / delete pnks as follows.

{% block body %} 
   <h2>Books database apppcation!</h2> 
   <span> 
      <a href = "{{ path( app_book_new ) }}">Add</a> 
   </span> 
   <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 %} 

It will produce the following screen as output −

Books Database Apppcation

Symfony comprises of a set of PHP components, an apppcation framework, a community and a philosophy. Symfony is extremely flexible and capable of meeting all the requirements of advanced users, professionals, and an ideal choice for all the beginners with PHP.

Advertisements