Help us understand the problem. What is going on with this article?

Slim(PHP Framework)事始め(3)

More than 3 years have passed since last update.

あらまし

配属先で[Slim]を使っているので、使い方などをメモしている。
前回

Whoops補足

前回、Whoopsの導入で、dopesong/Slim-Whoopsを導入してデバッグバー(kitchenu/Slim-Debugbar)を導入する際に

12    // ob_start以降のエラーをハンドルする
13    $container['phpErrorHandler']/* = $container['errorHandler']*/ = function($c) {
14        return new Dopesong\Slim\Error\Whoops($c->get('settings')['displayErrorDetails']);
15    };

のようにerrorHandlerをコメントアウトしていたのは、デバッグバーの受け取るエラーが合わない為でした
なので、vendor以下を修正する事になってしまいますが、

vendor/dopesong/slim-whoops/src/Whoops.php
...
 24 class Whoops extends \Slim\Handlers\Error // デバッグバー側で受け取るエラーを継承させる
 25 {
...
118    protected function determineContentType(ServerRequestInterface $request)
119    {// Slim\Handlers\Error::determineContentTypeのアクセス修飾子に合わせる
...

のようにするとコメントを外しても動作します

Phpmig導入

マイグレーションツールとして、Phpmigを導入してみます
マイグレーションツールとしては、Phinxも有名ですが、少しいじってみた感じとして、データベースにマイグレーションの情報が書き込まれるのがどうだろうな、と思ったりした為です
ちなみに、Phpmigですと、マイグレーション情報として初期化したディレクトリ内に、.migrations.logというファイルが作られて、その中に情報が書き込まれます

インストール

$ composer require davedevelopment/phpmig

マイグレーション用ディレクトリ作成

$ mkdir data

デフォルトだとプロジェクトルートにmigrationsというフォルダを作成してその中に色々作られますが、フィクスチャなど関連したデータをまとめたかったので、data/というディレクトリを作成しました

コマンドライン用に登録

composer.json
...
    "scripts": {
...
            "phpmig": "cd data && phpmig"
...
    }
...

初期化

$ composer phpmig init

data/phpmig.phpが出来るので、それを色々修正して、自分のシステムに合わせるようにします

data/phpmig.php
<?php

use \Phpmig\Adapter;

// get environment variables from phpdotenv
$dotenv = new Dotenv\Dotenv(__DIR__. '/../');
$dotenv->load();
// disable web debug tools
putenv('DEBUG=0');

$settings = require __DIR__ . '/../src/settings.php';

// we shold not need Slim\App, but want container...
$app = new Slim\App($settings);

require __DIR__ . '/../src/dependencies.php';

$container = $app->getContainer();

// replace this with a better Phpmig\Adapter\AdapterInterface
$container['phpmig.adapter'] = new Adapter\File\Flat(__DIR__ . DIRECTORY_SEPARATOR . 'migrations/.migrations.log');
...

こんな感じに書き換えて、slim側の設定を読み込むようにします

マイグレーションファイル作成

$ composer phpmig generate AddTableTest
> cd data && phpmig 'generate' 'AddTableTest'
+f ./migrations/20161112055904_AddTableTest.php

まだデータベースとの接続などを導入していないのでここまでです

Idiorm & Paris導入

データベースアクセスに何を使おうか?とここしばらく考えていましたが、軽量と聞いていたIdiorm & Parisを導入してみます
IdiormがORM、ParisがActiveRecordのようです

$ composer require j4mie/idiorm j4mie/paris

データベース設定

.env
# database settings
DB_PHPMIG1_DSN = mysql:host=localhost;dbname=phpmig1
DB_PHPMIG1_USER = root
DB_PHPMIG1_PASS = 

DB_PHPMIG2_DSN = mysql:host=localhost;dbname=phpmig2
DB_PHPMIG2_USER = root
DB_PHPMIG2_PASS = 
src/settings.php
<?php
return [
    'settings' => [
...
        // database settings
        'db' => [
            'phpmig1' => [
                'dsn'  => getenv('DB_PHPMIG1_DSN'),
                'user' => getenv('DB_PHPMIG1_USER'),
                'pass' => getenv('DB_PHPMIG1_PASS'),
            ],
            'phpmig2' => [
                'dsn'  => getenv('DB_PHPMIG2_DSN'),
                'user' => getenv('DB_PHPMIG2_USER'),
                'pass' => getenv('DB_PHPMIG2_PASS'),
            ],
        ],
    ],
];

職業柄か、複数DBを使用する事が多いので、2台設定しています

src/dependencies.php
...
$container = $app->getContainer();

if ($container->get('settings')['debug']) {
...
    // debugbar setting
    $settings = $container->get('settings')['debugbar'];
    $provider = new Kitchenu\Debugbar\ServiceProvider($settings);
    $provider->register($app);

    // デバッグバーに、データベース項目を追加する
    ORM::configure('logging', true);
    $collector = new DebugBar\DataCollector\PDO\PDOCollector();
    $container['debugbar']->addCollector($collector);
}
...
// databases
foreach ($container->get('settings')['db'] as $dbname => $settings) {
    // idiorm settings
    ORM::configure([
        'connection_string' => $settings['dsn'],
        'username' => $settings['user'],
        'pass' => $settings['pass'],
    ], null, $dbname);
    // デバッグ時には、デバッグバーに、コネクションを登録する
    if ($container->get('settings')['debug']) {
        $pdo = ORM::get_db($dbname);
        $debugbar = $container['debugbar'];
        $collector = $debugbar->getCollector('pdo');

        $source = new DebugBar\DataCollector\PDO\TraceablePDO($pdo);
        $collector->addConnection($source, $dbname);
    }
    // コンテナからもコネクションを取得出来るように設定
    $container["db.$dbname"] = function($c) use ($dbname) {
        return ORM::get_db($dbname);
    };
}

\$container["db.\$dbname"]としている為に、\$container->db.\$dbnameという取得の仕方が出来ません
あまりコンテナから取得する事は無いだろう、という事と、表記的に、db以下にコネクションをまとめたい、という事からこんな事をしていますが、取得したい場合は
\$container->get("db.\$dbname")という感じで取得出来ます

マイグレーションファイル設定

上の、マイグレーションファイル作成で生成されたファイルを編集します

migrations/20161112055904_AddTableTest.php
<?php

use Phpmig\Migration\Migration;

class AddTestTable extends Migration
{
    /**
     * Do the migration
     */
    public function up()
    {
        $this->get('db.phpmig1')->exec("
            CREATE TABLE `test1` (
              `id` int(11) NOT NULL AUTO_INCREMENT,
              `name` varchar(32) NOT NULL,
              `value` int(11) NOT NULL,
              `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
              PRIMARY KEY (`id`)
            )
        ");
        $this->get('db.phpmig2')->exec("
            CREATE TABLE `test2` (
              `id` int(11) NOT NULL AUTO_INCREMENT,
              `name` varchar(32) NOT NULL,
              `value` int(11) NOT NULL,
              `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
              PRIMARY KEY (`id`)
            )
        ");
    }

    /**
     * Undo the migration
     */
    public function down()
    {
        $this->get('db.phpmig1')->exec("DROP TABLE `test1`");
        $this->get('db.phpmig2')->exec("DROP TABLE `test2`");
    }
}

マイグレーション適用

$ composer phpmig migrate
> cd data && phpmig 'migrate'
 == 20161112055904 AddTableTest migrating
 == 20161112055904 AddTableTest migrated 0.0169s

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

data/migrations/.migrations.log
20161112055904

適用されたマイグレーションの番号が書き込まれて行きます

ロールバック

$ composer phpmig rollback
> cd data && phpmig 'rollback'
 == 20161112055904 AddTableFoo reverting
 == 20161112055904 AddTableFoo reverted 0.0222s

これで、直近のマイグレーションが取り消されて、テーブルが削除されます

感想

Whoopsの件は、修正をプルリクしておくべきなのかもしれませんが、そもそも今回使用してみたデバッグバー側でエラーを補足しなければ問題無かったはず(エラーしたらWhoopsが捕捉して表示するのでデバッグバー側で処理する必要が無い)なので、どのように修正するのか難しいところです

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした