#author("2020-06-22T17:03:31+09:00","default:fujioka","fujioka") #author("2020-06-22T17:04:09+09:00","default:fujioka","fujioka") http://www.infiniteloop.co.jp/docs/psr/psr-2-coding-style-guide.html *コーディングガイド [#l5e773bf] このガイドはPSR-1に準拠し、標準的なコーディング規約のためのスタイルガイドです。~ このガイドの目的は、複数メンバーがコードを読む際の認識のずれを抑えることです。 これはPHPコードをどのような書式にするかについて、ルールや期待値を共有することで実現します。~ スタイルルールは、様々なプロジェクトの共通内容から生み出されています。 様々な作者が複数プロジェクトを横断して協力しあうことで、全てのプロジェクトで有用なガイドライン策定の助けとなります。 従って、このガイド本来の利点は、ルール自体にはなくルールを共有することにあります。~ 文書内記載されている "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" 及び "OPTIONAL" は、RFC 2119で説明される趣旨で解釈してください。~ *概要 [#b908d242] PSR-1に準拠しなければなりません。 -インデントには4つのスペースを使用し、タブは使用してはいけません。 -行の長さに対してハードリミットがあってはいけません。ソフトリミットは120文字を上限とし、実際は80文字以内に抑えるべきです。 -名前空間定義のあとには空行を挟まなければいけません。またuse定義ブロックのあとにも同様に空行を挟まなければなりません。 -クラスの開き括弧は次の行に記述しなければなりません。また閉じ括弧は本文最後の次の行に記述しなければなりません。 -メソッドの開き括弧は次の行に記述しなければなりません。また閉じ括弧は本文最後の次の行に記述しなければなりません。 -アクセス修飾子は、全てのプロパティ、メソッドに定義しなければなりません。またabstractとfinalはアクセス修飾子の前に定義し、staticはアクセス修飾子の後に定義しなければなりません。 -制御構造の開始時は、その後に1スペースを開けなければなりません。メソッドや関数の呼び出しはスペースを開けてはいけません。 -制御構造の開き括弧は同じ行に記述しなければなりません。また閉じ括弧は本文最後の次の行に記述しなければなりません。 -制御構造の開始前にスペースがあってはいけません。また閉じる際もその前にスペースがあってはいけません。 **例 [#n82647ca] 以下は、概要内容を適用した例です。~ <?php namespace Vendor\Package; use FooInterface; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass; class Foo extends Bar implements FooInterface { public function sampleFunction($a, $b = null) { if ($a === $b) { bar(); } elseif ($a > $b) { $foo->bar($arg1); } else { BazClass::bar($arg2, $arg3); } } final public static function bar() { // メソッド本文 } } *一般 [#v1e8db12] **標準的なコーディング規約 [#eb5bd2f1] PSR-1に準拠しなければなりません。~ **ファイル [#s780b83e] 全てのPHPファイルの改行コードは、LFでなければなりません。~ 全てのPHPファイルは、最後に空行を入れなければなりません。~ PHPだけが書かれたファイルについては、終了タグ「?>」を省略しなければなりません。~ **行 [#k2e2ba8a] 行の長さに対してハードリミットがあってはいけません。~ 行の長さのソフトリミットは120文字を上限とします。 自動スタイルチェッカーはソフトリミットで警告しなければなりませんが、エラーを出してはいけません。~ 1行あたりの文字数が80文字を超えるべきではありません。超えてしまう場合は80文字以内の複数の行に分割するべきです。~ 行末に空白文字列を含んではいけません。~ 空行は読みやすさや関連するコードのまとまりを示すために適切に加えて構いません。~ 1行に複数のステートメントがあってはいけません。~ **インデント [#hc96474b] インデントは4つのスペースとしなければなりません。タブによるインデントは用いてはなりません。((スペースとタブを混在せず、スペースのみとすることにより差分表示やパッチ、履歴や注釈がずれる問題を回避できます。 スペースのみを使うことで、微妙なサブインデントの位置合わせを容易とすることができます。))~ **予約語とTrue/False/Null [#pa6e17e2] PHPの予約語は小文字で使用しなければなりません。~ PHP定数であるtrue、falseそしてnullは小文字でなければなりません。~ *名前空間とuse演算子による定義 [#i2a426fc] 名前空間の定義の後に空行が必要です。~ use定義は、名前空間宣言の後でなければなりません。~ 定義ごとにuse演算子が必要です。~ use定義のブロックの後には空行が必要です。~ 例:~ <?php namespace Vendor\Package; use FooClass; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass; // ... additional PHP code ... *クラス、プロパティ及びメソッド [#r635360d] ここでのクラスは、全ての一般クラス、インターフェイス、traitを含みます。~ **ExtendsとImplements [#z4730f40] extendsとimplementsは、クラス名と同じ行で定義されなけれなりません。~ クラスの開き括弧は次の行に記述しなければなりません。また閉じ括弧は本文最後の次の行に記述しなければなりません。~ <?php namespace Vendor\Package; use FooClass; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass; class ClassName extends ParentClass implements \ArrayAccess, \Countable { // constants, properties, methods } implements定義は、インデントにより揃えることで、複数行に分割しても構いません。 その際、最初の定義も次の行からはじめるものとし、1行に1つのインターフェイスを定義しなければなりません。~ <?php namespace Vendor\Package; use FooClass; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass; class ClassName extends ParentClass implements \ArrayAccess, \Countable, \Serializable { // constants, properties, methods } **プロパティ [#md3b2a75] アクセス修飾子は、全てのプロパティに定義しなければなりません。~ プロパティ定義に、varは使用してはいけません。~ ステートメントあたりに複数のプロパティ定義があってはなりません。~ プロパティ名に、protectedまたはprivateを示すためにシングルアンダースコアを使用すべきではありません。~ 具体的なプロパティ定義は下記のようになります。~ <?php namespace Vendor\Package; class ClassName { public $foo = null; } **メソッド [#t54977ed] アクセス修飾子は、全てのメソッドに定義しなければなりません。~ メソッド名に、protectedまたはprivateを示すためにシングルアンダースコアを使用すべきではありません。~ メソッド名の後ろにスペースを使用してはいけません。 開き括弧は次の行に記述しなければなりません。また閉じ括弧は本文最後の次の行に記述しなければなりません。 開き括弧の後ろや、閉じ括弧の前にスペースがあってはいけません。~ メソッド定義は下記のようになります。 括弧、カンマ、スペースの位置に注意してください。~ <?php namespace Vendor\Package; class ClassName { public function fooBarBaz($arg1, &$arg2, $arg3 = []) { // method body } } **メソッドの引数 [#yb97df6e] 引数リストでは、それぞれのカンマの前にスペースがあってはいけません。 また各カンマの後ろには1スペースおかなければなりません。~ デフォルト値を持つ引数は、引数リストの最後に配置しなければなりません。~ <?php namespace Vendor\Package; class ClassName { public function foo($arg1, &$arg2, $arg3 = []) { // method body } } 引数リストは、インデントにより揃えることで、複数行に分割しても構いません。 その際、最初の定義も次の行からはじめるものとし、1行に1つの引数を定義しなければなりません。~ 引数リストを複数行の分割配置としている場合、閉じ括弧と開き中括弧の間にはスペースを含め同じ行に配置する必要があります。~ <?php namespace Vendor\Package; class ClassName { public function aVeryLongMethodName( ClassTypeHint $arg1, &$arg2, array $arg3 = [] ) { // method body } } **abstract, final, and static [#g8df253e] abstractとfinalはアクセス修飾子の前に定義しなければなりません。~ staticはアクセス修飾子の後に定義しなければなりません。~ <?php namespace Vendor\Package; abstract class ClassName { protected static $foo; abstract protected function zim(); final public static function bar() { // method body } } **メソッド及び関数の呼び出し [#p387f4ef] メソッドや関数の呼び出し時は、メソッドや関数名と開き括弧の間にスペースがあってはなりません。 また開き括弧の後や、閉じ括弧の前にスペースがあってもいけません。 引数リストの前にスペースがあってはなりませんが、各カンマの後に1スペースが必要です。~ <?php bar(); $foo->bar($arg1); Foo::bar($arg2, $arg3); 引数リストは、インデントにより揃えることで、複数行に分割しても構いません。 その際、最初の定義も次の行からはじめるものとし、1行に1つの引数を定義しなければなりません。~ <?php $foo->bar( $longArgument, $longerArgument, $muchLongerArgument ); *制御構造 [#p41f0d16] 制御構造の一般的なスタイルルールや下記の通りです。~ -制御構造キーワードの後には1スペースを設けなければなりません。 -開き括弧の後にスペースを配置してはなりません。 -閉じ括弧の前にスペースを配置すべきではありません。 -開き括弧と閉じ中括弧の間にはスペースを挟まなければなりません。 -構造本文は1インデント下げなければなりません。 -閉じ括弧は構造本文の後に改行して配置しなければなりません。 -各構造本文は、中括弧で囲わなければなりません。 これは構造の見え方を標準化し、追加実装等が発生した際のエラーを抑えます。 **if, elseif, else [#odeab0d3] if制御について例えば下記のようになります。 括弧、スペースの位置に注意してください。elseやelseifの前後括弧は同じ行に配置されます。~ <?php if ($expr1) { // if body } elseif ($expr2) { // elseif body } else { // else body; } 全てのキーワードが1単語に見えるように、else ifではなくelseifを使うべきです。~ **switch, case [#ve92faa9] switch制御は下記のようになります。 括弧、スペースの位置に注意してください。 case文はswitchからインデントし、break(またはその他の終端キーワード)は、case内本文と同じレベルのインデントで揃えなければなりません。 また意図的に処理スルーさせる場合は「// no break」等、コメントしなければなりません。~ <?php switch ($expr) { case 0: echo 'First case, with a break'; break; case 1: echo 'Second case, which falls through'; // no break case 2: case 3: case 4: echo 'Third case, return instead of break'; return; default: echo 'Default case'; break; } **while, do while [#j363df7e] while文は下記のようになります。 括弧、スペースの位置に注意してください。~ <?php while ($expr) { // structure body } 同様に、do while文は下記のようになります。 括弧、スペースの位置に注意してください。~ <?php do { // structure body; } while ($expr); **for [#mca634cf] for文は下記のようになります。 括弧、スペースの位置に注意してください。~ <?php for ($i = 0; $i < 10; $i++) { // for body } **foreach [#oe684b95] foreach文は下記のようになります。 括弧、スペースの位置に注意してください。~ <?php foreach ($iterable as $key => $value) { // foreach body } **try, catch [#m2e03651] try catch文は下記のようになります。 括弧、スペースの位置に注意してください。~ <?php try { // try body } catch (FirstExceptionType $e) { // catch body } catch (OtherExceptionType $e) { // catch body } **Closure [#b66534f5] クロージャは、functionキーワードの後にスペースを、useキーワードの前後にスペースが必要です。~ 開き括弧は同じ行に記述しなければなりません。また閉じ括弧は本文最後の次の行に記述しなければなりません。~ 引数または変数リストの開き括弧の後にスペースがあってはなりません。 また閉じ括弧の前にスペースがあってもなりません。~ 引数または変数リストの前にスペースがあってはなりませんが、各カンマの後に1スペースが必要です。~ デフォルト値を持つ引数は、引数リストの最後に配置しなければなりません。~ クロージャ定義は下記のようになります。 括弧、スペースの位置に注意してください。~ <?php $closureWithArgs = function ($arg1, $arg2) { // body }; $closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) { // body }; 引数または変数リストは、インデントにより揃えることで、複数行に分割しても構いません。 その際、最初の定義も次の行からはじめるものとし、1行に1つの引数または変数を定義しなければなりません。~ 引数または変数リストを複数行の分割配置としている場合、閉じ括弧と開き中括弧の間にはスペースを含め同じ行に配置する必要があります。~ 引数リストが無く、及び変数リストが複数行に渡る場合のクロージャ実装は下記のようになります。~ <?php $longArgs_noVars = function ( $longArgument, $longerArgument, $muchLongerArgument ) { // body }; $noArgs_longVars = function () use ( $longVar1, $longerVar2, $muchLongerVar3 ) { // body }; $longArgs_longVars = function ( $longArgument, $longerArgument, $muchLongerArgument ) use ( $longVar1, $longerVar2, $muchLongerVar3 ) { // body }; $longArgs_shortVars = function ( $longArgument, $longerArgument, $muchLongerArgument ) use ($var1) { // body }; $shortArgs_longVars = function ($arg) use ( $longVar1, $longerVar2, $muchLongerVar3 ) { // body }; 引数として、クロージャが関数またはメソッドに直接使用される場合もまた、ルールが適用されることに注意してください。~ <?php $foo->bar( $arg1, function ($arg2) use ($var1) { // body }, $arg3 ); **その他 [#x0720944] 本スタイルガイドでは、意図的に省略しているスタイルやプラクティスが多くあります。 例えば下記のような幾つかについては、ここでは明記していません。~ -グローバル変数と定数について -関数群の定義について -演算と代入について -行間の配置 -コメントとドキュメントブロックについて -クラス名の接頭辞と接尾辞について -ベストプラクティスについて なお、本スタイルガイドは将来的に様々なスタイルやプラクティスの登場に応じて改定・拡張をできるものとします。~ RIGHT:Today : &counter(today); / Yesterday : &counter(yesterday); / Total : &counter(total);