Symfony-complete-working-example

提供:Dev Guides
移動先:案内検索

symfony-動作例

この章では、完全なMVCベースの* BookStoreアプリケーション*をSymfony Frameworkで作成する方法を学びます。 手順は次のとおりです。

ステップ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:ビューを作成する

「apps/Resources/views/」ディレクトリに「Books」という名前の新しいフォルダーを作成しましょう。 フォルダ内に「authorl.twig」ファイルを作成し、以下の変更を追加します。

authorl.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/authorl.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/displayl.twig', array('data' => $bk));
}

ステップ12:ビューを作成する

表示アクションを指すビューを作成しましょう。 ビューディレクトリに移動し、ファイル「displayl.twig」を作成します。 ファイルに次の変更を追加します。

displayl.twig

{% extends 'basel.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」をリクエストすることで結果を取得できます。

結果

Books Database Application

ステップ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/newl.twig', array('form' => $form->createView(),));
}

ステップ14:ブックフォームのビューを作成する

新しいアクションを指すビューを作成しましょう。 ビューディレクトリに移動し、ファイル「newl.twig」を作成します。 ファイルに次の変更を追加します。

{% extends 'basel.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/newl.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/newl.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 %}

それは出力として次の画面を生成します-

Books Database Application

symfonyは、一連のPHPコンポーネント、アプリケーションフレームワーク、コミュニティ、および哲学で構成されています。 symfonyは非常に柔軟で、上級ユーザー、専門家のすべての要件を満たすことができ、PHPを使用するすべての初心者にとって理想的な選択です。