1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する(5. チケット管理システムを再現➀)

Last updated at Posted at 2020-07-16

はじめに

Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する
(4.PDO使用)
の続きです。

前提

下記記事で構築した環境を前提とします。

  • Windows10にVagrantをを入れてCentOS7をインストールしよう(123456)

  • ローカルでLAMP環境を構築しよう(01234

  • CentOS7にComposerをインストールしよう

  • 私家版 Slim Framework チュートリアル (123456)
    @nunulkさんのチュートリアルを一通り。
    ここで作成したDBを使いまわします。

  • Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する(1234

手順

1. 専用のユーザーを作成
2. プロジェクトディレクトリを作成・slim3インストール
3. 各種設定
4. DocumentRootを変更&表示確認
5. Twigを使ってみよう
6. Loggingしてみよう
7. Controllerを作成しよう
8. PDOを使用してデータベースに接続しよう
9. @nunulkさんのチュートリアルで作成したチケット管理システムをtwigを使って再現しよう

やってみよう

今回の記事では、手順9を行います。

9. @nunulkさんのチュートリアルで作成したチケット管理システムをtwigを使って再現しよう

Repositoryを実装

Repositoryでは、データベースとの通信を行うための、データアクセスロジックを実装します。
下記のようにフォルダ・ファイルを作成してください。

.
├── src/             
    └── Domain/
        └── Ticket/
            └── TicketRepository.php

src/Domain/Ticket/TicketRepository.phpには以下のように記述します。
CRUD機能を一通り用意します。

TicketRepository.php
<?php

namespace App\Domain\Ticket;

use DomainException;
use PDO;

final class TicketRepository
{
    private $PDO;

    public function __construct(PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    public function getTicketById(int $id): array
    {
        $sql = 'SELECT * FROM tickets WHERE id = :id';
        $stmt = $this->pdo->prepare($sql);
        $stmt->execute(['id' => $id]);
        $row = $stmt->fetch();

        if (empty($row)) {
            throw new DomainException(sprintf('Ticket not found: %s', $id));
        }

        return $row ?: [];
    }

    public function getTickets(): array
    {
        $sql = 'SELECT * FROM tickets';
        $stmt = $this->pdo->query($sql);
        $tickets = [];
        while($row =$stmt->fetch()) {
            $tickets[] = $row;
        }
        if (empty($tickets)) {
            throw new DomainException('Tickets not found');
        }
        return $tickets ?: [];
    }

    public function insertTicket($subject): bool
    {
        $sql = 'INSERT INTO tickets (subject) values (:subject)';
        $stmt = $this->pdo->prepare($sql);
        $result = $stmt->execute(['subject' => $subject]);
        if (!$result) {
            throw new DomainException('could not save the ticket');
        }
        return $result;
    }

    public function updateTicket($ticket): bool
    {
        $bool_flg = true;

        try {
            $selectTicket = $this->getTicketById($ticket['id']);
        } catch (DomainException $e) {
            $bool_flg = false;
        }

        if ($bool_flg) {

            $sql = 'UPDATE tickets SET subject = :subject WHERE id = :id';
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute($ticket);
        }

        return $bool_flg;
    }

    public function deleteTicket(int $id): bool
    {
        $bool_flg = true;
        try {
            $ticket = $this->getTicketById($id);
        } catch (DomainException $e) {
            $bool_flg = false;
        }

        if ($bool_flg) {

            $sql = 'DELETE FROM tickets WHERE id = :id';
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute(['id' => $ticket['id']]);
        }

        return $bool_flg;
    }
}

Serviceクラスを実装

Serviceクラスにはビジネスロジックを実装します。
ServiceクラスはControllerから呼び出されます。
Serviceクラスでは、Repositoryで実装されたメソッドを使用します。
下記のようにフォルダ・ファイルを作成してください。

.
├── src/             
    └── Domain/
        └── Ticket/
            └── TicketRepository.php
            └── TicketService.php

src/Domain/Ticket/TicketService.phpには以下のように記述します。

TicketService.php
<?php

namespace App\Domain\Ticket;

final class TicketService
{
    private $ticketRepository;

    public function __construct(TicketRepository $ticketRepository)
    {
        $this->ticketRepository = $ticketRepository;
    }

    public function getTicketById(int $id): array
    {
        $ticketRow = $this->ticketRepository->getTicketById($id);
        return $ticketRow;
    }

    public function getTickets(): array
    {
        $ticketRows = $this->ticketRepository->getTickets();
        return $ticketRows;
    }

    public function insertTicket($subject): bool
    {
        $result = $this->ticketRepository->insertTicket($subject);
        return $result;
    }

    public function updateTicket($ticket): bool
    {
        $result = $this->ticketRepository->updateTicket($ticket);
        return $result;
    }

    public function deleteTicket(int $id): bool
    {
        $result = $this->ticketRepository->deleteTicket($id);
        return $result;
    }
}

Controllerクラスを実装

Controllerクラスを実装して、まずは前回実装したチケット一覧画面を表示してみましょう。
Controllerクラスですが、ネーミングはダニエルさんに従ってActionクラスです。
なぜですか。ダニエルさん。

下記のようにフォルダ・ファイルを作成してください。

.
├── src/             
    └── Domain/
        └── Ticket/
            └── TicketRepository.php
            └── TicketService.php
    └── Action/
        └── Action.php
        └── TicketAction.php

まずは抽象クラスのsrc/Action/Action.phpに以下のように記述します。

Action.php
<?php

namespace App\Action;

use Psr\Container\ContainerInterface;
use Slim\Views\PhpRenderer;

abstract class Action
{
    protected $renderer;
    protected $db;
    protected $twig;

    public function __construct(ContainerInterface $container)
    {
        $this->renderer = $container['renderer'];
        $this->db = $container['db'];
        $this->twig = $container['twig'];
    }
}

src/Action/Action.phpを継承したsrc/Action/TicketAction.php以下のように記述します。

TicketAction.php
<?php

namespace App\Action;

use App\Domain\Ticket\TicketRepository;
use App\Domain\Ticket\TicketService;
use Psr\Http\Message\ResponseInterface;
use Slim\Http\Request;
use Slim\Http\Response;

final class TicketAction extends Action
{
    public function index(Request $request, Response $response)
    {
        $repository = new TicketRepository($this->db);
        $service = new TicketService($repository);
        $tickets = $service->getTickets();
        $data = ['tickets' => $tickets];
        return $this->twig->render($response, 'tickets/index.twig', $data);
    }
}

routes.php修正

config/routes.phpで、前回修正した箇所を削除し、以下の記述を追加します。

config/routes.php
$app->get('/tickets', \App\Action\TicketAction::class . ':index');

container.php修正

config/container.phpで、以前追加した箇所を修正します。

config/container.php(修正前)
$container[Twig::class] = function (Container $container) {
config/container.php(修正後)
$container['twig'] = function (Container $container) {

動作確認

ブラウザで以下のURLを開いて、チケット一覧画面が表示されればOKです。

http://192.168.33.90/tickets

以前作成したページを表示するための修正

上記変更を行ったので、time.twighome-index.twigは表示できなくなりましたので、修正します。

time.twig

以下のようにsrc/Action/TimeAction.phpを追加します。

src/Action/TimeAction.php
<?php

namespace App\Action;

use Slim\Http\Request;
use Slim\Http\Response;

final class TimeAction extends Action
{
    public function __invoke(Request $request, Response $response)
    {
        $viewData = [
            'now' => date('Y-m-d H:i:s')
        ];
        return $this->twig->render($response, 'time.twig', $viewData);
    }
}

次にconfig/routes.phpを修正します。

config/routes.php(修正前)
$app->get('/time', function (Request $request, Response $response) {
    $viewData = [
        'now' => date('Y-m-d H:i:s')
    ];

    return $this->get(Twig::class)->render($response, 'time.twig', $viewData);
});
config/routes.php(修正後)
$app->get('/time', \App\Action\TimeAction::class);

home-index.twig

home-twig.twig用に設定したcontainer.phpの内容を削除し、
src/Action/HomeIndexAction.phpを以下のように変更します。

src/Action/HomeIndexAction.php
<?php

namespace App\Action;

use Psr\Http\Message\ResponseInterface;
use Slim\Http\Request;
use Slim\Http\Response;

final class HomeIndexAction extends Action
{
    /**
     * Action.
     *
     * @param Request $request the request
     * @param Response $response the response
     *
     * @return ResponseInterface the response
     */
    public function __invoke(Request $request, Response $response): ResponseInterface
    {
        $viewData = [
            'name' => 'World',
        ];

        return $this->twig->render($response, 'Home/home-index.twig', $viewData);
    }
}

Action.phpを継承することでControllerクラスにTwigの宣言が不要になりましたし、
container.phpに記述する設定も不要になり、実装がシンプルになりました。

参考サイト

Creating your first Slim 3 Framework Application
Creating your first Slim 3 Framework Application Part 2
私家版 Slim Framework チュートリアル (123456)

関連ページ

Windows10にVagrantをを入れてCentOS7をインストールしよう

1. VagrantインストールからVagrantfileを設置まで
2. 仮想マシンの操作
3. WinSCP、Tera Termに秘密鍵でログイン
4. WinSCP、Tera Termにrootユーザーでパスワードログイン
5. zip/unzipをインストール
6. Vagrantにて仮想環境を配布

ローカルでLAMP環境を構築しよう

0. 事前準備
1. Apacheをインストール
2. MySQLをインストール
3. PHPをインストール
4. ファイアウォールとか停止する

Composerをインストール

CentOS7にComposerをインストールしよう

PHP Slim3フレームワークのサンプルアプリを作ろう

2-1. First Application Walkthrough Getting Set Upまで

Apache

DocumentRootを変更しよう

Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する

1. プロジェクト作成~各種設定
2. DocumentRoot変更~Twigを使用
3. LoggingとController
4.PDO使用
5. チケット管理システムを再現➀
6. チケット管理システムを再現➁

1
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?