社畜系WEBエンジニアの消耗戦

読者です 読者をやめる 読者になる 読者になる

社畜系WEBエンジニアの消耗戦

修羅の国でせっせと働く社畜系WEBエンジニアのブログ

PHP The Right Wayを読んでPHPを基礎からしっかり学ぶ〜コーディング規約編

PHP The Right Wayを読み進めながら、PHPの基礎力を高めつつ派生知識を習得していくシリーズ。本エントリではコーディング規約について扱います。

参考文献

PHP: The Right Way

成果物

  • PHPのコーディング規約に関する知識
  • エディタでのコーディング規約チェックの自動化
  • エディタでのコード整形の自動化
  • CIでのコード整形の自動化

PHPのコーディング規約

PHPのコーディング規約はphp-figによってPSRという規約にまとめられており、その種別によりPSR-0〜分類されている。よく出てくるコーディング規約としては以下の4種類、PSR-0は非推奨なので、実質3種類である。

  • PSR-0(非推奨)
  • PSR-1(PSR-2に内包)
  • PSR-2
  • PSR-4(PSR-0の後継規約)

PSRは他にもあり、 PHP Standards Recommendations - PHP-FIGにドラフト状態のものも含めてまとめられている。

ちなみに僕が現在使っているLaravelでは、PSR-2準拠、PSR-4準拠であることが明記されている( Contribution Guide - Laravel - The PHP Framework For Web Artisans )が、中にはフレームワーク独自の規約を持っているものもある(クソかよ)。

それぞれの規約に関して見ていこう。

PSR-1

PSR-1: Basic Coding Standard - PHP-FIG

PSR-1は、Basic Coding Standardという名の通り、ごくごく基本的な内容が列挙されています。日本語訳してくれている方がいますので、ありがたく参考にさせていただきます。

参考:PSR-1 基本コーディング規約(日本語)|北海道札幌市のシステム開発会社インフィニットループ

PHPコードは「<?php」及び 「<?=」タグを使用しなければなりません。

特筆すべき事はないです。その通り。

文字コードUTF-8(BOM無し)を使用しなければなりません。

特筆すべき事はないです。その通り。

シンボル(クラス、関数、定数など)を宣言するためのファイルと、副作用のある処理(出力の生成、ini設定の変更など)を行うためのファイルは、分けるべきです。

これ、ちょっと意味するところが難しい。こちらはNGパターン。

<?php
// side effect: change ini settings
ini_set('error_reporting', E_ALL);

// side effect: loads a file
include "file.php";

// side effect: generates output
echo "<html>\n";

// declaration
function foo()
{
    // function body
}

こちらがOKパターン。

<?php
// declaration
function foo()
{
    // function body
}

// conditional declaration is *not* a side effect
if (! function_exists('bar')) {
    function bar()
    {
        // function body
    }
}

よく言われる言葉で言うとするならば、「疎結合」にしましょうってことですかね棒。

名前空間、クラスについてはPSR-0に準拠しなければなりません。

特筆すべき事はないです。その通り。

クラス名は、StudlyCaps(単語の先頭文字を大文字で表記する記法)記法で定義しなければなりません。

特筆すべき事はないです。その通り。

クラス定数は全て大文字とし、区切り文字にはアンダースコアを用いて定義しなければなりません。

特筆すべき事はないです。その通り。

メソッド名はcamelCase記法で定義しなければなりません。

特筆すべき事はないです。その通り。

以上がPSR-1の内容になります。特に難しいことは言ってないですね。

PSR-2

PSR-2: Coding Style Guide - PHP-FIG

こちらはCoding Style Guideということで、実際にコーディングする上で最も意識する部分になります。こちらに関しても日本語訳してくれている方がいますので、ありがたく参考にさせていただきます。

参考:PSR-2 コーディングガイド(日本語)|北海道札幌市のシステム開発会社インフィニットループ

PSR-1に準拠しなければなりません。

特筆すべき事はないです。その通り。

インデントには4つのスペースを使用し、タブは使用してはいけません。

特筆すべき事はないです。その通り。タブキーで4スペースが入力されるようにエディタ設定をするのが得策でしょう。

行の長さに対してハードリミットがあってはいけません。ソフトリミットは120文字を上限とし、実際は80文字以内に抑えるべきです。

長過ぎる行は行を分けなさいということ。

名前空間定義のあとには空行を挟まなければいけません。またuse定義ブロックのあとにも同様に空行を挟まなければなりません。

特筆すべき事はないです。その通り。

クラスの開き括弧は次の行に記述しなければなりません。また閉じ括弧は本文最後の次の行に記述しなければなりません。

特筆すべき事はないです。その通り。

メソッドの開き括弧は次の行に記述しなければなりません。また閉じ括弧は本文最後の次の行に記述しなければなりません。

特筆すべき事はないです。その通り。

アクセス修飾子は、全てのプロパティ、メソッドに定義しなければなりません。またabstractとfinalはアクセス修飾子の前に定義し、staticはアクセス修飾子の後に定義しなければなりません。

特筆すべき事はないです。その通り。

ただここで僕の不勉強ぶりが発揮されます。キーワードの意味を補足説明しておきます。

abstract:クラスの抽象化を行う為のキーワード。abstractキーワードをつけてクラス宣言を行うことでクラスを抽象化でき、また、abstractキーワード付きで定義されたメソッドは外観のみで実装を定義することはできない。これらのメソッドは継承先のクラスで必ず定義されなければならない。

final:クラスおよびメソッドをfinalキーワード付きで定義可能。finalキーワードをつけて宣言したクラスは継承できない、また、finalキーワードをつけて宣言したメソッドは継承先でオーバーライドできません。

このあたりはPHP公式のドキュメントを見たほうがわかりやすいかもしれませんね。

少し話題はそれますが、interfaceabstractの使い分けに関する良記事を見つけたので、紹介しておきます。

参考: PHPのinterfaceとabstractを正しく理解して使い分けたいぞー ::ハブろぐ

制御構造の開始時は、その後に1スペースを開けなければなりません。メソッドや関数の呼び出しはスペースを開けてはいけません。

特筆すべき事はないです。その通り。

制御構造の開き括弧は同じ行に記述しなければなりません。また閉じ括弧は本文最後の次の行に記述しなければなりません。

特筆すべき事はないです。その通り。

制御構造の開始前にスペースがあってはいけません。また閉じる際もその前にスペースがあってはいけません。

特筆すべき事はないです。その通り。

PSR-4

PSR-4: Autoloader - PHP-FIG

PSR-0の後継のオートローディングに関する規約です。ペーペーエンジニアは自分でcomposer書いたりしないので、一旦は忘れておいても問題ないでしょう。

規約全部は覚えられない問題

おっしゃる通りです。こんなもの、覚えてられません。覚えられないならどうするか。エディタに任せたり、外部サービスに頼ったりするのが常套手段です。

方向性としては、エディタに自動チェック、自動整形を入れて、さらに外部サービスでチェックするというやり方で設定するのが、今の僕のベストプラクティス。

エディタの拡張を設定する

僕はAtomを使っているので、Atomのパッケージを使っていきます。以下辺りのパッケージを入れれば、基本的には問題ありません。ガンガン警告が出まくる、かつ、ファイル保存時に自動的に整形される(設定次第)ので、ほぼ強制的にPSR準拠のコードを書かされることになります。

  • atom-beautify
  • linter
  • linter-php
  • linter-phpcs
  • linter-phpmd

警告出まくりつらたん。

CIで漏れを完全になくす

StyleCI - The PHP Coding Style Service

Publicなリポジトリであれば、無料でStyleCIを利用することができます。エディタでの整形漏れのファイル(CLIで自動生成しただけのファイル等)があったとしても、機械的にチェックしまくるので絶対にもれない。最高。しかも、自動でPR投げてくれる。設定値次第では自動でマージもしてくれちゃう(僕の場合は手動でマージ設定)。

ただ、ほぼデフォルトのLaravelプロジェクト放り込んだらいくつかuseしてるのが消えたんですけど大丈夫なんですかねこれ?ま、動かなかったらそれはその時。

完全に余談ですが、バッジもつけられます。今までつけたことなかったから、クソ感動。

StyleCI Status

もちろんSlackへの通知も完備。と思ったらSlack通知は有料プランからでした。オワタ。

おわりに

とりあえずPSRの理解も出来たし、コーディングする上ではなんの労力も掛けずにPSR準拠のコードを書くことができるようになりました。こういう地味に手間のかかる部分を先に自動化できていると、後で非常に楽できますね。

それではよきPSRライフを。