ブログトップ 記事一覧 ログイン 無料ブログ開設

k4200’s notes and thoughts

2012-05-10

既存のPHPプロジェクトをZend Frameworkのプロジェクトに

やりたい事

タイトル通りだけど、既存のPHPプロジェクト(フレームワークとかは特に使っていない)をZend Frameworkのプロジェクトに移行する。

参考ページ

基本はこのページのとおり。

環境

/var/www/html 直下に既存のプロジェクトがあるものとする。

続きを読む

2012-04-25

sbteclipseでソース添付

最近またScalaでプログラムを再開した。開発環境はsbt + Eclipse。なので、sbteclipse を使っている。

知らない人のために一応書くと、sbteclipseとは、Eclipseの.projectファイルとかを作成してくれて、sbtプロジェクトをEclipseのプロジェクトとして開けるようになるという、GUI厨には欠かせないプラグイン

sbtで設定した依存ライブラリとかもclasspathに入れてくれるんだけど、ライブラリのソース添付ってどうやるんだろう。

ちょっとbingったら、こちらのブログエントリが。でも、イマイチよくやり方が分からなくて、もう少し調べたらsbteclipseのドキュメントに書いてあった

結論は build.sbt に以下のように記述すればOK。

EclipseKeys.withSource := true

2012-04-13

PHPUnit 3.6 not supported by ZF 1.11.10

Got the following error when running my 1st db test using PHPUnit and Zend Framework.

PHP Fatal error:  Class Zend_Test_PHPUnit_Db_Metadata_Generic contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (PHPUnit_Extensions_Database_DB_IMetaData::disablePrimaryKeys, PHPUnit_Extensions_Database_DB_IMetaData::enablePrimaryKeys) in /path/to/zf/Zend/Test/PHPUnit/Db/Metadata/Generic.php on line 167

It turned out that Zend Framework (Zend_Test_PHPUnit) doesn't support PHPUnit 3.6. See the comments on an issue here.

My environment:

2012-04-12

Zend_Locale in compatibility

Zend_Locale 使ったら以下のようなエラーが出た。

[Wed Apr 11 18:03:11 2012] [error] [client 192.168.56.1] PHP Notice:  You are running Zend_Locale in compatibility mode... please migrate your scripts in /path/to/zf/Zend/Locale.php on line 294

こちらのページにあるように、以下のようにすればOK。

Zend_Locale::$compatibilityMode = false;

Zend Framework 1.11.10

2012-03-28

Mustach Template Engine

はじめに

JavaScriptPHPテンプレートを共用したい

今仕事で作ってるサイトは、フレームワークとかも使っていないプレーンなPHPで出来ている。(自分は開発に途中から参加したので、その辺りの決定には関与していない)。

あと、特徴として、(最近のwebサイトにありがちな)サーバーからJSON形式のデータをAJAXで取得してJavaScriptで描画する処理が結構多い。その部分の処理にテンプレートを使って楽をしたいと思って、最初はJavaScriptで使えるテンプレートをいくつか試した。

そのうちSEOとかも絡んでくると、クライアント側のAJAXで処理するだけではなく、時にはサーバー側(PHP)で全てHTMLを組み立ててブラウザに返す場合も出てきた。となると、PHPJavaScriptで同じテンプレートが使えたほうが楽じゃんって事でMustache Template Engine (System?)を使うことにした。

Mustache?

詳しくはググるなりbingるなりして下さい。

  • 各言語向けの実装があること
  • Logic-lessという、ある意味大胆なシンプルさ

の2点が特徴かと個人的には思ってる。Logic-lessっていうのは、他のテンプレートエンジンにあるようなif, else, whileのような制御構造がないって意味なんだけど、これには抜け道というかそういうのがあるので、別にそんなに使い勝手が悪いわけでもない。詳しくは(?)後述。

基本的な使い方

準備

ここから各言語向けの実装が落とせるので、PHP用のMustache.phpJavaScript用のmustache.jsダウンロードしておく。

必須じゃないけど便利なんでjQueryダウンロードしておく。


テンプレートの定義

PHPで以下のように定義する。これを例えばtmpl.inc.phpとして保存する。

$tmpl = <<EOT
  <div class="image_area">
    <img id="image_{{image_id}}" src="{{url}}" />
  </div>
EOT;

同じテンプレートJavaScript側でも使えるように、以下のようにする。

<?php
require_once('tmpl.inc.php');
?>
var tmpl = <?php print json_encode($tmpl); ?>;
PHPで使用する
<?php
require_once('Mustache.php'); //ライブラリの読み込み
$m = new Mustache(); // インスタンスの生成

// テンプレートに流しこむデータの作成
$data = array("image_id" = 100, "url" => "http://image.example.com/100.jpg");
?>
<html>
<head><title>PHPのサンプル</title></head>
<body>
<div id="canvas">
<?php $m->render($tmpl, $data); // 描画 ?>
</div>
</body>
</html>
JavaScriptで使用する
<?php
require_once('tmpl.inc.php');
?>
<html>
<head>
  <title>JavaScriptのサンプル</title>
  <script type="text/javascript" src="jquery.min.js"></script>
  <script type="text/javascript" src="mustache.js"></script>
</head>
<script>
$(document).ready(function() {
  var tmpl = <?php print json_encode($tmpl); ?>;
  var data = {image_id: 100, url: "http://image.example.com/100.jpg"};
  var htmlStr = Mustache.to_html(tmpl, data); // HTMLの生成
  $('#canvas').html(htmlStr); // 生成されたHTMLをdiv要素に挿入
});
</script>
<body>
<div id="canvas"></div>
</body>
</html>

ロジック風のもの、その1:ループ

こっからはサクサク説明。まずは複数の画像を表示させてみる。


テンプレート

{{#foo}} というセクションは、渡されたデータにfooという名前の配列があれば、その各要素に関してテンプレートを展開する。具体例を。

$tmpl = <<EOT
  <div class="image_area">
    {{#images}}
      <img id="image_{{image_id}}" src="{{url}}" />
    {{/images}}
  </div>
EOT;

PHP

プログラムはデータの部分のみ変更で、その他は一緒。

$data = array("images" => array(
  array("image_id" = 100, "url" => "http://image.example.com/100.jpg"),
  array("image_id" = 103, "url" => "http://image.example.com/103.gif")));
JavaScript

書くまでもないけど・・・

var data = {images:
              [{image_id: 100, url: "http://image.example.com/100.jpg"},
               {image_id: 103, url: "http://image.example.com/103.jpg"}]};

ロジック風のもの、その2:条件分岐

英語のWikipediaのMustacheのページを見ると、「ラムダを使えば出来るよ」って書いてあるし、確かにその通りなんだけど、よくあるような「偶数行と奇数行で色分けしたい」とかなら、以下のようなもうちょい簡単な方法で良さそう。

テンプレート

{{#even}}~{{/even}}で囲まれたセクションは、evenという変数が存在してtrueであれば描画される。{{^even}}~{{/even}}はその逆。

$tmpl = <<EOT
  <table>
    <tr>
      <th>製品コード</th><th>製品名</th>
    </tr>
    {{#products}}
      {{#even}}
        <tr class="gray">
      {{/even}}
      {{^even}}
        <tr class="white">
      {{/even}}
        <td>{{product_id}}</td>
        <td>{{product_name}}</td>
      </tr>
    {{/products}}
  </table>
EOT;
PHP

先程と同様、プログラムはデータの部分のみ変更で、その他は一緒。

$data = array("products" => array(
  array("product_id" = 33, "product_name" => "ああ", "even" => true),
  array("product_id" = 35, "product_name" => "いい"),
  array("product_id" = 12, "product_name" => "うう", "even" => true)));
JavaScript
var data = {products:
              [{product_id: 33, product_name: "ああ", even: true},
               {product_id: 35, product_name: "いい"},
               {product_id: 12, product_name: "うう", even: true}]};

その他紹介していない事柄を簡単に説明

エスケープ

{{foo}} は全てエスケープされるので、XSS対策によい。というか、それがそもそもテンプレートエンジンを使う意義の1つだし。ちなみに{{{foo}}} (カッコが1つ多い)とやるとエスケープされなかったはず。うろ覚え。

パーシャル

これは便利。テンプレートAの中でサブテンプレートBを呼び出す、みたいな感じ。このエントリーをここまで読んでいれば、後はマニュアル見ればすぐ使い方はわかるはず。

まとめ

Mustacheは手軽でそこそこ便利だよ。性能もそこそこだったはずなので、大規模サイトとかの場合には違った選択肢もあるとは思うけど。詳しくは「テンプレートエンジン パフォーマンス」などで検索するといいかも。