Symfony-実例

この章では、完全なMVCベースを作成する方法を学習します BookStore ApplicationSymfonyフレームワークで。手順は次のとおりです。

ステップ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:ゲッターとセッター

[エンティティのバインド]セクションに示されているように、次のコマンドは、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:ビューを作成する

表示アクションを指すビューを作成しましょう。viewsディレクトリに移動し、ファイル「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(), 
      )); 
   } 
}

ここでは、2つの機能を処理しています。リクエストにIDのみが含まれている場合は、データベースから取得してブック形式で表示します。また、リクエストに完全な書籍情報が含まれている場合は、データベースの詳細を更新して、書籍の表示ページにリダイレクトします。

ステップ17:オブジェクトを削除する

オブジェクトを削除するには、エンティティ(doctrine)マネージャーの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のすべての初心者にとって理想的な選択肢です。