iMind Developers Blog

iMind開発者ブログ

PHPでTwigとDoctrineを利用してWebサイトを作る

概要

HTMLがある程度書けてPHP/JavaScriptも少しわかるという人がメンテするシステムがあったとする。生のPHPで書かれていてHTMLとロジックがかなり入り混じっている。

これを破綻させないように程よく改修する必要が出た場合、フレームワークを使うと担当者が改修後のコードをメンテできるか心もとない。しかし生のPHPのみで開発を進めるのは破綻が見えている。

ということで妥協案としてテンプレートとORMだけでもということで、TwigとDoctrineを個別に導入しみる。

バージョン情報

  • PHP 7.2.19
  • Composer version 1.9.0
  • twig/twig v2.11.3
  • doctrine/orm v2.6.4

インストール

twigとdoctrineを入れる。

Webサーバー、PHP、composerの導入は事前に済んでいるものとする。

$ composer require "twig/twig"
$ composer require "doctrine/orm"

フォルダ構成

今回のサンプルコードは /var/www/htmlがdocument rootになっている場合に下記のようなフォルダ階層になっているものとする。

└── www
    ├── html
    │   └── example.php
    ├── vendor
    └── templates
        └── example.html

Twigの使い方

Twigでtemplateを呼び出すだけの処理を書いてみる。

html/example.php に下記を記述する。

<?php
require_once '../vendor/autoload.php';

# twigの初期化
$loader = new \Twig\Loader\FilesystemLoader('../templates');
$twig = new \Twig\Environment($loader);

# example.htmlというテンプレートにパラメータを渡して呼び出す
echo $twig->render('example.html', ['name' => 'watanabe']);

templates/example.html に下記を記述する。

<!DOCTYPE html>
<html>
<body>
    <p>your name : {{ name }}
</body>
</html>

/example.php を開くと your name : watanabe と表示される。

これで最低限、Viewとロジックの分離はできる。

doctrineの使い方

例としてMySQLに接続してSELECTしてみる。

<?php
// 接続情報
$config = new \Doctrine\DBAL\Configuration();
$connectionParams = array(
    'dbname' => 'database',
    'user' => 'user',
    'password' => 'password',
    'host' => 'localhost',
    'port' => 3306,
    'charset' => 'utf8',
    'driver' => 'pdo_mysql',
);

// 接続
$conn = \Doctrine\DBAL\DriverManager::getConnection($connectionParams, $config);

// usersテーブルというテーブルがあったとして検索する
$result = $conn->fetchAll(
    'select * from users'
);
var_dump($result);

doctrineでQueryBuilderを使う

複雑な条件のSQLを書く必要が出た時の為に、QueryBuilderの使い方についても用意しておく。

下記はid, name, passwordの3カラムを持つusersというテーブルがあった場合の想定。

<?php
$qb = $conn->createQueryBuilder();
$result = $conn->createQueryBuilder()
    ->select('id, name')
    ->from('users')
    ->where('id=:id')
    ->setParameter('id', 'root')
    ->andWhere('password=:password')
    ->setParameter('id', 'root')
    ->setParameter('password', 'password')
    ->execute()
    ->fetchAll();

// SQLの実行結果
var_dump($result);
    //=> array(1) { [0]=> array(5) { ["id"]=> string(4) "root" ["password"]=> string(8) "password" ["name"]=> string(4) "user"

// 生成されたクエリ
var_dump($qb->getSql());
    //=> SELECT * FROM users WHERE (id=:id) AND (password=:password)

// 渡したパラメータ
var_dump($qb->getParameters());
    //=> array(2) { ["id"]=> string(4) "root" ["password"]=> string(8) "password" }

postされた値によって動的にクエリを生成したい場合。

<?php
$qb = $conn->createQueryBuilder()
    ->select('id, name')
    ->from('users');

// $_POSTに指定のパラメータがいた時だけ条件を追加する
if($_POST['userid']) {
    $qb->andWhere('id=:id')
        ->setParameter('id', $_POST['userid']);
}
if($_POST['password']) {
    $qb->andWhere('password=:password')
        ->setParameter('password', $_POST['password']);
}

$result = $qb->execute()
    ->fetchAll();

INSERT

<?php
// 新しくfooというidのユーザーを追加する
$qb = $conn->createQueryBuilder()
    ->insert('users')
    ->setValue('id', ':id')
    ->setValue('password', ':password')
    ->setValue('name', ':name')
    ->setParameter(':id', 'foo')
    ->setParameter(':password', 'bar')
    ->setParameter(':name', 'baz');

$result = $qb->execute();

UPDATE

<?php
$qb = $conn->createQueryBuilder()
    ->update('users')
    ->set('name', ':name')
    ->where('id=:id')
    ->setParameter('name', 'bazbaz')
    ->setParameter('id', 'foo');

$result = $qb->execute();

DELETE

<?php
$qb = $conn->createQueryBuilder()
    ->delete('companies')
    ->where('id=:id')
    ->setParameter('id', 'foo');

改定履歴

Author: Masato Watanabe, Date: 2019-10-12, 記事投稿