2021年4月4日日曜日

PHP:Symfony-05

1.SymfonyでのRDB接続

Symfonyフレームワークでは公式で用意されているレシピではDoctrine (Doctrine DBAL / Doctrine ORM)に対応しています。Doctrine ORMではORマッピングを利用したRDB処理、Doctrine DBALではPHP PDOをラップしたようなものになっています。Doctrine DBALではPDO同様にMySQL / MariaDB / PostgreSQL 等に対して SQL を実行する以外に、SQLを生成するクエリビルダ―の機能も有ります。


2.DBとの接続

.env ファイルの修正

 DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name

データベースはコマンドで作成または、DBで作成することも可能です

3.エンティの作成

>php bin/console make:entity books

 created: src/Entity/Books.php

 created: src/Repository/BooksRepository.php

  book_id  integer notnull

  book_name  string 255 notnull

  book_price  integer notnull

  book_release  date notnull


>php bin/console make:migration

>php bin/console doctrine:migrations:migrate

これでテーブルが作成されます

またリポジトリのファイルも作成されます

4.ソースの修正など

/src/Repository ディレクトリに、BooksRepository.php をインタフェースに修正

<?php

namespace App\Repository;

interface BooksRepository
{
    public function get(int $book_id);
}

/src/Repository/Impl ディレクトリに、BooksRepositoryImpl.php を追加し、BooksRepository.phpを実装する

<?php

namespace App\Repository\Impl;

use App\Repository\BooksRepository;

class BooksRepositoryImpl implements BooksRepository
{

    /** @var \Doctrine\DBAL\Connection connection */
    protected $db;

    /** @var Psr\Log\LoggerInterface logger */
    protected $logger;

    public function __construct(\Doctrine\DBAL\Connection $con, 
                                \Psr\Log\LoggerInterface $logger)
    {
        $this->db = $con;
        $this->logger = $logger;
    }

    public function get(int $book_id)
    {
        $sql = "SELECT * FROM books WHERE book_id = :book_id";

        $stmt = $this->db->prepare($sql);
        $stmt->bindValue("book_id", $book_id);
        $stmt->execute();

        $book = $stmt->fetch();

        return $book;
    }
}

/src/Service ディレクトリに、BooksService.php を作成

<?php
namespace App\Service;

use App\Repository\BooksRepository;

class BooksService
{
    private $booksRepository;

    /** @var Psr\Log\LoggerInterface logger */
    protected $logger;

    public function __construct(BooksRepository $booksRepository, 
                                \Psr\Log\LoggerInterface $logger)
    {
        $this->booksRepository = $booksRepository;
        $this->logger = $logger;
    }

    public function bookDetail(int $book_id)
    {
        $this->logger->log('info'
          'book_id: ' . $book_id . ' の詳細データを取得して返します');
        return $this->booksRepository->get($book_id);
    }

}

Controller/RootController.phpを修正します

    /**
     * http://127.0.0.1:8000/books/detail/1/
     * @Route("/books/detail/{book_id}/", name="book_detail", 
     * requirements={"book_id"="\d+"})
     */
    public function bookDetailAction($book_id, BooksService $booksService)
    {
        $book = $booksService->bookDetail($book_id);

        return $this->render('books/detail.html.twig', [
            'book_id' => $book_id,
            'book_detail' => $book
        ]);
    }

detail.html.twig を修正

{% extends 'base.html.twig' %}
 
{% block title %}Book Detail{% endblock %}
 
{% block body %}
 
<h1>Book Detail ID:{{ book_id }}</h1>
<p>
    <div>書籍名: {{ book_detail.book_name }}</div>
    <div>価格: {{ book_detail.book_price|number_format }}円</div>
    <div>発売日: {{ book_detail.book_release }}</div>
</p>
 
{% endblock %}