はじめに
Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する
(3. LoggingとController)の続きです。
前提
下記記事で構築した環境を前提とします。
手順
1. 専用のユーザーを作成
2. プロジェクトディレクトリを作成・slim3インストール
3. 各種設定
4. DocumentRootを変更&表示確認
5. Twigを使ってみよう
6. Loggingしてみよう
7. Controllerを作成しよう
8. PDOを使用してデータベースに接続しよう
9. @nunulkさんのチュートリアルで作成したチケット管理システムをtwigを使って再現しよう
やってみよう
今回の記事では、手順8を行います。
8. PDOを使用してデータベースに接続しよう
settings.phpに設定を追加
以下の記述を追加します。
$settings['db'] = [
'driver' => 'mysql',
'host' => 'localhost',
'user' => 'root',
'pass' => 'P@ssw0rd',
'dbname' => 'slim_tutorial',
'charset' => 'utf8',
'collection' => 'utf8_unicode_ci',
'flags' => [
PDO::ATTR_PERSISTENT => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
],
];
$settings['renderer'] = [
'template_path' => __DIR__ . '/../templates/',
];
container.phpに設定を追加
以下の記述を追加します。
$container['db'] = function (Container $container) {
$settings = $container->get('settings');
$host = $settings['db']['host'];
$dbname = $settings['db']['dbname'];
$username = $settings['db']['user'];
$password = $settings['db']['pass'];
$dsn = "mysql:host=$host;dbname=$dbname";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_PERSISTENT => false,
PDO::ATTR_EMULATE_PREPARES => true,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
];
return new PDO($dsn, $username, $password, $options);
};
$container['renderer'] = function (Container $c) {
$settings = $c->get('settings')['renderer'];
return new \Slim\Views\PhpRenderer($settings['template_path']);
};
routes.phpにルートを追加
以下の記述を追加します。
$app->get('/tickets', function (Request $request, Response $response) {
$sql = 'SELECT * FROM tickets';
$stmt = $this->db->query($sql);
$tickets = [];
while($row = $stmt->fetch()) {
$tickets[] = $row;
}
$data = ['tickets' => $tickets];
return $this->renderer->render($response, 'tickets/index.phtml', $data);
});
#@nunulkさんのチュートリアルで作成したチケット管理システムのチケット一覧だけ表示してみる
さて、ここまででDBに接続する準備はできました。
早速@nunulkさんのチュートリアルで作成したチケット管理システムのチケット一覧を表示して、
DBに接続できるか試してみましょう。
templatesディレクトリの下にticketsディレクトリを作成し、
事前に作っておいたファイルを以下のコマンドでコピーしてきましょう。
コピー元のパスはご自分の環境に置き換えてください。
cp /home/slimuser/projects/slim/Tutorial-First-Application/templates/tickets/index.phtml /home/slimuser/projects/slim/SampleApplication/templates/tickets/index.phtml
cp /home/slimuser/projects/slim/Tutorial-First-Application/templates/header.phtml /home/slimuser/projects/slim/SampleApplication/templates/header.phtml
cp /home/slimuser/projects/slim/Tutorial-First-Application/templates/footer.phtml /home/slimuser/projects/slim/SampleApplication/templates/footer.phtml
cp /home/slimuser/projects/slim/Tutorial-First-Application/src/helpers.php /home/slimuser/projects/slim/SampleApplication/src/helpers.php
composer.jsonには下記を追記します。
"autoload": {
"psr-4": {
"App\\":"src/"
}
,"files":["src/helpers.php"] ←追記
},
composer.jsonを編集したので、下記コマンドを実行します。
composer dump-autoload
動作確認
ブラウザで以下のURLを開いてください。
以下の画像のように表示されたらOKです。
http://192.168.33.90/tickets
ついでに先程表示したチケット一覧をtwig化してみよう
base.twigを作成
@nunulkさんのチュートリアルではheader.phtmlとfooter.phtmlを作成し、
各ファイルから呼び出していましたが、せっかくtwigを使用するのでアプローチを変えてみましょう。
templates/base.twig
というファイルを作成し、以下のように記述してください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8"/>
<title>チケット管理</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" type="text/css">
</head>
<body>
<div class="container">
<h1>チケット管理</h1>
{% block content %}{% endblock %}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0/js/bootstrap.min.js"></script>
</body>
</html>
templates/base.twig
という共通のテンプレートを作成し、
それぞれのファイルからtemplates/base.twig
を呼び出し、
{% block content %}~{% endblock %}の中にそれぞれのメインコンテンツを記述します。
header.phtmlとfooter.phtmlはもう使用しないので削除しておきましょう。
rm templates/header.phtml
rm templates/footer.phtml
index.phtmlをtwig化
index.phtmlの拡張子をtwigに変更します。
mv /home/slimuser/projects/slim/SampleApplication/templates/tickets/index.phtml /home/slimuser/projects/slim/SampleApplication/templates/tickets/index.twig
templates/tickets/index.twig
を以下のように変更します。
<?= $this->fetch('header.phtml') ?>
<div class="card">
<div class="card-body">
<h2 class="card-title">チケット一覧</h2>
<div class="card-text">
<a href="/tickets/create">新規作成</a>
<ul class="list-group">
<?php foreach($tickets as $ticket): ?>
<li class="list-group-item">
<a href="/tickets/<?= $ticket['id'] ?>">
<?= e($ticket['subject']) ?>
</a>
</li>
<?php endforeach ?>
</ul>
</div>
</div>
</div>
<?= $this->fetch('footer.phtml') ?>
{% extends 'base.twig' %}
{% block content %}
<div class="card">
<div class="card-body">
<h2 class="card-title">チケット一覧</h2>
<div class="card-text">
<a href="/tickets/create">新規作成</a>
<ul class="list-group">
{% for ticket in tickets %}
<li class="list-group-item">
<a href="/tickets/{{ticket.id}}">
{{ticket.subject|escape('html')}}
</a>
</li>
{% endfor %}
</ul>
</div>
</div>
</div>
{% endblock %}
helpers.php削除
helpers.phpから、htmlspecialchars関数を呼び出すようにしていましたが、
twigではhtmlspecialchars関数を使わないので、helpers.phpを以下のコマンドで削除しましょう。
rm src/helpers.php
composer.jsonからもhelpers.phpの記述を削除します。
"autoload": {
"psr-4": {
"App\\":"src/"
}
,"files":["src/helpers.php"]
},
"autoload": {
"psr-4": {
"App\\":"src/"
}
},
composer.jsonを編集したので、下記コマンドを実行します。
composer dump-autoload
routes.phpのルートを修正
以下の記述になるように修正します。
$app->get('/tickets', function (Request $request, Response $response) {
$sql = 'SELECT * FROM tickets';
$stmt = $this->db->query($sql);
$tickets = [];
while($row = $stmt->fetch()) {
$tickets[] = $row;
}
$data = ['tickets' => $tickets];
return $this->get(Twig::class)->render($response, 'tickets/index.twig', $data);
});
動作確認
ブラウザで以下のURLを開いてください。
先程のチケット一覧画面が表示されたらOKです。
http://192.168.33.90/tickets
twig文法解説
今回使用したtwigの文法を解説します。
継承(extends)
twigではHTML全体を記述したベーステンプレートを用意して、
子テンプレートで上書きできる部分を blockタグで定義することができます。
今回はベーステンプレートがtemplates/base.twig
、templates/tickets/index.twig
が子テンプレートです。
子テンプレートでは以下のように記述することでベーステンプレートを継承します。
{% extends 'ベーステンプレート名' %}
blockタグは以下のように記述します。
子テンプレートでは、ベーステンプレートで記述した同名のブロック名を持つblockタグ内にメインコンテンツを記述します。
{% block ブロック名 %}{% endblock %}
for文
Twig でループを作るには for 〜 in を用います。
{% for key, value in users %} のようにしてキー名を取り出すことも出来ます
{% for ticket in tickets %}
// 処理
{% endfor %}
このような書き方も。
{% for i in 0..10 %}
// 処理
{% endfor %}
HTMLエスケープ
phpのhtmlspecialchars関数でやっていたことはtwigでは以下のように記述します。
{{ ticket.subject|escape }}
または
{{ ticket.subject|e }}
デフォルトでhtmlエスケープを行いますが、コンテクストに応じたエスケープをしたい場合は、以下のように記述します。
{{ ticket.subject|e('html') }}
{{ ticket.subject|e('js') }}
{{ ticket.subject|e('css') }}
など
参考サイト
Creating your first Slim 3 Framework Application
私家版 Slim Framework チュートリアル (1、2、3、4、5、6)
[PHP]Twigテンプレートの実践的な構成と作り方
Twig テンプレート
escape
関連ページ
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をインストール
PHP Slim3フレームワークのサンプルアプリを作ろう
2-1. First Application Walkthrough Getting Set Upまで
Apache
Slim3 Framework×slim-skeleton不使用×twigでプロジェクトを作成する
1. プロジェクト作成~各種設定
2. DocumentRoot変更~Twigを使用
3. LoggingとController
4.PDO使用
5. チケット管理システムを再現➀
6. チケット管理システムを再現➁