2010年1月31日日曜日

Zend Framework1.10.0のZend_Toolを試してみた

Zend Framework 1.10.0でZend_Toolを利用してみたので、とりあえずメモ。

事前にzf.shコマンドをパスに通しておく。

Ubuntu9.10の環境で試しているので、とりあえず以下でパスを通して実行
$export $PATH=$PATH:zf.shが存在するパス
$zf.sh

エラーが出ずに動けばOK.

(1)プロジェクトを作成する。

sampleという名のプロジェクトを作成するには、

$zf.sh create project sample

と指定する。
実行が完了すると以下のディレクトリやファイルが生成される。
[生成されるディレクトリやファイル]
sample/
    application/
        Bootstrap.php    <=メソッドなしのクラス
        configs/
            application.ini
        controllers/
            IndexController.php
            ErrorController.php
        layouts/    <=空
        models/    <=空
        views/
            helpers/
            scripts/
                index/
                    index.phtml
                error/
                    error.phtml  
    public/
        index.php
        .htaccess
  
    tests/    <=PhpUnitの関連ファイル
    library/    <=空


Index、Errorの2つのコントローラが実行できるようになっている。
VIEWは以前のバージョンで試していたときは、ショートタグ形式だったけどがPHPの指定に変更になっていた。
普段ショートタグは使用してなくて、書き換えていたので、この変更はうれしい。


とりえず生成したものをブラウザからアクセスできるように設定する。
自動生成したものには、ZendFrameworkのライブラリ一式は、library配下におくことが前提になっている。
このため、Zend Frameworkのファイルをコピーするか、他にすでに配置されているようならば、シンボリックリンクを張っておく。

次に公開領域にプロジェクトのpublicディレクトリのシンボリックリンクを作成する。
#apacheの設定で、公開領域でシンボリックリンクを利用できるように設定しておく
#個人的にはあまり好きじゃないけど、とりあえず、動かすだけなので。

$cd /var/www
$ln -s ~/sample/public sample

ブラウザからアクセスするとzfで自動生成したファイルが表示される。
http://xxxxxx/sample/


Controllerの追加などは、プロジェクトディレクトリ直下でコマンド操作する。
$cd sample


(2)レイアウトを追加
1.10.0からZend_ToolでLayoutの有効・無効が設定できるようになった。

$zf.sh enable layout

コマンドを実行すると

a)layouts/script/layout.phtmlが作成される
b)application.iniに
 resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"
 と追加される。

(3)アクションを追加

$zf.sh create action アクション名 コントローラ名

コマンドを実行すると
a)IndexControllerにsampleAction()が追加される
b)views/scripts/index/sample.phtmlが作成される
viewには、コントローラ名と、アクション名が表示されるようになっている。

※コマンドの説明では、
Action
zf create action name controller-name[=index] view-included[=1] module

とあって、 indexがデフォルトだと思って実行してみたけど、追加するコントローラがないと怒られる。
実はコントローラの指定では、Indexと最 初は大文字で指定しないとNGなようで、ハマッた。


(4)モデルを作成
これも1.10.0から追加されたもの

$zf.sh create model modelsample

コマンド実行すると
a)applications/models/Modelsample.php が作成される

単に空のクラスが作成されるだけ。
ディレクトリによる階層分けを試してみたけど、うまく指定できなかった。



(5)コントローラーの追加
$zf.sh create controller sample

コマンドを実行すると、
a)applications/controllers/SampleController.phpが作成される
メソッドはinit()とindexAction()が空の状態で生成される。
b)views/scripts/db/index.phtmlが作成される

(6)DBアダプターの設定をapplication.iniに追加
これも1.10.0から追加された。

$zf.sh configure dbadapter "host=ホスト名&adapter=Pdo_Pgsql&username=ユーザ名&password=パスワード&dbname=データベース名"

コマンドを実行すると
a)application.iniに指定内容がZend_Application_Resource_Dbが利用できる形で反映される。

DBパラメータ指定箇所は単に展開されるだけなので、正しいパラメータ名を記述する必要がある。

[パラメータ名]
host
adapter
dbname
username
password


※section-nameを指定して、application.ini内の任意のセクションに設定を追加できると思うのだけど、うまくいかなかった。

(7)テーブルクラスを追加
これも1.10.0で追加された。

zf.sh create db-table account account_tb -f

コマンドを実行すると

a)models/DbTable/Acctount.phpが作成される

$_nameにテーブル名が指定される状態でコードが生成される。
テーブル名を指定しないとエラーになる。
テーブル名とクラス名の規約に一致していればいいはずなので、指定なしでもいいような・・・。


マニュアルを見ると、データベースを指定して、データベースの自動生成できるようなことが書いてある。
コマンド例をいろいろ試してみたけど、できなかった。まだ、実装されていないのだろうか?

ついでに、コマンドのヘルプでは、db-tableと指定することになっているけど、リファレンスでは、dbtableになっており、どちらの指定でも生成はされていた。


DbTalbeが自動的にDB内のテーブルをスキャンして生成してくれるようになるとずいぶん楽になるんだけど、もうすこしといったところか。

2010年1月29日金曜日

Zend Framework 1.10.0リリース

Zend Framework 1.10.0リリースがリリースされてました。

気になるのは、
Zend_Application resourcesで、Log, Mailが追加されている
Zend_ToolでModel generation, DbAdapter setup, Layouts and Form Generationが追加されている(っぽい)
ところか。

Zend_Db_Table(その4) 検索その1

テーブルからデータ取得をするために3つのメソッドが用意されている

find() :主キーを利用して検索
fetchRow() :条件を指定して一行だけ検索
fetchAll() :条件を指定して複数行検索

fetchRow()以外はZend_Db_Table_Rowsetで取得できる。
fetchRow()は条件にマッチしたら、Zend_Db_Table_Row、マッチなかったらnullが取得できる。

--------コード例--------
$table=new Hoge();
//主キーを利用した検索
$rows=$table->find($key);
//条件を指定して検索(一行だけ)
$row=$table->fetchRow($table->select()->where("col=?",$value);
//条件を指定して検索(複数行)
$rows=$table->fetchAll($table->select()->where("col=?",$value);
-------ここまで-------


foreach文で、Zend_Db_Table_Rowを取得できる。
--------コード例--------
$table=new Hoge();
$rows=$table->fetchAll($table->select()->where("col=?",$value);
foreach($rows as $row){
 $row->name;
$row->id;
}
-------ここまで-------
Zend_Db_Table_Rowsetでは、count()メソッドで件数を取得できる。



配列で取得したいなら、toArray()メソッドを使えば、列を連想配列に変換したものの配列を取得できる

--------コード例--------
$table=new Hoge();
$rows=$table->fetchAll($table->select()->where("col=?",$value);

$data_array=$rows->toArray();
foreach($data_array as $key=>$value){
echo "キー=".$key."\n";
echo "値=".$value."\n";
}
-------ここまで-------

current()メソッドを使うと最初の行だけ取得できる。
find()を利用する場合はRowsetが必ずで返るので、以下のようにして、Rowを取得する。
Rowsetが0件の場合、current()の戻り値はnullになる。
--------コード例--------
$table=new Hoge();
$rows=$table->find($key);
$data=$rows->current();
-------ここまで-------

2010年1月27日水曜日

Zend_Db_Table(その3) テーブルクラスの定義

Zend_Db_Tableを継承したクラスを定義する。
対象となるテーブルが規約にクラス名と同じであり、主キーがシーケンスのように自動インクリメントすキーを持つテーブルであれば、クラス定義や具象クラスを利用するだけでで使用できる。

--------テーブル例--------
CREATE TABLE HOGE
(
ID SERIAL NOT NULL UNIQUE,
NAME TEXT,
PRIMARY KEY (ID)
) ;
CREATE TABLE HOGECHILD
(

CID SERIAL NOT NULL UNIQUE,
PARENT_ID INTEGER NOT NULL REFERENCES HOGE,
NAME VARCHAR(10) NOT NULL,
PRIMARY KEY (CID)
)
--------ここまで--------

--------コード例--------
class Hoge extends Zend_Db_Table_abstract{
}
$table=new Hoge();
$result=$table->find(1);//主キーによる検索
-------ここまで---------

(クラスを定義しない方法 1.9以上)
--------コード例--------
$table = new Zend_Db_Table('hoge');
-------ここまで---------

(テーブル名をクラス名と分ける場合)
--------コード例--------
class Hoge extends Zend_Db_Table_Abstract{
protected $_name="hoge";
}
-------ここまで---------

(主キーが自動インクリメントするキーの場合)
--------コード例--------
class Hoge extends Zend_Db_Table_Abstract{
protected $_sequence=true;
}
-------ここまで---------

(主キーが自然キーの場合)
--------コード例--------
class Hoge extends Zend_Db_Table_Abstract{
protected $_sequence=false;
}
-------ここまで---------

(プラリマリーキーを指定する場合)
--------コード例--------
class Hoge extends Zend_Db_Table_Abstract{
protected $_primary="id";
protected $_sequence=true;
}
-------ここまで---------


テーブル間の関係(リレーション)をクラスに定義しておくと、Zend_Db_Rowクラスから、親テーブルや子テーブルへのアクセスが簡単に利用できる。
テーブルに親、子供テーブルが存在する場合は、親、子に対する関係を記述する。

(従属するテーブルが存在する場合)
--------コード例--------
class Hoge extends Zend_Db_Table_Abstract{
protected $_sequence=true;
//テーブル名ではなく、Zend_Db_Tableを継承したクラス名を記述する
protected $_dependentTables=array(
'HogeChild'
);
}
-------ここまで---------

(親テーブルが存在する場合)
--------コード例--------
class HogeChild extends Zend_Db_Table_Abstract{
protected $_sequence=true;
//refTableClassの要素はテーブル名ではなく、Zend_Db_Tableを継承したクラス名を記述する
protected $_referenceMap=array(
'Rule1'=>array(
'columns'=>'parent_id',
'refTableClass'=>'Hoge',
'refColumns'=>'id'
)
);}
-------ここまで---------

2010年1月24日日曜日

Zend_Db_Table(その2) 接続準備編

Zend_Db_Tableに接続先となるDBの情報を指定する必要がある。
※指定するのはZend_Db_Adapterクラス、でZend_Db::Factory()で生成すればいい。


Zend_Db_Tableの継承クラスに指定する方法はいくつかあるので、必要に応じて使い分ける。

a)Zend_Db_Tableのコンストラクタで接続先情報を指定する
b)Zend_Db_Table::_setupDatabaseAdapter()をオーバーライドして、接続先情報を設定する。
c)Zend_Db_Table_Abstract::setDefaultAdapter($db)ですべてZend_Db_Table継承クラスに対して、接続先を指定する。
※a),b)の指定が優先される。
b)は接続先が他のテーブルと異なる、かつ、接続先の設定変更しないような場合に使う。

通常のアプリケーションでは、テーブルがひとつということはほとんどないので、c)の方法でBootstrapで記述しておけばいい。
------コード例-------
$db=Zend_Db::factory('Pdo_Pgsql', array(
 host=>'localhost',//接続先ホスト
 username=>'dbuser',//DBユーザ名
 password=>'dbpass',//DBパスワード
 dbname=>'DB NAME'//DB名
));
Zend_Db_Table_Abstract::setDefaultAdapter($db)
------ここまで-------

Zend_Db::factory()メソッドで指定する場合、配列で直接指定するほかにZend_Configを利用して外部iniファイルに設定を記述することもできる。

Zend_Applicationを利用する場合は、リソースプラグイン(Zend_Application_Resource_Db)を利用できるので、以下のように記述しておけば、勝手にデフォルトアダプターとして設定してくれるので便利

-------application.iniでの記述例---------
resources.db.adapter = pdo_pgsql
resources.db.params.host = localhost
resources.db.params.username = dbuser
resources.db.params.password = dbpassword
resources.db.params.dbname = dbname
resources.db.isDefaultTableAdapter = true
-------ここまで----------

Zend_Db_Table(その1)

Zend Frameworkに用意されているO/Rマッパー。

DBで定義しているテーブルに対して1対1で対応するZend_Db_Tableを継承するクラスを定義する。

hogehogeテーブル<=>hogehogeクラス

(コード例)
$hote=new Hoge_Table();

//主キーによる検索
$hoge->find("値");
//追加
$hoge->insert(array("列名1"=>"値","列名2"=>"値"));
//更新
$hoge->update(
 array("列名1"=>"値","列名2"=>"値"),
 $hoge->select()->where("列名=?"="値")
);
//削除
$hoge->delete($hoge->select()->where("列名=?"="値"));


主キーによる検索などは、Zend_Db_Tableに用意されているメソッドを使い、アプリケーションに必要処理だけコーディングすることで、シンプルなコードにできる。

Zen_Db_Tableの抽象化対象となるテーブルは、主キーとして、自動生成できるシーケンスを前提といる。
このため、DB設計をする際に、そのあたりを考慮しておくとコーディングが楽になる。
#そうでないテーブルも主キーに関する定義をすることで、当然対象にできる。

テーブル間のリレーションをクラス定義する際に、指定することで、検索結果などで取得できるZend_Db_Table_Rowクラスから関連するテーブルの情報を簡単に取得することもできる。

2010年1月19日火曜日

FirePHPは便利

FirePHPは、FirefoxのアドオンのFirebugの機能拡張で、インストールすることで、サーバ側の出力をFirebugのコンソールに出力できる。

HTTPヘッダーを利用しているようで、試してませんが、Ajaxの通信などでHTMLをブラウザに出力しない場合でも利用できるそうです。
Zend Frameworkのコンポーネントでは、Zend_logやZend_Db_Profilerなどで、出力先をFireBugのコンソールにできます。

(1)ログを内容を出力する
ログライターにZend_Log_Writer_Firebugを利用する。

$writer=new Zend_Log_Writer_Firebug();
$log=new Zend_Log($writer);
//日本語出力もOK
$log->info("日本語もOK");

日本語の出力も問題なくできました(UTF-8だけしか試してません)

(2)DBのプロファイルを出力する
プロファイラーに Zend_Db_Profiler_Firebugを設定する。

$db=Zend_Db::factory('Pdo_Pgsql', array(
 host=>'hogehoge',
 username=>'dbuser',
 password=>'dbpass',
 dbname=>'sampledb'
));
$profiler=new Zend_Db_Profiler_Firebug('All DB Queries');
$profiler->setEnabled(true);
$db->setProfiler($profiler);
Zend_Db_Table_Abstract::setDefaultAdapter($db);


Firebugのコンソールではテーブル構成で結構見やすい。

自分の環境では、なぜか、ページを出力しただけではコンソールに出力されず、その状態で一度Firebugをオフ/オンして再表示するとコンソールに表示される。
まだ安定してないのか、設定がよくないのか・・・・。
(追記)Firebugを1.50に更新したら直った。

Zend Framework 1.9.7などなどリリース

Zend Framework 1.9.7がリリースされてました。

他にも、1.8.5,1.7.9と古いバージョンのリビジョンがあがっています。
XSS関連の問題の修正がされているようです。

Zend_SessionでCookieを使用しないセッション管理

デフォルトはCookieを使うようになっているので、php.iniもしくは.htaccessで使用しないように設定。
勝手にURLにセッションをつけない様にする。セッションIDの名称変更。

.htaccessの記載例)

php_value session.use_cookies 0 #Cookie利用しない
php_value session.use_only_cookies 0 #Cookie以外も利用
php_value session.use_trans_sid 0 #URLへの自動付与OFF
php_value session.name hogesession #セッションID名称を変更


Zend_Sessionでセッションをスタート

Zend_Session::setOptions(array(use_only_cookies=>'off'));
Zend_Session::start();
$session=new Zend_Session_Namespace('hoge');


Zend_Sessionでは、use_only_cookiesがデフォルトでONに設定されるようで、.htaccessでoffにしていても、ONになってしまうので、Zend_Session::startの引数で必ずオプションを設定しておいたほうがいい。

.htaccessで設定したほうが、プログラム内で設定するよりもいいと思うけど、Zend_Sessionが動作する際に、上書きしてしまうので、すべてZend_Sessionのパラメータで設定するのでもいいかも。

Zend_Sessionを利用する場合は以下は必ず必要なので忘れずに。
php_value session.auto_star 0 #セッション自動開始OFF

そのほか指定しそうなパラメータ

・有効期間
php_value session.gc_maxlifetime 1800 #有効期間を30分

・セッション情報保存先を指定(ファイルに出力する場合)
#/tmp/php/hogeディレクトリへ出力 書き込み権限は必要
php_value session.save_path=/tmp/php/hoge



Zend_Sessionを利用する際にしてはいけないこと。
・session_start関数は使用しない。
・Zend_Session::start()使用やZend_Session_Namaspaces()の生成などは、Zend_Session関連のそのほかの操作の前には必ず処理をさせておく


view部分で、セッション名称やセッションIDをを取得するには、以下の関数から取得する。
セッション名:session_name();
セッションID:session_id();

2010年1月8日金曜日

ひさびさにフリーのER図作成ツール

以前からEclpiseで利用していたDBモデリングツールのClay(1.4.2)をEclipse3.5で使おうとしたら動かなかったので、別のものを探してみました。

とりあえず、PostgreSQLに対応していて、DDLが出力できるもの。
さらにER図の画像出力や、テーブル定義をドキュメント出力してくれるとうれしい。

[Clay MarkII]
http://www.azzurri.co.jp/ja/clay/index.html

Clayが2009/8くらいにMarkIIになってました。#ガンダムか?
試しに、旧バージョンのファイルを読み込ませてみたら、テーブルの配置がすべて左上になってました。
PostgreSQLの対応は7.3,7.4で旧版と変わらず。このあたり8.x対応になったりしないのかな?
見た目は前よりもリッチ感(?)があるように思えました

有償版はライセンスの形態が変更になっていて、従来のインストールベースから、プロジェクトベースになっており、お値段も8万4千円とお高くなってます。
前バージョンは会社でライセンスを買っていましたが(確か3万円弱だったような?)、1人か2人くらいで開発することが多いので、前バージョンよりも割高感があります。

前バージョンは直接ダウンロードできず、プラグインの入手方法は「注文番号を添えて問い合わせてください」って書いてありました。


[ERMaster]
http://ermaster.sourceforge.net/index_ja.html

使い方はClayとほとんど変わらず、迷わず使えました。

Entityの色やデザインを変更できたり、Entityに表示するレベルを変更できたりします。
ExcelやHTMLでテーブル定義書っぽいものを出力できるので、体裁を整えるにはいいかも。
あと、辞書機能は便利でした。
ClayMarkIIよりも好みにあっているので、とりあえずERMasterを使ってみようと思います。

本当はNetbeans6で利用できるものがあればよかったんだけど、見つからず。
知っている人がいたら教えてほしい。

2010年1月6日水曜日

ExtJS3.1がリリースされてました

IE6のメモリリークに関する対応がなされた模様。
その他、新しいUIも追加されているようです。

Zend Framework 1.9.6リリース

Zend Framework 1.9.6リリースがリリースされてました。
次は1.10.1になりそうです。