コーディング規約

この文書は Nette を開発するときの決まりとおすすめをまとめたものです。Nette にコードを貢献するときは、これに従わなければなりません。いちばん簡単なやり方は、既存のコードをまねることです。目指すのは、すべてのコードがひとりの人によって書かれたように見えることです。

Nette のコーディング規約は PSR-12 Extended Coding Styleに沿っていますが、大きな違いが 2 つあります。字下げに空白ではなくタブを使うことと、クラスの定数に PascalCaseを使うことです。

これらの決まりの多くは Nette Coding Standardの道具が自動的に確かめて直せるので、手で確かめる必要はありません。

全般の決まり

  • すべての PHP のファイルには declare(strict_types=1) を入れます
  • 読みやすさのために、メソッドのあいだは空行 2 つで区切ります
  • 黙らせる演算子(@)を使う理由は書き残さなければなりません。@mkdir($dir); // @ - directory may exist
  • 緩い型の比較の演算子(つまり ==!= など)を使うなら、その意図を書き残さなければなりません。// == to accept null
  • 例外のクラスは exceptions.php という名前のひとつのファイルに複数書けますし、enum は enums.php に複数書けます
  • インターフェースではメソッドの可視性を書きません。いつも public だからです
  • すべてのプロパティ、戻り値、パラメータには型を指定しなければなりません。逆に final の定数には型を決して書きません。自明だからです
  • 文字列は単一引用符で囲むべきです。ただしその文字列自身がアポストロフィを含む場合は別です

名前の付け方

改行と波かっこ

Nette のコーディング規約は PSR-12(または PER Coding Style)に沿っていますが、いくつかの点でそれを細かく定めたり変えたりしています。

  • アロー関数はかっこの前に空白を入れずに書きます。つまり fn($a) => $b です
  • 種類の違う use の import の文のあいだに空行は要りません
  • 関数やメソッドの戻り値の型と、開く波かっこは、いつも別々の行に置きます。
	public function find(
		string $dir,
		array $options,
	): array
	{
		// method body
	}

開く波かっこを別の行に置くのは、関数やメソッドの見出しを本体から目で分けるために大事です。見出しが 1 行なら区切りははっきりしています(左の図)。複数行なら、PSR では見出しと本体が溶け合ってしまいますが(真ん中)、Nette の規約では分かれたままです(右)。

文書のかたまり(phpDoc)

いちばんの決まりはこれです。価値を足さずに、パラメータの型や戻り値の型のような見出しの情報を重ねて書かないこと

クラスの定義の文書のかたまりです。

  • クラスの説明から始めます
  • 続いて空行
  • 続いて @property(あるいは @property-read@property-write)のアノテーションを 1 行にひとつずつ。書き方は、アノテーション、空白、型、空白、$name
  • 続いて @method のアノテーションを 1 行にひとつずつ。書き方は、アノテーション、空白、戻り値の型、空白、name(type $param, ...)
  • @author のアノテーションは書きません。誰が書いたかはソースコードの履歴に残ります
  • @internal@deprecated のアノテーションは使えます
/**
 * MIME message part.
 *
 * @property string $encoding
 * @property-read array $headers
 * @method string getSomething(string $name)
 * @method static bool isEnabled()
 */

@var のアノテーションだけを含むプロパティの文書のかたまりは、1 行に書くべきです。

/** @var string[] */
private array $name;

メソッドの定義の文書のかたまりです。

  • メソッドの短い説明から始めます
  • 空行は入れません
  • @param のアノテーションを 1 行にひとつずつ
  • @return のアノテーション
  • @throws のアノテーションを 1 行にひとつずつ
  • @internal@deprecated のアノテーションは使えます

どのアノテーションのうしろにも空白をひとつ置きます。ただし @param だけは、読みやすさのために空白 2 つを置きます。

/**
 * Finds a file in directory.
 * @param  string[]  $options
 * @return string[]
 * @throws DirectoryNotFoundException
 */
public function find(string $dir, array $options): array

大域の関数と定数

大域の関数と定数は先頭のバックスラッシュなしで書きます。つまり \count($arr) ではなく count($arr) です。PHP が最適化できる関数には、コンパイラがより効率よく翻訳できるよう、ファイルの先頭に use function を足します。countstrlenis_arrayis_stringis_scalarsprintf などの関数がそれに当たります。import のかたまりをこぢんまり保つために、関数は 1 行に並べます。

use Nette;
use function count, is_array, is_scalar, sprintf;

ときには、その値を知ることがコンパイラの助けになる定数も import します。

use const PHP_OS_FAMILY;

空白ではなくタブ

タブには空白に対していくつかの利点があります。

  • 字下げの大きさをエディタでも ウェブ でも変えられます
  • 書き手の好みの字下げの大きさをコードに押し付けないので、コードが持ち運びやすくなります
  • ひと打ちで入力できます(タブを空白に変えるエディタに限らず、どこでもです)
  • 字下げこそがその役目です
  • 目の不自由な仲間や見えない仲間の必要に応えます

プロジェクトでタブを使うことで幅を変えられるようにしています。多くの人には要らないことに見えるかもしれませんが、目の不自由な人には欠かせません。

点字ディスプレイを使う目の見えないプログラマーにとって、空白ひとつは点字のマスひとつです。ですから既定の字下げが空白 4 つなら、3 段めの字下げは、コードが始まる前に貴重な点字のマスを 12 個も無駄にします。ノートパソコンでもっともよくある 40 マスのディスプレイなら、それは使えるマスの 4 分の 1 以上を、何の情報も与えずに無駄にすることになります。