PhalconのModelをWordPressと統合しデータベースと密接に連携したサーバサイドバリデーションを行う
WordPressのデータ検証を強化
WordPressを利用してフォームを開発している際に以下の点に気付いた。
新規テーブルのサーバサイドバリデーション
新規フォームで新規のデータベーステーブルにデータを保存する際のサーバサイドバリデーション機能が無い
という点。
WordPressが標準で管理しているデータについては、WordPressの機能を使ってデータを管理するのが効率的であるが、一歩ワードプレスの外に出ると、途端に思考停止に陥ってしまった。
WordPressのデータ検証機能については以下のCodexで調べることが出来る。
文字列のエスケープ処理やメールアドレスの書式が適切かどうかといったデータ検証機能は備えているものの、データベースと密に連携したデータ検証機能は、開発者が別途コーディングする必要がある。
例えば、フィールド内のデータとフォームのデータに重複が無いか確認したい場合が該当する。また、バリデーション結果のエラーメッセージの管理という作業が発生する。
この部分の領域(MVCのModel)は、WordPressよりもサーバサイドMVCフレームワークの方が機能が充実しているため、WordPressとModelの連携を考えてみた。
ぱっと思いついたのはCakePHPのModelを利用できないかどうか?
MVCフレームワークで最も詳しく知っているのがCakePHPなので、WordPressからうまくCakePHPのModelを使う方法を検討してみた。CakePHPのファイルの配置方法などを模索していた際に、もっといいMVCフレームワークがあることに気付いた。
PhalconPHP
という便利なフレームワークがあることを思い出した。
Phalconは最速PHPフレームワークとして人気のあるサーバサイドフレームワークで、Webエンジニアブログでも何度か記事にしたことがある。インストールの方法なども記事にしてあるので、
を参考にして頂きたい。
Phalconでは、インストール作業としてPHPの拡張モジュールを設定することになり、
ファイルを展開する作業が無い
という特徴がある。
CakePHP2のようにフルスタックなファイル一式を展開するのではなく、必要なモジュールを開発者が選択してアプリケーションを構築していく開発スタイルになっている。
そのため、
Phalconをサーバにインストールすれば、WordPressからPhalconのModelを利用可能
ということになる。
理論的に可能と判断できたので実践することにした。
wp-config.phpでPhalconオブジェクトを作成
最初にWordPress全体でPhalconを利用可能な状態にする。そのためには、WordPressのinitファイル的な存在である
wp-config.php
でPhalconオブジェクトを生成する。
// Phalconを呼び出してmodelのパスを設定 $loader = new \Phalcon\Loader(); $loader->registerDirs(array( __DIR__ . '/models/' ))->register(); // データベースの接続情報を設定 $di = new \Phalcon\DI\FactoryDefault(); $di->set('db', function(){ return new \Phalcon\Db\Adapter\Pdo\Mysql(array( "host" => "localhost", "username" => "engineer", "password" => "pass", "dbname" => "wp392ja" )); }); // Phalconオブジェクト生成 $phalcon = new Phalcon\Mvc\Micro($di);
ここまでの作業でPhalconオブジェクトが生成された。$phalconは、WordPressのfunctions.phpから呼び出して利用することが出来る。つまり、Model機能が使えるようになった。
functions.phpでデータベースを操作するコードが書く前にModelを配置するパスの作成とModelのコーディング作業をやっておく必要がある。
PhalconのModel on WordPress
modelsディレクトリを
WordPressのルート
に配置する。配置例は下の画像のとおりです。
modelsフォルダ内に
mailmagazines.php
というファイルを作成しコーディングします。
use Phalcon\Mvc\Model, Phalcon\Mvc\Model\Message, Phalcon\Mvc\Model\Validator\PresenceOf, Phalcon\Mvc\Model\Validator\email, Phalcon\Mvc\Model\Validator\InclusionIn, Phalcon\Mvc\Model\Validator\Uniqueness; class mailmagazines extends Model { public function validation() { // email必須 $this->validate(new PresenceOf( array( "field" => "email", 'message' => 'The email is required' ) )); // メールの書式チェック $this->validate(new email( array( "field" => "email", 'message' => 'The e-mail is not valid' ) )); // すでに同じメールアドレスが無いか $this->validate(new Uniqueness( array( "field" => "email", "message" => "The email must be unique" ) )); // statusは0か1以外NG $this->validate(new InclusionIn( array( "field" => "status", "domain" => array("0", "1") ) )); } }
mailmagazinesモデルが出来上がりました。
- 必須入力チェック
- メールの書式チェック
- メールの重複チェック
- status値が0,1以外はNG
4つのバリデーション機能と検証結果がエラーだった場合に返すエラーメッセージをコーディングしました。
mailmagazinesモデルに対応するテーブル
mailmagazinesモデルは、mysqlのmailmagazinesテーブルに対応しています。
CREATE TABLE IF NOT EXISTS `mailmagazines` ( `id` int(11) NOT NULL AUTO_INCREMENT, `email` varchar(512) NOT NULL, `status` int(1) NOT NULL, `date` datetime NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
mailmagazinesテーブルの構造は上のSQLで設定できます。
functions.phpからデータをinsert
PhalconのModel経由でデータをセットする準備が整ったので、WordPressのfunctions.phpからPhalconオブジェクトを使ってみます。
function wp_uses_phalcon_model() { // wp-config.phpで生成したphalconオブジェクトを利用する global $phalcon; // Phalcon形式のSQL $phql = "INSERT INTO Mailmagazines (email, status, date) VALUES (:email:, :status:, :date:)"; // SQL実行 $status = $phalcon->modelsManager->executeQuery($phql, array( 'email' => 'web@engineer.local', 'status' => '1', 'date' => current_time('mysql', 1) )); // バリデーションの結果で条件分岐 if ($status->success() == true) { } else { // バリデーションNGの場合はエラー配列を作成 foreach ($status->getMessages() as $message) { $errors[] = $message->getMessage(); } } echo "<pre>"; echo "検証結果\n"; var_dump($status->success()); echo "</pre>"; echo "<pre>"; echo "エラーメッセージ\n"; var_dump($errors); echo "</pre>"; } add_filter('the_content', 'wp_uses_phalcon_model');
the_contentフィルターにPhalconのModel経由でSQLを実行するコードをフックしてあるので、適当な記事ページを表示すれば、データの挿入と検証結果がpreタグで表示されます。
操作例
正常値
$status = $phalcon->modelsManager->executeQuery($phql, array( 'email' => 'web@engineer.local', 'status' => '1', 'date' => current_time('mysql', 1) ));
異常値 エラー1つ
$status = $phalcon->modelsManager->executeQuery($phql, array( 'email' => 'webengineer', 'status' => '1', 'date' => current_time('mysql', 1) ));
異常値 エラー2つ
$status = $phalcon->modelsManager->executeQuery($phql, array( 'email' => 'webengineer', 'status' => '2', 'date' => current_time('mysql', 1) ));
Phalconの組み込みValidator
magazinesモデルでは以下のvalidatorを利用したが、
- PresenceOf
- InclusionIn
- Uniqueness
Phalconに標準で組み込まれているバリデーション機能は他にも利用可能なものがあり公式ドキュメントで確認できる。
WordPressとPhalconのModelを連携させることで、新規のデータベーステーブル管理を効率的にコーディングすることが可能になる。