Strings of Life

PHP/Phalcon/MySQL/JavaScript/RegExp/Ruby/Perl/ActionScript

JavaScriptではじめるプログラミング入門

とある場所で、プログラミング初心者向けのハンズオンセミナーを開催しました。初心者に教えるというのは、やはり難しい。今回は知識レベルもまちまちで、人によってはHTMLも知らなかったので、スライドには無いけどHTML基礎講座をやったりしました。

また、受講者の方にはあらかじめChromeのインストールをお願いしたのですが、PCにインストールされているソフトウェアの影響で、こちらの想定した動作とは異なる動作をするPCがあったりして、なかなかに悩ましい。

環境構築が簡単なJavaScriptでさえこれなのだから、他の言語は推して知るべし、ですね。

内容としては、結構詳細に(ある程度本気でプログラミングを覚えたい人向けに)説明してしまったのですが、もっとプログラミングの楽しさをダイジェスト的に感じられるような課題だと良かったかな、と思いました。

ちなみに、今回はreveal.jsでスライドを作成し、GitHub Pagesにアップロードして公開しました。reveal.jsは簡単にスライドが作れるし、GitHubにgh-pagesブランチを切ってpushすればGitHub Pagesとして公開できるので、とても楽。この組み合わせは今後も使っていきたいですね。

ここしばらくの間、「Phalconまとめ」シリーズで、Phalconのドキュメントを自分なりに翻訳する試みをやってきました。結果、難易度・作業量の面でいけそうだという感触を得ることができたので、Phalconドキュメントの日本語翻訳チームにJOINしました(Transifexでのアカウント名はryo511です)。

Phalconのドキュメントの翻訳は、以前はGitHubで進められていましたが、現在はTransifexという翻訳サービスに移行しています。

If you want to translate English documentation into your native language, please request join a translation team at Transifex.

https://github.com/phalcon/docs/blob/master/CONTRIBUTING.md
翻訳チームへの参加方法は以下のとおり。
(1) Transifexにアカウントを作成する
(2) Phalconドキュメントのプロジェクトに参加申請をする
(3) 参加申請が受諾されたら、翻訳作業を開始できる

今後はPhalconドキュメントの翻訳作業はTransifexで行うことになるため、このブログにはドキュメントの翻訳は掲載しなくなると思います。

「最速」PHPフレームワークPhalconのモデルについて、基本事項をまとめます(公式ドキュメントの翻訳+αです)。記事執筆時のPhalconのバージョンは1.3.1です。

ビヘイビア

ビヘイビアとは、複数のモデルに共有される振る舞いのことです。PhalconのORマッパーは、モデルでビヘイビアを実装するためのAPIを提供しています。また、イベントとコールバックを使用して、より自由度の高いビヘイビアを実装することもできます。

ビヘイビアは、モデルの初期化処理に加えなければなりません。モデルは複数のビヘイビアをもつことができます。

<?php

use Phalcon\Mvc\Model\Behavior\Timestampable;

class Users extends \Phalcon\Mvc\Model
{
    public $id;

    public $name;

    public $created_at;

    public function initialize()
    {
        $this->addBehavior(new Timestampable(
            array(
                'beforeCreate' => array(
                    'field' => 'created_at',
                    'format' => 'Y-m-d'
                )
            )
        ));
    }

}

フレームワークは、以下の組み込みビヘイビアを提供しています。

名前 説明
Timestampable レコードが作成・更新される際に、自動的にモデルのフィールドを更新する
SoftDelete 永続的な削除(物理削除)の代わりに、削除フラグを付与する(論理削除)

Timestampable

このビヘイビアは、配列をオプションとして受け取ります。最初のキーが、カラムへの代入が行われるイベント名になります。

<?php

public function initialize()
{
    $this->addBehavior(new Timestampable(
        array(
            'beforeCreate' => array(
                'field' => 'created_at',
                'format' => 'Y-m-d'
            )
        )
    ));
}

それぞれのイベントには独自のオプションがあり、fieldは更新されるカラム名になります。formatが文字列なら、PHPのdate()関数の引数として渡されます。formatには無名関数を使うこともでき、お好みの形式でタイムスタンプを作ることができます。

<?php

public function initialize()
{
    $this->addBehavior(new Timestampable(
        array(
            'beforeCreate' => array(
                'field' => 'created_at',
                'format' => function() {
                    $datetime = new Datetime(new DateTimeZone('Europe/Stockholm'));
                    return $datetime->format('Y-m-d H:i:sP');
                }
            )
        )
    ));
}

formatがオプションの配列に含まれない場合は、タイムスタンプはPHPのtime()関数を使用し、タイムスタンプの数値が代入されます。

SoftDelete

このビヘイビアは、以下のように使います。

<?php

use Phalcon\Mvc\Model\Behavior\SoftDelete;

class Users extends \Phalcon\Mvc\Model
{

    const DELETED = 'D';

    const NOT_DELETED = 'N';

    public $id;

    public $name;

    public $status;

    public function initialize()
    {
        $this->addBehavior(new SoftDelete(
            array(
                'field' => 'status',
                'value' => Users::DELETED
            )
        ));
    }

}

このビヘイビアは、2つのオプションを受け取ります。fieldは更新されるフィールド名を、valueは削除フラグの値を指定します。以下のようなデータをもつusersテーブルについて考えてみます。

mysql> select * from users;
+----+---------+--------+
| id | name    | status |
+----+---------+--------+
|  1 | Lana    | N      |
|  2 | Brandon | N      |
+----+---------+--------+
2 rows in set (0.00 sec)

もし、いずれかのレコードを削除したら、レコードが削除される代わりに、statusが更新されます。

<?php

Users::findFirst(2)->delete();

上記コードが実行されると、テーブルの中のデータは以下のようになります。

mysql> select * from users;
+----+---------+--------+
| id | name    | status |
+----+---------+--------+
|  1 | Lana    | N      |
|  2 | Brandon | D      |
+----+---------+--------+
2 rows in set (0.01 sec)

削除済みか否かのフラグをクエリで明示的に指定してやる必要がある点に注意してください。テーブルが上の状態の時、以下のコードを実行すると、削除されたはずのBrandonも取得されてしまいます。

$users = Users::find();

論理削除済みのレコードを除外するには、以下のようにします。

$users = Users::find('deleted = ' . Users::NOT_DELETED);

独自のビヘイビアを作る

ORマッパーは、独自のビヘイビアのためのAPIを提供しています。ビヘイビアは、Phalcon\Mvc\Model\BehaviorInterfaceを実装したクラスでなければなりません。また、Phacon\Mvc\Model\Behaviorが、ビヘイビアの実装に必要なほとんどのメソッドを提供しています。

以下のビヘイビアは、1つの実装例です。Blamableビヘイビアは、ユーザーがモデルに行った操作を特定します。

<?php

use Phalcon\Mvc\Model\Behavior;
use Phalcon\Mvc\Model\BehaviorInterface;

class Blameable extends Behavior implements BehaviorInterface
{

    public function notify($eventType, $model)
    {
        switch ($eventType) {

            case 'afterCreate':
            case 'afterDelete':
            case 'afterUpdate':

                // セッションからユーザー名取得
                $userName = $this->getDI()->get('session')->get('userName');

                // ユーザー名・イベント種別・主キーをログに記録
                file_put_contents(
                    'logs/blamable-log.txt',
                    $userName . ' ' . $eventType . ' ' . $model->id
                );

                break;

            default:
                /* 他のイベントは無視する */
        }
    }

}

次に、このビヘイビアをモデルに追加してみます。

<?php

class Profiles extends \Phalcon\Mvc\Model
{

    public function initialize()
    {
        $this->addBehavior(new Blamable());
    }

}

ビヘイビアは、不明なメソッド呼び出しに対して割り込みができます。

<?php

use Phalcon\Mvc\Model\Behavior,
    Phalcon\Mvc\Model\BehaviorInterface;

class Sluggable extends Behavior implements BehaviorInterface
{

    public function missingMethod($model, $method, $arguments=array())
    {
        // 「getSlug」メソッドが呼ばれたら、titleを変換する
        if ($method == 'getSlug') {
            return Phalcon\Tag::friendlyTitle($model->title);
        }
    }

}

Sluggableを実装しているモデルにgetSlug()メソッドの呼び出しを行うと、SEO対策のされたtitleが返ります。

<?php

$title = $post->getSlug();

トレイトをビヘイビアとして使う

PHP5.4以降では、トレイトを使うことでクラスのコードの再利用ができます。この機能を使って、独自のビヘイビアを実装することもできます。以下のトレイトは、TimeStampableビヘイビアのシンプルな実装例です。

<?php

trait MyTimestampable
{

    public function beforeCreate()
    {
        $this->created_at = date('r');
    }

    public function beforeUpdate()
    {
        $this->updated_at = date('r');
    }

}

モデルでは、以下のようにして利用します。

<?php

class Products extends \Phalcon\Mvc\Model
{
    use MyTimestampable;
}

今回はここまで

今回は、Phalconのモデルで利用可能なビヘイビアについて紹介しました。次回は、Transactionsから先をみていきます。

このページのトップヘ