# php-02. PHPコーディング規約 ________________________________________ PHP-FIG — PHP Framework Interop Group - PHP-FIG https://www.php-fig.org/ ________________________________________ ## 1. 前提:理解しておきたい挙動 ________________________________________ 要点 ```text 1. PHPの値型ライクな型はCopy on Write - C#のstring型ライクな挙動 2. PHPの配列は値型ライク - なお、この方式を採用しているのは他だとPerlのみ 3. PHPのbool型への型変換はisEmptyOrIsZero的な挙動 4. PHPのbool型とnullの厳密比較は常にfalse 5. PHPの配列と連想配列は内部的には同一で混在できてしまう 6. 無名関数で外側の変数を利用するにはuse(&$outerVar)が必要 7. PHPの継承周りの挙動はC#とは静的・インスタンスの考え方が全く異なる ``` オートローダとuseに関して ```text クラス呼び出しの前提 - 完全修飾形式(/で始める呼び出し)ならば、C#と考え方は同一 - 相対修飾形式(/で始めない呼び出し)は、相対パスのような解決になる - useキーワードはC#のusingに近いが、末端の記述が必要 - これは、クラス名まで記述してクラス単位でuseすることを想定しているため - もっと言えば、スクリプト言語はこの方式が多い(jsもこの方式) オートローダに関して - オートローダなしでは、require_onceとuseで二重に似た記述を書くはめになる - オートローダを用意して一元管理することで、require_onceを自動化する ``` ________________________________________ ## 2. PHP Standards Recommendations ________________________________________ ### 2.1. PSR-0(要約) ```text 1. 名前空間とフォルダを合わせる 2. ファイル名はクラス名.php 3. 名前空間はOrganization\Product 4. 名前空間やクラス名にはアンダーバーを使用しないほうが楽 -(クラス名のアンダーバーはDIRECTORY_SEPARATORに変換される) ※ 改訂版のPSR-4では、上記より少し緩くなった 具体的には - フォルダ名はハイフン区切りで階層をまとめてもよい - フォルダ階層の末端側のsrc、libなどを追加してもよい - 前述2つの目的は、あるライブラリの名前空間が実質1つしかない場合に対する許容 - わざわざフォルダを階層化せず、末端側のlib、srcなどは省略してよい、ということ - アンダーバーの変換仕様は廃止 ``` ________________________________________ ### 2.2. PSR-1&2(要約) ファイル形式と全体記法 ```text 1. UTF-8 BOMなし 2. 改行はLF(PSR-12で追加) 3. 通常タグはは記載しないこと(PSR-12で追加) 5. クラス.phpはクラスを書く -(読み込んだだけで外部に影響与えてはならない) - グローバル直下のini_set - グローバル直下のecho - グローバル直下のrequire_once(オートローダを使用すること) 6. 1行に複数の文を書いてはならない(PSR-12で追加) ``` 命名規則と記法スタイル ```text 1. 予約語 : 小文字 2. クラス名 : UpperCamel 3. 定数 : UPPER_SNAKE 4. メソッド : camelCase 5. プロパティ: 自由だが統一。PHP4以前用のvarキーワードは禁止 6. インデントはスペース4つ 7. クラス、プロパティ、メソッド名はアンダースコアで始めてはいけない 8. 名前空間宣言、空行、use、空行、主コード 9. K&Rのスタイル - 関数定義以上の開始はオールマン - 制御ブロック以下の開始は同行 - if (expression) { 10. アクセス修飾子は省略してはならない 11. extendsとimplementsはクラス名と同じ行で記述 - (implementsの詳細は改行してよい) 12. switchで意図的なフォールスルーには// no break 13. abstract、finalはアクセス修飾子よりも前に書く ※ 改訂版はPSR-12(1と2の意味) ``` ________________________________________ ## 3. その他、よくある規約 ________________________________________ ### 3.1. 基本的な規約 コメント、変数展開、リテラル ```text 1. #による単行コメント禁止 2. 可変変数、文字列の変数展開パラメータは{}で囲む 3. 数値リテラルにおいて、8進数リテラル禁止 4. 文字列リテラルはどれでもよければ、シングルクォートを基本とする 5. ヒアドキュメントIDは、必ず"か'か明示する ``` 型と暗黙の型変換 ```text 1. 型のエイリアス(boolean, integer, double, real)禁止 - 関数の型宣言時に認識されないため、普段から使わないこと 2. 暗黙の型変換は、整数⇔浮動小数点間、アップキャストでのみ許容 3. 例えば、整数および浮動小数点型同士以外で、四則演算は禁止 4. 例えば、bool型と整数型、bool型と文字列型で、比較演算は禁止 5. 例えば、文字列同士以外で、文字列結合演算は禁止 ``` 演算子 ```text 1. マジカルインクリメントは非推奨 2. 配列以外の等価比較は、!==、===を使用すること(!=、==は禁止) 3. 三項演算子のネスト禁止(他の言語と挙動が違うため) 4. 宇宙船演算子(<=>)禁止 - 2021年現在はまだちょっと一般的ではない。3年後には一般的になるかも。他言語の採用状況は以下 - Perl1.0 - Ruby1.0 - C++2020 - C# なし(Comparison delegate) 5. 実行演算子(`コマンド`)禁止 6. エラー制御演算子(@)禁止 7. 文字列に対するブラケット[]による文字取り出し禁止 - マルチバイト時に想定通りにならない 8. 参照渡しは、CダブルポインタやC#ref渡しを実現したい時に使う - PHPの値型ライクはCopy on Writeなので通常用途では参照渡しは必要ない - foreachでも使ってよい ``` 配列と連想配列 ```text 1. 配列と連想配列を使い分けること。これらの混用・マージは禁止 - 内部的には同じ存在だが、使い分けたほうが好ましい 2. 配列や連想配列に対する+演算子禁止 3. 配列や連想配列の比較演算子は、!=か==のみ使ってよい(各要素の順序問わない比較) - 他の比較演算は挙動がわかりづらい - 厳密比較は参照比較ではない。各要素の順序考慮比較である。使いづらい 4. 配列に対する要素追加ブラケット$ary[] = は使用してよい ``` 制御文 ```text 1. 制御文で{}の省略禁止 2. 制御文での:~endXX記法禁止 3. switch文は==で比較されてしまうことを理解すること 4. switch文でのcontinue禁止 5. for文でのカンマによる複数式禁止 6. foreach内での要素追加・要素削除禁止 7. foreach($list as $item), foreach($list as $key => $val)を積極的に使う 8. foreach($list as &$item)、foreach($list as $key => &$val)は使ってよい - PHP固有の手法だが、使いやすく便利なため ``` グローバル変数と関数 ```text 1. グローバル変数禁止 2. 関数の型宣言を積極的に利用する 3. staticローカル変数の禁止 4. 可変長引数(...$args)の禁止 5. アンパック演算子(...$array)の禁止 ``` 標準ライブラリ ```text 1. 文字列操作には必ずmbを使用する - mb_strlen - mb_strtolower - mb_strtoupper - mb_substr - mb_ereg_replace - mb_split - mb_strpos 2. mbでない文字列操作の禁止 ``` その他 ```text 1. require_onceを利用する 2. 関数内インクルード禁止 3. 特別な理由がない限り、unset()禁止 4. yieldジェネレータは使用してよい ``` ________________________________________ ### 3.2. クラス周りの規約 調整中