[[FrontPage]] >

* PHP5ベストプラクティス [#u9c282c1]
#contents

** ビルドの自動化 [#edf96399]
-[[phing]](PHP版Ant)により、ユニットテスト([[PHPUnit]])、パッケージング(PEARパッケージ)、ドキュメンテーション([[PhpDocumentor]])などが自動化できます。

** ドキュメンテーション [#jf833c4e]
-PhpDocumentor で、APIドキュメントを最新に保ちます。

** ディレクトリ構成とファイル名 [#oebdef1b]
-クラスが定義されているファイルの場所が分かるように、ファイルへのパスはクラス名に反映させるようにします(PEARの規約と同様)。したがって、ディレクトリ階層は適当な深さ(2〜4階層ほど)で、各ディレクトリ名は大文字で始め、コンパクトな長さにします。
-クラス名は、ファイルへのパスの区切り文字('/'や'\')をアンダースコア('_')に置換し、拡張子を除いたものになります。
|>|>|~例|
|~1|~ファイルパス|Commons/Lang/Builder/ToStringBuilder.php|
|~|~定義されているクラス|Commons_Lang_Builder_ToStringBuilder|
|~2|~ファイルパス|Commons/Lang/Time/StopWatch.php|
|~|~定義されているクラス|Commons_Lang_Time_StopWatch|
-ファイル名は、クラスを定義している場合には(クラス名に反映させるので)大文字で始め、実行スクリプトの場合には小文字で始めます。拡張子は、''.php'' のみを用います。''.class.php'' は冗長ですし、定数定義に define は使用しない(代わりに const を使う)ので、''.inc'' を使う場面もないでしょう。

** 命名規約 [#l9f64277]
-クラス名は、上記の通りファイルへのパスを反映させます。
-他のものについては、PEARの規約に準じます。

** コーディング [#f05a526f]

*** PHP5の既知の問題 [#b9fc882d]
-[[spl関数の問題]]
-[[自己参照]]

*** [[オブジェクト指向言語ではないPHP5の特徴]] [#ocd54952]

*** マルチバイト文字列対応 [#v93446bf]
-[[文字列処理関数の互換性問題]]
-[[文字列処理関数の謎の仕様]]

*** 定数 [#v117f46b]
-定数は define せずに、''抽象クラスまたはインタフェイスの中の const 変数で定義''します。迂闊な二重定義を防ぐことができ、定義されている場所を見失うこともありません。

*** プロパティ [#aeef94ca]

*** 比較 [#s42ff68a]
-基本的に、''同じ型同士で比較''するようにします。
-非オブジェクト型の比較(同値性比較)の場合には、''常に型を考慮する比較演算子(===、!==)''を用います。
-オブジェクト型の比較の場合には、同値性比較には各クラスに ''equals()'' メソッドを用意し、それを用い、同一性比較には''同じクラスの同じインスタンスを参照する場合''を比較する演算子(''===''、''!=='')を用います。
-比較演算子 == と != は型を考慮しないので(オブジェクトの場合にはクラスを考慮しますが紛らわしいので)、使用を控えます。

*** __toString()メソッドのオーバーライド [#kdb519c6]
-クラスでは、__toString()メソッドをオーバーライドし、有益な文字列情報を出力するようにします。オブジェクト状態のロギングが容易になります。
-&COLOR(red){以下の例にある ToStringBuilder は、array の内容を展開し文字列化しますが、array の要素に自己参照や参照ループがある場合、無限ループを回避することができませんので、ご注意ください(自己参照を持つ array の同一性比較自体が要素比較の走査によりエラーになるので)。};
 require_once 'Commons/Lang/Builder/ToStringBuilder.php';
 ...
     public function __toString() {
         $builder = new Commons_Lang_Builder_ToStringBuilder($this);
         return $builder
             ->append('_startTime', $this->_startTime)
             ->append('_stopTime', $this->_stopTime)
             ->__toString();
     }

*** プログラムの計測 [#sf3859e9]
-パフォーマンスに注意が必要な処理には、時間計測のコードを入れるようにします。
 require_once 'Commons/Lang/Time/StopWatch.php';
 ...
 $stopWatch = new Commons_Lang_Time_StopWatch();
 $stopWatch->reset();
 $stopWatch->start();
 ...    // 処理
 $stopWatch->stop();
 $elapsedTime = $stopWatch->getTime();            // 156(ミリ秒)
 $elapsedTimeStr = $stopWatch->__toString();    // '0:00:00.156'

*** デバッグセッションの活用 [#s3b6188f]
-[[Eclipse(PDT)によるデバッグ]]

** ロギング [#xfa33d31]
-log4php のようなカテゴリとレベル機構のあるフレームワークを利用します。
--カテゴリ名には、(ディレクトリ階層を反映した)クラス名のアンダースコア('_')をドット('.')に置換したものを指定します。これにより、各ディレクトリ階層でログ出力を制御することができるようになります。
|>|~例|
|~クラス名|Commons_Lang_Time_StopWatch|
|~カテゴリ名|Commons.Lang.Time.StopWatch|

*** [[PHP Commons Logging>CommonsLogging]] を利用したログ出力 [#t68a8941]
-[[PHP Commons Logging>CommonsLogging]] を利用することにより、ログ出力コードを変更せずに実際にログ出力するロギングフレームワークを切替えることが可能になります。
-詳細は[[こちら>CommonsLogging]]。

** ユニットテスト [#x0c8a306]

***ツール [#f4d54412]
-[[Eclipse(PDT)でのユニットテスト]]

** DI [#l12f1f3a]


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS