CodeIgniter 3.0でマイグレーションをCLIから操作するCli for CodeIgniter

マイグレーションとは、簡単に言うとデータベースのテーブル定義をコードによりバージョン管理する仕組みです。CodeIgniterにも2.1.0からMigrationクラスが標準で含まれています。

日本語の情報としては、以下がCodeIgniter 2.xのものですが詳しいです。

CodeIgniter 3.0では、マイグレーションファイルのバージョンのデフォルトが「3桁の数字」ではなく「タイムスタンプ(YYYYMMDDHHMMSS)」に変更されていますが、他は同じだと思います。

ここで、CodeIgniterでは、マイグレーションファイルは手動で作成する必要があります。そうなると、20150507043122_Create_bbs.phpみたいなファイル名を自分で入力して作成しないといけません。

また、マイグレーションの状態がどうなっているか確認する方法もデフォルトではありません(そもそもマイグレーションを実行するためのスクリプトも標準ではなく、サンプルコードがユーザガイドに掲載されているだけなんですが)。

ということで、ちょっと面倒な感じなので、コマンドラインからマイグレーションを操作できるようにしてみました。

そのためにコマンドライン(CLI)からコマンドを実行する仕組みとして「Cli for CodeIgniter」を作成しました。

Cli for CodeIgniterのインストール

Cli for CodeIgniter(以下、codeigniter-cli)は、CodeIgniterのプロジェクトの中にComposerでインストールします。PHP 5.4以上が必要です。

CodeIgniterのフォルダ構成

デフォルトでは、CodeIgniterのプロジェクトは以下のフォルダ構成が想定されています。異なる場合はcodeigniter-cliの設定を変更します(後述)。

codeigniter/
├── application/
├── composer.json
├── composer.lock
├── public/
│   └── index.php
└── vendor/
    └── codeigniter/
        └── framework/
            └── system/

CodeIgniterのインストールがまだの場合は、以下でインストールできます。詳細は、「Codeigniter 3.0をコマンド一発でインストールするCodeIgniter Composer Installer」を参照してください。

$ composer create-project kenjis/codeigniter-composer-installer codeigniter

codeigniter-cliのインストール

CodeIgniterのプロジェクトのルートフォルダに移動して、codeigniter-cliをインストールします。

$ cd codeigniter/
$ composer require kenjis/codeigniter-cli:1.0.x@dev --dev

codeigniter-cliのコマンドファイルと設定フォルダなどをCodeIgniterのプロジェクトにコピーします。

$ php vendor/kenjis/codeigniter-cli/install.php

以下のようにインストールされます。上記のコマンドは以下のファイルがすでに存在する場合はファイルを上書きします。

codeigniter/
├── application/
├── ci_instance.php ... CodeIgniterインスタンス生成用のスクリプト
├── cli             ... コマンドファイル
├── config/         ... 設定フォルダ
└── vendor/

codeigniter-cliの設定

フォルダ構成が想定される場合と異なるときは、ci_instance.phpの以下のパスを変更します。

$system_path        = 'vendor/codeigniter/framework/system';
$application_folder = 'application';
$doc_root           = 'public';

これでインストールは完了です。

cliコマンドの使い方

$ ./cli

または、

$ php cli

でコマンドの一覧が表示されます。

データベースマイグレーション

それでは、データベースマイグレーションを使ってみましょう。

その前に、CodeIgniterのデータベース接続の設定を済ませてください。

マイグレーションの設定

マイグレーション設定ファイル(config/migration.php)を変更します。

マイグレーションを使用するのでmigration_enabledTRUEに変更します。

それから、マイグレーションファイルを配置するフォルダmigration_pathAPPPATH.'database/migrations/'に変更します。migration_pathは好みの問題なのでデフォルトのままでも構いません。

--- a/application/config/migration.php
+++ b/application/config/migration.php
@@ -11,7 +11,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
 | and disable it back when you're done.
 |
 */
-$config['migration_enabled'] = FALSE;
+$config['migration_enabled'] = TRUE;

 /*
 |--------------------------------------------------------------------------
@@ -81,4 +81,4 @@ $config['migration_version'] = 0;
 | Also, writing permission is required within the migrations path.
 |
 */
-$config['migration_path'] = APPPATH.'migrations/';
+$config['migration_path'] = APPPATH.'database/migrations/';

そして、migration_pathに設定されているフォルダを作成してください。

bash-3.2$ mkdir -p application/database/migrations

では、マイグレーションの現状をcli migrate versionコマンドで確認してみましょう。

bash-3.2$ ./cli migrate version

以下のように3つのバージョンが表示されました。

 current: 0 (in config/migration.php)
database: 0 (in database table)
  latest: null (in migration files)

ここで

  • currentはマイグレーション設定ファイルに記載されているバージョン
  • databaseはデータベースに記録されているバージョン(データベースはこのバージョンまでマイグレーションされている)
  • latestはマイグレーションファイルの中の最新バージョン

です。

初期状態なので0やnullが表示されています。

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

マイグレーションファイルとは、データベースへの変更操作を記録するクラスです。

例としてbbsテーブルを作成するマイグレーションファイルをcli generate migrationコマンドで作成してみましょう。最後の引数はクラス名になります。

bash-3.2$ ./cli generate migration Create_bbs

以下のように表示されました。

Generated: application/database/migrations/20150507043122_Create_bbs.php

20150507043122_Create_bbs.phpが作成されたことがわかります。20150507043122がマイグレーションのバージョンです。

中身は以下のようになっています。

<?php
/**
 * Migration: Create_bbs
 *
 * Created by: Cli for CodeIgniter <https://github.com/kenjis/codeigniter-cli>
 * Created on: 2015/05/07 04:31:22
 */
class Migration_Create_bbs extends CI_Migration {

    public function up()
    {
//      $this->dbforge->add_field(array(
//          'blog_id' => array(
//              'type' => 'INT',
//              'constraint' => 11,
//              'auto_increment' => TRUE
//          ),
//          'blog_title' => array(
//              'type' => 'VARCHAR',
//              'constraint' => 100,
//          ),
//          'blog_description' => array(
//              'type' => 'TEXT',
//              'null' => TRUE,
//          ),
//      ));
//      $this->dbforge->add_key('blog_id', TRUE);
//      $this->dbforge->create_table('blog');
    }

    public function down()
    {
//      $this->dbforge->drop_table('blog');
    }

}

ここで、

  • up()メソッドにこのマイグレーションが実行されたときに実行するコード
  • down()メソッドに前のバージョンに戻す場合に実行するコード

を記載します。例えば、以下のようになります。

<?php
/**
 * Migration: Create_bbs
 *
 * Created by: Cli for CodeIgniter <https://github.com/kenjis/codeigniter-cli>
 * Created on: 2015/05/07 04:31:22
 */
class Migration_Create_bbs extends CI_Migration {

    public function up()
    {
        $this->dbforge->add_field(array(
            'id' => array(
                'type' => 'INT',
                'constraint' => 11,
                'auto_increment' => TRUE
            ),
            'name' => array(
                'type' => 'VARCHAR',
                'constraint' => '64',
            ),
            'subject' => array(
                'type' => 'VARCHAR',
                'constraint' => '128',
                'null' => TRUE,
            ),
            'body' => array(
                'type' => 'TEXT',
                'null' => TRUE,
            )
        ));

        $this->dbforge->add_key('id', TRUE);
        $this->dbforge->create_table('bbs');
    }

    public function down()
    {
        $this->dbforge->drop_table('bbs');
    }

}

さて、ここでcli migrate versionでバージョンを確認してみましょう。

bash-3.2$ ./cli migrate version
 current: 0 (in config/migration.php)
database: 0 (in database table)
  latest: 20150507043122 (in migration files)

latest(マイグレーションファイルの最新バージョン)が変わりました。

マイグレーションの実行

マイグレーションの実行は、設定ファイルにあるバージョンまでデータベースのバージョンを上げるというものです。

なので、まず、マイグレーション設定ファイル(config/migration.php)のmigration_versionを最新のマイグレーションファイルのバージョン(20150507043122)に変更します。

--- a/application/config/migration.php
+++ b/application/config/migration.php
@@ -69,7 +69,7 @@ $config['migration_auto_latest'] = FALSE;
 | be upgraded / downgraded to.
 |
 */
-$config['migration_version'] = 0;
+$config['migration_version'] = 20150507043122;

 /*
 |--------------------------------------------------------------------------

そして、マイグレーションを実行します。

bash-3.2$ ./cli migrate 
 current: 20150507043122 (in config/migration.php)
database: 20150507043122 (in database table)
  latest: 20150507043122 (in migration files)

すべてのバージョンが一致して最新になりました。

データベースの中身を確認してみましょう。

bash-3.2$ sqlite3 application/sqlite-database.db 
SQLite version 3.8.5 2014-08-15 22:37:57
Enter ".help" for usage hints.

sqlite> .schema bbs
CREATE TABLE "bbs" (
        "id" INTEGER PRIMARY KEY AUTOINCREMENT,
        "name" VARCHAR NOT NULL,
        "subject" VARCHAR NULL,
        "body" TEXT NULL
);

sqlite> select * from migrations;
20150507043122

テーブルbbsが作成され、マイグレーションのバージョンが最新になっていることがわかります。

マイグレーションファイルの一覧表示

以下のようにマイグレーションファイルを追加したとします。

bash-3.2$ ./cli generate migration Create_captcha
bash-3.2$ ./cli generate migration Create_category
bash-3.2$ ./cli generate migration Create_product

ここで、cli migrate statusコマンドを実行します。

bash-3.2$ ./cli migrate status

すると、以下のようにマイグレーションファイルの一覧が表示されます。

application/database/migrations/
  20150507043122_Create_bbs.php (current/database)
  20150507060215_Create_captcha.php
  20150507060219_Create_category.php
  20150507060223_Create_product.php

データベースの状態はバージョン20150507043122であり、実行されていないマイグレーションがあることがわかります。

codeigniter-cliについて

codeigniter-cliはそもそもCodeIgniter 3.0のためのCLIツールです。コマンドを作成するための仕組みです。ユーザがコマンドを作成することもできます。

また、マイグレーション以外にも

  • データベースシーディングのためのseedコマンド
  • コントローラを実行するrunコマンド

が付属しています。

Scrutinizerのスコアは9以上(very good)、テストも書かれておりテストカバー率は90%以上です。

興味のある方は、以下を参照してください。

関連

Tags: codeigniter, database

CodeIgniter 3.0をコマンド一発でインストールするCodeIgniter Composer Installer

CodeIgniter 3.0がMITライセンスでリリースされたわけですが、公式なインストール方法はZipファイルをダウンロードするというものです。初心者にやさしいCodeIgniterなので、これで動かせるのは理にかなっています。

しかし、日頃からComposerに慣れているPHPユーザには、Composerでフレームワーク(CodeIgniter)のバージョンアップができた方がいいです。

以下の記事に、そのようにComposerでフレームワークを管理する方法がありました。

これでいいのですが、できればコマンド一発でインストールしたいです。

というわけで、コマンド一発でインストールできるパッケージを作りました。

CodeIgniter Composer Installer

CodeIgniterのインストール

composerがインストール済みの環境で、以下のコマンドだけで最新のCodeIgniterがインストールできます。

$ composer create-project kenjis/codeigniter-composer-installer codeigniter

上記のコマンドは、

  1. プロジェクトのフォルダを作成し、CodeIgniterをComposerでvendorフォルダ以下にインストール
  2. applicationフォルダをプロジェクトのトップにコピー
  3. index.phppublic/index.phpにコピー
  4. フォルダのパスの調整とcomposer_autoloadの設定

をします。

インストールするCodeIgniterは本家の`master`ブランチです。本当はバージョンを指定しようと思ったのですが、Packagistの`codeignter/framework`に何故か`3.0.0`がなかったので、`dev-master`にしてます。

インストールするCodeIgniterは本家の3.0.*です(codeigniter-composer-installer v0.1.2以降)。

フォルダ構成は以下のようになります。

codeigniter/
├── application/
├── composer.json
├── composer.lock
├── public/
│   └── index.php
└── vendor/
    └── codeigniter/
        └── framework/
            └── system/

言語ファイルのインストール

(2015-06-06 更新) (2015-04-30 追記)

日本語の言語ファイルをインストールします。

$ cd /path/to/codeigniter
$ php bin/install.php translations develop

これでapplication/language

developブランチの言語ファイルがコピーされました。

他にもサードパーティ製のライブラリをインストールするスクリプトも少し付属しています。詳細は、

を参照してください。

CodeIgniterのバージョンアップ

CodeIgniterのバージョンが上がっても、以下のコマンドで更新できます。

$ cd /path/to/codeigniter
$ composer update

ただし、もし、applicationフォルダ内のファイルやindex.phpが変更された場合は、それらを手動で更新する必要はあります。その場合は、ユーザガイドに従って作業してください。

systemフォルダ以下は完全に更新されますので、systemフォルダ以下のファイルを直接変更することは禁止してください。バージョンアップ時に消えてなくなります。

関連

Tags: codeigniter

昨日のPHPでFizzBuzzの解説

PHPでFizzBuzzを書いてみました」について、以下のようなツイートがありました。

個人的には、まだリーダブルなコードだと思っていましたが、少々トリッキーなコードであることは否めません。

確かに、検索しづらいので、一応、解説を書いておくことにします。

ちなみに、「PHP FizzBuzz」でぐぐると、以下のコードが出てきましたが、正直読めませんでした(w

最短のFizzBuzz

<?while($i++<100)echo[Fizz][$i%3].[Buzz][$i%5]?:$i,"
";

上記のコードですが、これをPHP 5.3でも動くように、そして、読みやすく書けば、以下のようになります。

<?php

$a1 = array(Fizz);
$a2 = array(Buzz);

while ($i++<100) {
    echo $a1[$i%3] . $a2[$i%5] ?: $i, "
";
}

ここで配列の要素FizzBuzzは未定義の定数です。未定義の定数があるとPHPでは以下のNoticeが発生します。

Notice: Use of undefined constant Fizz - assumed 'Fizz'

そこに表示されていますが、結局、文字列として解釈されます。

$i%3$iを3で割った余りなので、0の場合のみ配列の要素が存在し、文字列が表示されます。

要素が存在しない場合は、以下のようなNoticeが発生します。

Notice: Undefined index: 1

そして、もともとのコードの

[Fizz][$i%3]

は、PHP 5.4で導入された配列の短縮構文([])と、PHP 5.5で導入された配列リテラルのデリファレンスです。

配列を書いてそのままその要素にアクセスしています。

Tags: php