ushidayの日記

主に「IBMi」のメモに・・・

第三回Haskell読書会@Shizu-Devお知らせ

第三回Haskell読書会開催を行いますので、お知らせ致します。
今回は第四章です。メインは...何だろう?まだ読んでないので、読まないと...。:-P

第三回Haskell読書会 開催要項

以下の要領でHaskell読書会を開催いたします。

    • 日 時 : 2010年3月27日(土) 13:00〜16:45(開場 12:30)
    • 場 所 : 静岡市民文化会館 第二会議室
    • 地 図 : http://www17.ocn.ne.jp/~bnk1103/page019.html
    • 定 員 : 20名
    • 費 用 : 一般 1000円,学生・未成年:無
    • 持ち物 : パソコン(練習問題をやるのに使用)課題図書※各自事前購入
    • 課題図書:プログラミングHaskellISBN:4274067815
    • 環境  :OS依存はしないが、GHC又はHugsを事前導入しておく事
    • 範 囲 : 4 章
    • 担 当 : いとうさん

あわせて、以下の要領で懇親会を開催いたします。

    • 場 所 : くいもの屋 わん 静岡呉服町店( http://www.hotpepper.jp/strJ000024878/
    • 時 間 : 17:30〜19:30
    • 懇親会費: 一般 4,000 円、学生・未成年 2,000 円

参加申し込みはこちらから「http://bit.ly/b6izyX
申し込み確認はこちらから「http://bit.ly/dwlJHS

ZendServer CEの環境変数

ローカルになんちゃって、IBM i(AS/400)の環境を作りたくて(個人では買えないですから...)、DB2 for WindowsとZend Sever CE 5.0 for Windowsを入れました。
そもそも、イケない感じはしていたのですが、DB2の入れた順序が悪いらしく、

  1. DB2 Express-C V9.7 for Windows
  2. DB2 Connect V9.1 (iSeries付属)
  3. DB2 Runtime V9.5 (ZendServer付属)

の順で入れたら、変な挙動をして、一旦アンインストールと思い実行したのですが、待てど暮らせど終了せず、途中で失敗してからは、それはもう最悪の状況になりました。仕方なくレジストリを、地道に修正して、ようやく復帰しました。

今度は、バージョンの古い順に入れたら、おかしな動きはなくなりました。
DB2 V9以降は、複数のDB2を入れても、DB2_COPYという状態で、複数のインストールが出来ます。
DB2には、デフォルトDB2コピーの切り替えが可能な”デフォルトDB2選択ウィザード”([プログラム]→[IBM DB2]→[セットアップ・ツール]→[デフォルトDB2選択ウィザード])が、付属していて、システム環境変数レジストリを書き換えてくれるようです。
無事切り替えてから、ヤレヤレとホットしたのもつかの間、PHPのアプリケーションでやりたかった、ローカルのDB2 Winの参照が出来ず、DB2 iを参照してしまいます。再起動しても何をしても結果は変わらず、システム環境変数の”PATH”も”DB2INSTANCE”もDB2 Winに変わっているのに...。

”var_dump($_SERVER)”で、環境変数を調べてみると、”PATH”がDB2 iのモジュールに通っている。プロセスブラウザで”Apacheのプロセス(httpd.exe)”を見てももちろん同じ、他のプロセスを見ると、現在のシステム環境変数になっているのにと、そんな状況。
httpd.confに何かあるのか?SetEnvとかしなきゃ駄目?→何もない..。
zend.confに何かあるのか?→何もない..。
php.iniに何か有るのか?→何もない..。
ZendEnablerConf.xml?→Coreには、なかったUTF-8でBOMがエラーで、インストール時のデフォルトでコケたぐらいのファイル。自分が認識が甘かった...。orz
ここにモロに、環境変数が記述してあります。こんな感じで...。

<Environment>
	<Variable name="DB2INSTANCE" value="DB2" />
	<Variable name="PHP_FCGI_MAX_REQUESTS" value="10000" />
	<Variable name="TEMP" value="C:\DOCUME~1\ushida\LOCALS~1\Temp" />
	<Variable name="PHPRC" value="C:\Program Files\Zend\ZendServer\etc" />
	<Variable name="PATH" value="...;C:\Program Files\IBM\SQLLIB\BIN;..." />
</Environment>

”DB2INSTANCE”と”PATH”を変更したら、無事ローカルのDB2 WinとDB iの切り替えが出来ました。これで同じカタログのデータベースを作成すれば、ローカルだけで開発とデモが出来そうです。(X60が頑張りすぎで、ソロソロやばいかもしれません)

あとはデータをDB2 iからDB2 Winへ簡単にレプリケーション出来ないかなぁ?
手動でエクスポート&インポートって何だか原始的だし

第二回Haskell読書会

第二回Haskell読書会が無事終了いたしました。今回、体調が悪く絶不調であまり発言する元気がなかったので、少しおとなしめで終わってしまいました。第三回頑張ります。(最近モヤットなのでパーッと飲みに行きたい!!)

内容ですが、スピーカのたかはしさんが、”操作させる”、”考えさせる”的な手法で、非常にうまい説明をして頂けたと思います。違った見方ですが、こういう面も非常に参考になり、勉強会として価値があると思いました。
今回の章は、主に”型”、”カリー化”、”クラス”についてがメインテーマでした。
型は、コンピュータ言語をやっている”方”にとっては、入り口的なところなので、みなさん理解も良かったのではと思います。ただ関数型言語における型とは、手続き型のソレとは違い、引数から返り値までを型という表現で表します。これは、GHCiやHugsの「:type」コマンドで確認することが出来ます。

Prelude> :type tail
tail::[a]->[a]

若干GHCiとHugsで表現の違いもあるようです。([Char]がStringだったり)

カリー化について、言葉で表すのって難しいですね。細かいことはハッキリ言ってわかりませんが(単に1つの引数をとって残りの部分を関数として返すとザックリ目に理解したとして)、Haskellの場合は、意識せずカリー化された関数になっている処が、凄いとは思います。

myadd::Int->Int->Int
-- myadd::Int->(Int->Int)
myadd x y =  x + y

この場合は、letを使う事で、関数が部分適用されている様が、わかる事を教えて頂きました。(letはHugsでは駄目らしい)下の例では、"myadd"にx=1を部分適用した、常に1を加える関数を"myadd'"に戻り値として受けている事がわかります。

*Main> let myadd' = myadd 1
*Main> myadd' 5
6

■カリー化・自分的理解
myadd 1 5

myaddの引数xに1を適用した無名関数を返す
無名関数(myadd 1) y = 1 + y

無名関数::Int->Int
無名関数 y = 1 + y

無名関数 5

無名関数 5 = 1 + 5

結局引数が幾つあっても、1つ引数をとって、残りの関数を返すという事を意識せず出来る所に素晴らしさが、あるのでしょう。まだ自分はありがたみが分かる程理解出来てないのが悲しいですが...orz。

クラスについても、オブジェクト指向のクラス、インスタンス、メソッドとは、違うというか、当てはめようとしても違和感があります。

■クラス・自分的理解
クラス・・・関数の集合
メソッド・・・クラスと言う定義によって集められた関数たち
インスタンス・・・メソッドの引数として取れる型

今のところ、自作の関数を作ろうとした時に、引数の制約として使う事が主のようなので、ザックリ理解で先に進めないと行き詰まってしまいそうです。
例えば
Eqクラスを調べるには

*Main> :i Eq
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
        -- Defined in GHC.Classes
------ 中略 ------
instance Eq Integer -- Defined in GHC.Num
instance Eq Float -- Defined in GHC.Float
instance Eq Double -- Defined in GHC.Float
instance Eq Bool -- Defined in GHC.Base
instance Eq Ordering -- Defined in GHC.Base
instance Eq Char -- Defined in GHC.Base
instance Eq Int -- Defined in GHC.Base
------ 中略 ------

Eqクラスのメソッドは「(==)左辺と右辺が同じ時真」と「(/=)左辺と右辺が異なる時真」(比較演算子的な関数)です。
関数の引数にEqクラス制約があった場合は、実装でその引数に対してメソッド(==や/=関数)が使われているから、引数に対してシバリを入れている。
==や/=関数に引数にとる事が出来るのが、インスタンスになる?==や/=も引数に同じ制約が入っている?少し煮え切らない部分もありますが、その内視界も開けてくるでしょう。
任意の関数型がEqクラスのインスタンスにならないのは、感覚的に分かる気がします。引数にとる型のパターンがあまりに多すぎて、通常は比較しようがないのでは?的な理解です。

まだ3章なので、ぼんやりですが、回が進に連れて、ハッキリしていければ良いなと思います。

第三回も日程は決まりましたが、会場まだなのでまた後日告知します。

ちなみにおやつは、美味しい”シュークリーム”でした。次回はプリン楽しみ。:-)

Zend Server CE 4.0.6 for Winを入れてみた

Zend Server CE(Community Edition)4.0.6をWindows環境に入れて、IBM i(AS/400)のDB2とゴタゴタやったので、メモしておきます。

■動作環境

DB2 Connectのセットアップ
  • DB2ランタイムで躓き...

これは、結果論で分かったのですが、Zend Server(以下ZS)には、DB2のランタイムがバンドルされていて、ZSインストール時に導入されます。しかしランタイム版は”Unix,Linux,Windows”のDB2を対象としている様で、”DB2 for i”は対象外の様です。以下のエラーが投げられました。

---- 接続文字列 ----
「DRIVER={IBM DB2 ODBC DRIVER};DATABASE=カタログ名;HOSTNAME=ホストIP;PORT=446;PROTOCOL=TCPIP;UID=ユーザー名;PWD=パスワード;」は接続出きません。

---- db2_conn_errormsg()の内容 ----
[IBM][CLI Driver] SQL8002N Connect processing failed; a valid product license was not found. SQLSTATE=42968 SQLCODE=-8002

AS/400と同時提供されている”DB2 Connect Personal Edtion”を入れる必要がありました。
IBMよりCDが提供され入るので、32bit Windwos版のインストールを行ないます。
インストール自体は、フルインストールにして、特に難しいところはありません。

  • カタログの作成

[スタート]→[プログラム]のDB2から、[セット・アップツール]→[構成アシスタント]を選び、カタログを構成します。

構成を追加するか?訪ねられるので”はい”を選びます。ウィザードを以下スナップショットの手順で、進めます。
ちなみにデータベース名は「WRKRDBDIREコマンド」で確認して、”*LOCAL”になっている項目です。










以下の設定が終わると、[管理ツール]の[データソース]でシステムDSNに、カタログが作成されています。

  • db2cli.lstのバインド

DB2のコマンドウィンドウでcliのバインド事前にしておく必要があります。しておかないと、DB2接続で以下のエラーが発生しました。

-------------------------------------------
[IBM][CLI Driver][AS] SQL0805N
パッケージ "NULLID .SYSSH200"
が見つかりませんでした。 SQLSTATE=51002
-------------------------------------------

cliのバインド
※参考(https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_11.1.0/com.ibm.db2.luw.qb.dbconn.doc/doc/c0005595.html

C:\Program Files\IBM\SQLLIB\BIN> db2 connect to カタログ名 user ユーザ名 using パスワード
C:\Program Files\IBM\SQLLIB\BIN> cd ../bnd

※DB2 LUWの場合は以下を実行
C:\Program Files\IBM\SQLLIB\bnd> db2 bind @db2cli.lst blocking all grant public
C:\Program Files\IBM\SQLLIB\bnd> db2 bind @db2ubind.lst blocking all grant public 

※IBMiの場合は以下を実行
db2 bind @ddcs400.lst blocking all grant public
(実行後に”NULLID”の中にSYSオブジェクトが作成される)

DB2クライアントのエンコーディングが、ローカル環境がデフォルトになるようで、DB2関数で返される結果が、SJISになって文字化けしました。以下のコマンドをDB2のコマンドウィンドウで実行して、エンコーディングUTF-8(CCSID 1208)にします。

db2set db2codepage=1208
---- 確認 ----
db2set -all

[構成アシスタント]の[DB2レジストリ]でも設定する事が可能です。


Zend Server CEのセットアップ

Zend.comより「Zend Server CE 4.0.6」のWindowsインストーラより導入します。
フルインストールをしないと、IBM系のExtension(ibm_db2,pdo_ibm)はインストールされないので、フルインストールします。最後に前述で入れたDB2 Connectについて、「既知のDB2 Clientがあるよ」と言われます。

  • ZendEnablerConf.xmlの修正

”C:\Program Files\Zend\ZendServer\etc\ZendEnablerConf.xml”の先頭に壊れたデータが入っています。この壊れたデータを除去します。この壊れたデータの影響で、http://localhost:89/ZendServer/ の表示が500 Internal Server Error になります。id:satoruyoshidaさんのこちらの日記で解決させて頂きました。助かりました。

新しい管理用UIは、設定変更時のリスタートもその場で出来るなど、使い易くて良い感じです。
php.iniやhttpd.confを適宜直して、実行すればWindwos Zend Serverの出来上がり?

DB2関数の接続は、カタログ接続の場合は、i5と全く同等です。「*LOCAL」を使わずカタログ名にしておけば、そのままソースを変更する事なく動作します。以下の様な感じです。

<?php
/*
// 非カタログ接続
$database = 'CSC2008';
$user = 'name';
$password = '****';
$hostname = '192.168.xxx.xxx';
$port = 446; // WRKRDBDIREで確認。デフォルトの*DRDAは「446」

$conn_string = "DRIVER={IBM DB2 ODBC DRIVER};DATABASE=$database;" .
  "HOSTNAME=$hostname;PORT=$port;PROTOCOL=TCPIP;UID=$user;PWD=$password;";
$db = db2_connect($conn_string, '', '');
*/

// カタログ接続
$conn_string = "CSC2008"; //カタログ名
$db = db2_connect($conn_string, 'name', '****');

しかし、「ibm_db2.i5_dbcs_alloc=1」を設定してやっても、i5だと半角カナが切れないのに、Windowsだと半角カナが切れてしまいます。(UTF-8で3バイトで認識されて、フィールドのバイト数にあたる文字数になってしまう)これは未解決のままです。

一応ベンチマーク

以前i5でやったベンチマーク同じ条件でやったら、若干遅くなりました。
DB2関数

 time indexex time%
Start1266922322.48437600-0.00%
DB2 Start select1266922322.484397000.0000210.00%
DB2 End select1266922323.986329001.50193223.22%
DB2 Start insert1266922323.986358000.0000290.00%
DB2 End insert1266922328.558094004.57173670.68%
DB2 Start update1266922328.558126000.0000320.00%
DB2 End update1266922328.952449000.3943236.10%
Stop1266922328.952471000.0000220.00%
total-6.468095100.00%

■PDO

 time indexex time%
Start1266922241.96875100-0.00%
PDO Start select1266922241.968781000.0000300.00%
PDO End select1266922243.733597001.76481626.03%
PDO Start insert1266922243.733623000.0000260.00%
PDO End insert1266922248.343330004.60970767.98%
PDO Start update1266922248.343354000.0000240.00%
PDO End update1266922248.749533000.4061795.99%
Stop1266922248.749565000.0000320.00%
total-6.780814100.00%

先日行って来た、OS協議会のお話ですと、これからAS/400にもZend Serverがプリインストールされるみたいです。

第二回Haskell読書会@静岡Developers勉強会

第二回Haskell読書会@shizu-devが、いよいよ来週となりましたので、この場をかりて告知させて頂きます。
詳細はこちら

第二回Haskell読書会

以下の要領でHaskell読書会を開催いたします。

    • 日 時 : 2010年2月27日(土) 13:00〜17:30
    • 場 所 : 静岡市産学交流センター 演習室 3 ※ネットワーク使用可 http://www.hanjyou.jp/
    • 地 図 : http://www.hanjyou.jp/map.html
    • 定 員 : 20名
    • 費 用 : 一般 1000円,学生・未成年:無
    • 持ち物 : パソコン(練習問題をやるのに使用)課題図書※各自事前購入
    • 課題図書:プログラミングHaskellISBN:4274067815
    • 環境  :OS依存はしないが、GHC又はHugsを事前導入しておく事
    • 範 囲 : 3 章
    • 担 当 : たかはしさん
    • 懇親会 :HONEY DRIPPER(ハニードリッパー) http://www.hotpepper.jp/strJ000637976
    • 懇親会参加費:学生・未成年2,000円、一般4,000円

※参加申し込みはこちらから「http://bit.ly/6aZBtT
 申し込み確認はこちらから「http://bit.ly/5oVa46

Zend Framework Controllerメモ

Zend_Controllerを使ってみた時のメモを残しておきます。

httpd.confの設定

Zend Framework(ZF)では、URL変換に”mod_rewrite”モジュールを使用しているので、「/usr/local/Zend/apache2/conf/httpd.conf」を以下の様に書き換えます。

#LoadModule rewrite_module modules/mod_rewrite.so
↓
LoadModule rewrite_module modules/mod_rewrite.so

ちなみに、”Zend Core 2.6.1”はデフォルトでモジュールが有効になってました。”.htaccess”を有効にする為に、””以下に追記します。

# ルートの設定
<Directory />
    Options FollowSymLinks
    AllowOverride None
</Directory>

# ドキュメントルートの設定
<Directory "/www/zendcore/htdocs">
    Options Indexes FollowSymLinks

#    AllowOverride None
    ↓
    AllowOverride All

    Order deny,allow
        Deny from all
    Allow from 127.0.0.1
</Directory>
.htaccessの設定

Zend StudioZend Frameworkプロジェクトで作成すると以下の構造になり、コントローラ、ビューの雛形や.htaccessもデォルトで用意されますので、それを適宜変更します。

■デフォルトの.htaccess

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
Controllerを使う
    • フロントコントローラの準備。(e.g. PROJECT_HOME/public/index.php
    • Zend_Controller_Actionのサブクラスのアクションコントローラを準備。(e.g. PROJECT_HOME/application/controllers/IndexController.php
    • 継承されるメソッド
      • init : コントローラの初期化の実装をオーバーライド
      • preDispatch : Actionメソッド実行前のフックの実装をオーバーライド。
      • postDispatch : Actionメソッド実行後のフックの実装をオーバーライド。
      • _forward(アクション, クラス=null, モジュール, 引数) : アクション実行後にフォワード。preDispatchで行った場合は、アクションがキャンセルされる。(e.g. $this->_forward("hogehoge","hoge")<=> "/hoge/hogehoge" )
      • _redirect(URI) : URIへリダイレクトする。(e.g. $this->_redirect("/hoge/hogehoge"))
    • Viewを準備。(e.g. PROJECT_HOME/application/views/scripts/index/index.phtml)
    • 命名規則
      • コントローラクラス : 「HogeController.php」(MSD1が大文字)
      • アクションメソッド : 「hogehogeAction」(小文字名+Action)
      • ビュー : 「hogehoge.phtml」(小文字名)
    • URIにコントローラとメソッドを指定しない場合のデフォルト
      • アクションコントローラ : 「IndexController.php」(setDefaultControllerNameで変更可)
      • アクションメソッド : 「indexAction」(setDefaultActionで変更可)

■フロントコントローラの例

<?php
require_once 'Zend/Controller/Front.php';

/*
Zend_Controller_Front::run("../application/controllers");
↑は↓と同意
$front = Zend_Controller_Front::getInstance();
$front->setControllerDirectory("../application/controllers");
$front->dispatch();
*/
$front = Zend_Controller_Front::getInstance();
$front->setControllerDirectory("../application/controllers");

// 独自のデフォルトコントローラとデフォルトメソッドを指定する場合 
/*
$front->setDefaultControllerName("hoge");
$front->setDefaultAction("hogehoge");
*/

$front->dispatch();

■アクションコントローラの例

<?php

require_once 'Zend/Controller/Action.php';
require_once 'Zend/Date.php';

class hogeController extends Zend_Controller_Action
{

    public function init()
    {
        /* 初期化処理をここに記述する。コンストラクタの後に実行される */
        $this->view->assign("message","初期化を行いました。");
        $this->view->assign("message3","forwardするとコントローラの初期化で消える");
    }

    public function preDispatch(){
    /* アクションの呼出前に実行する処理 */
    }

    public function postDispatch(){
        /* アクションの呼出後に実行する処理 */
    	$this->view->assign("message4","アクションを実行しました。");
    }
  
    public function indexAction()
    {
        $this->view->assign("actionname","indexアクションです。");
        $this->view->assign("message3","forwardするとこのメッセージは消される。");
        $date = new Zend_Date();
        $this->view->assign("dt",$date->get(Zend_Date::TIMES));

        if(($date->compare("09:00:00",Zend_Date::TIMES) < 0)
           || ($date->compare("17:00:00",Zend_Date::TIMES) > 0)){
            $this->view->assign("message2","9〜17時以外は稼働時間外です");
            // 条件によって、別のアクションにフォワードする例
            // forward(アクション名,コントローラ名,モジュール名,パラメータ)
            $this->_forward("hogehoge");
        }else{
            $this->view->assign("message2","システム稼働中");               
        }        
    }
    
    public function hogehogeAction()
    {
        $this->view->assign("actionname","hogehogeアクションです。");        
    }    
}

■ビューの例

<html>
<head>
<title>タイトル</title>
</head>
<body>
アクション名:「<?php echo $this->escape($this->actionname);?><br/>
現在の時刻は「<?php echo $this->escape($this->dt);?>」です。<br/>

<?php echo $this->escape($this->message);?><br/>
<?php echo $this->escape($this->message2);?><br/>
<?php echo $this->escape($this->message3);?><br/>
<?php echo $this->escape($this->message4);?><br/>

</body>
</html>

Zend Core for i5で国際化&ローカライズ

IBM i(AS/400)の5250アプリで、多言語対応する場合は、”*MSGF”を使ったり、画面制約に縛られたりで、実装も保守も個人的には「面倒だ」というネガティブなイメージがあります。(中には画面やメニューだけ別言語で書き直して、OVRDSPFなんてのもあります。)
しかし、海外拠点を持つカスタマー(特にアチラコチラに散在しているケース)からは、「今後どこの国に進出するか判らないけど(現在は主に中国、東南アジアやヨーロッパだったり)、アプリケーションは多言語対応したい」との要望を寄せられるケースもあります。そこで、”Zend Core for i5”に、デフォでバンドルされている、”Zend Framework(ZF)”の機能の1つ、”Zend Translate”を使って国際化&ローカライズを試してみました。

■サーバー環境

■クライアント環境

■参考サイト

最新Zend Frameworkの導入

Zend CoreにデフォでバンドルされているZFは、”1.6.0”だったので、最新の”1.10.0”にしました。"Zend Frameworkの公式サイト"から手に入れる事が出来ます。
アーカイブをダウンロードしたら、AS/400のIFS上の適当なディレクトリで解凍して、php.ini(/usr/local/Zend/Core/etc/php.ini)の”include_path”に、「/usr/local/Zend/ZendFramework-1.10.0/library」を追加します。これで、”require”などで「Zend/フレームワーク名」で使えるようになります。

PHPプログラムの準備

”Translate”の大まかな使い方は、以下のステップです。

    1. 「require_once 'Zend/Translate.php'」でインクルード。
    2. Zend_Translateのインスタンス(※以下”$tl”)を作成。この際にコンストラクタで、翻訳アダプタ、翻訳されたリソースのパス、ローケルを指定します。翻訳アダプタは様々なフォーマットが使える様に柔軟に出来ているようです。今回はgettextで試しました。
      • Array
      • CSV
      • gettext(*.mo)
      • ini
      • TMXなどなど...
    3. 追加のローケルがあれば、$tl->addTranslationメソッドで、翻訳リソースとローケルを追加する
    4. ローケルを設定しなければ、デフォルトローケルが使われます。明示的に設定する場合は、$tl->setLocaleメソッドを呼び出します。
    5. $tl->_メソッドで言語を変換。
翻訳ファイルの準備

gettextのソースファイルpoを編集可能な”poEdit”を使います。導入はインストーラまかせで、特に何もありません。初回起動時に言語の選択等があります。
起動後、phpのソースファイルを元に、翻訳用のカタログを作成します。[ファイル]→[新規カタログ]を選びます。

[情報]タブで、必要な項目を以下の様に入力します。

[パス]タブでは、[ベースパス]に環境依存のパスを指定します。今回の場合はZend Studioワークスペースまでのパスとします。[パス]には、翻訳対象となるソースが存在するパスを指定します。

[キーワード]タブは、翻訳対象となるメソッドを登録します。デフォルトで”_”が存在するので特にする事はありません。OKボタンを押して、保管先を指定すればpoファイルが作成されます。

あとは、対訳をえっちらおっちらと、入力します。デフォルトで、”poファイル”を保存すれば、同じディレクトリに”moファイル”が作成される設定になってます。

元のPHPソースに変更が合った場合は、[カタログ(A)]→[ソースから更新(U)]を行うか、ツールバーにある地球マークをクリックすれば、poファイルをマージします。
翻訳リソースのmoファイルを、Zend Studioに適宜配置します。(PROJECT_HOME/languages/jp/message_jp.moなど)
以下が今回のサンプルプログラムです。
■ ZendTranslate.php

<?php
require_once 'Zend/Translate.php';

// Zend Transelate
$translate = new Zend_Translate("gettext","./languages/en/messages_en.mo","en");
$translate->addTranslation("./languages/ja/messages_ja.mo","ja");

echo "これは英語\n";
$translate->setLocale("en");
print $translate->_("Example") . "\n";
print "=======\n";
print $translate->_("Here is line one"). "\n";
$format = $translate->_("Today is the %1\$s.%2\$s.%3\$s");
printf($format . "\n" , date("m"),date("d") ,date("Y"));
print $translate->_("Here is line two") . "\n";
print "\n";

echo "ここから日本語\n";
$translate->setLocale("ja");
print $translate->_("Example") . "\n";
print "=======\n";
print $translate->_("Here is line one"). "\n";
$format = $translate->_("Today is the %1\$s.%2\$s.%3\$s");
printf($format . "\n" , date("m"),date("d") ,date("Y"));
print $translate->_("Here is line two") . "\n";

■実行結果

番外編:gtedプラグイン

Eclipseのpluginの”gted”も試してみました。”http://gted.sourceforge.net/update”を、Zend Studioの[Help]→[install New Software]から導入します。
導入後に[Preferences]→[gted]→[gettext Tools]で、”poEdit”のインストールディレクトリにある”bin”ディレクトリを指定します。

プロジェクトを右クリックして[Properties]→[gted Settings]を適宜設定します。

プロジェクトを右クリックして[gted]→[Update PO Files]を行うと、プロジェクト内のソースからpoファイルが作成されます。ただ一見するとマージ機能等はなさそうなので(※自分が機能を探しきれてないだけかも知れませんが...)、poEditの方が使い勝手は良いような気がします。ただ参照と編集だけの用途ならば、十分にも思えます。po専用のエディタは縦横2タイプのGUIビューとコードエディタが選べます。

結局この後、[Preference]→[General]→[Editors]→[File Associations]で、”*po”と”*pot”のデフォルトエディタを、外部エディタで”poEdit”に変更しました。