WP STAGING の開発に参加したい場合は、以下のコーディングガイドラインとベストプラクティスをご確認ください。
- PSR を使用してください。https://www.php-fig.org/psr/
- 短い Array 構文 [] を使用してください。
- 変数名には camelCase を使用してください。
- クラス名には StudlyCaps を使用してください。
- ファイル名とフォルダ名にはアンダースコアを使用してください。
- インライン条件を避けてください。
- 略語はめったに使用しないでください! チームに承認されていない略語は使用せず、プロパティやメソッドに名前を付ける際に一般的に普及していない独自の略語を発明しないでください。
- クラス、メソッド、プロパティの名前は、その目的を正確に説明する必要があります。
クリーンコード
- 散らかった状態を所有する総コストは時間とともに複利化します。
- レガシーシステムをゼロから再構築するのは非常に困難です。リファクタリングと段階的な改善のほうが、取るべき良い経路であることがよくあります。
- 散らかったコードベースでは、数時間で済むはずのタスクを完了するのに数日から数週間かかることがあります。
- 速く進むために時間をかけてください。
- クリーンコードは 1 つのことをうまく行います。悪いコードは多くのことをしようとします。
- クリーンコードは十分にテストされています。
- よく書かれたコードを読むと、すべての関数が期待どおりのことを行います。
- 数十年の経験を持つ誰かが教えている原則に同意しない場合、それを無視する前に少なくとも彼らの視点を考慮するのが良いでしょう。
- コードは書かれるよりはるかに頻繁に読まれます。
- 読みやすいコードは変更しやすいです。
- コードベースを見つけたときよりも良い状態で残してください (ボーイスカウトの法則)。
コメントと docBlock
- コメントは嘘をつくことがあります。最初から間違っているか、当初は正確でも関連コードが変わるにつれて時間が経って古くなることがあります。たとえば、メソッドの名前を変更したりリファクタリングしたりした場合は、コメントがまだ有効か常に確認する必要があります。
- コメントは何が起きているかを説明するのではなく、なぜそのように書かれているかを説明するために使用してください。
- 多くの場合、明確に名前が付けられた変数を使用し、コードのセクションを明確に名前が付けられた関数に抽出することで、コメントを回避できます。
- 検索しやすいよう、TODO コメントを一貫した方法で接頭辞付けしてください。TODO コメントを定期的に見直してクリーンアップしてください。
- docBlock を使うためだけに使わないでください。メソッドが何をするか、どんな引数を取るか、何を返すかを説明するコメントは、しばしば冗長で、最悪の場合は誤解を招きます。
- コメントは、それを読む人が必要とする関連情報と文脈をすべて含むべきです。コメントを書くときに怠惰だったり曖昧だったりしないでください。
- ジャーナルコメントとファイル作成者コメントは、バージョン管理と git blame があるため不要です。
- デッドコードをコメントアウトしないでください。単に削除してください。将来そのコードが必要になると思うなら、それがバージョン管理の役目です。
- 必要なだけコメントし、可能な限り少なくしてください。メソッドを書いて、それにコメントを書きたい強い圧力を感じる場合、ほとんどの場合、メソッド名が十分明確ではないか、コードが複数のことを行っています。その場合、コメントを書く前にリファクタリングを検討してください。
コードスタイル
二項演算子のスペース
二項演算子「=」と「=>」はスペースで囲む必要があります。IDE のコードスタイル設定には、次のようにキー値の代入を整列できる自動整形オプションがあります:
$array = [
$var => 'foo',
$varvar => 'foo'
];
$var = 1;
$var100 = 100;
$var2000 = 2000;
これは類似コードの大きな部分を読みやすくする巧妙なテクニックです。
ヨーダ条件
読みやすさのため、ヨーダ条件を使用しないことに投票しました。
非推奨:
if ( true === $var ) {}
推奨:
if ( $var === true ) {}
ネイティブ関数・定数の呼び出し
ネイティブ呼び出しは、解決を高速化するために関数・定数の呼び出しの前に先頭のバックスラッシュ (\) を追加する手法です。これにより PHP は関数や定数が名前空間からのものかネイティブなものかをチェックする必要がなくなります。
読みやすさのため、コードベースでエラーを起こしやすくなることを避けるため、ネイティブ関数・定数呼び出し手法を使用しないことに投票しました。
ただし、場合によっては慎重かつ賢明に使用することは許可されます。
非推奨:
if ( \is_array($var) ) {}
if ( \PHP_SAPI === 'cli') {}
推奨:
if ( is_array($var) ) {}
if ( PHP_SAPI === 'cli') {}
名前空間とクラス名
オブジェクト指向プログラミング (OOP) の原則によれば、クラス名はシステム内のオブジェクトや概念を表すため、名詞である必要があります。これにより、他の開発者がコードをより読みやすく、理解しやすくなります。
ただし、PHP を含む一部のプログラミング言語では、動詞をクラス名として使用できます。これらの場合、動詞は通常クラスがオブジェクトではなくアクションやふるまいを表すことを示す方法として使用されます。
たとえば、「Mailer」という名前のクラスはメールを送信するオブジェクトを表すかもしれませんが、「SendMail」という名前のクラスはメールを送信するふるまいを表すかもしれません。動詞をクラス名として使用することは技術的には許可されていますが、コードが読みにくく理解しにくくなる可能性があり、名詞を使用することが一般的に推奨されます。
- 名前空間とクラス名には a-z、A-Z、0-9 の文字のみが許可されます。
- 名前空間は通常 UpperCamelCase で書かれますが、確立された名前と略語に対してはバリエーションが許可されます。
- クラス名は常に
UpperCamelCaseで書かれます。 - 非修飾クラス名は、名前空間なしでも文字通りに意図されている必要があります。
- 名前空間の主な目的は分類と順序付けです。
- クラス名は名詞でなければならず、決して形容詞ではいけません。
- 抽象クラスの名前は「Abstract」という単語で始まる必要があり、アスペクトのクラス名は「Aspect」という単語で終わる必要があります。
名前空間とクラスの不正な命名:
| 完全修飾クラス名 | 非修飾名 | 備考 |
|---|---|---|
| WPStaging\Framework\Session\Php | Php | このクラスは PHP の表現ではありません |
| WPStaging\Framework\Cache\Backend\File | File | このクラスはファイルを表していません! |
| WPStaging\Framework\Session\Interface | Interface | 許可されていません、「Interface」は予約語です |
| WPStaging\Framework\Controller\Default | Default | 許可されていません、「Default」は予約語です |
| WPStaging\Framework\Objects\Manager | Manager | 「Manager」だけでは曖昧すぎます |
名前空間とクラスの正しい命名:
| 完全修飾クラス名 | 非修飾名 | 備考 |
|---|---|---|
| WPStaging\Framework\Util\FileSystem | FileSystem | これは FileSystem です |
| WPStaging\Framework\Cache\Backend\FileBackend | FileBackend | File Backend |
| WPStaging\Framework\Session\SessionInterface | SessionInterface | セッションのインターフェイス |
| WPStaging\Framework\StandardController | StandardController | 標準コントローラー |
| WPStaging\Framework\ObjectManager | ObjectManager |
名前空間とクラスの命名のエッジケース:
| 完全修飾クラス名 | 非修飾名 | 備考 |
|---|---|---|
| WPStaging\Framework\Mvc\ControllerInterface | ControllerInterface | 結果として、このインターフェイスは Controller サブ名前空間内のすべてのコントローラーに属します |
| WPStaging\Framework\Mvc\Controller\ControllerInterface | より良い | |
| WPStaging\Framework\Cache\AbstractBackend | AbstractBackend | ここでも同様: 実際にはこのクラスはバックエンドに属します |
| WPStaging\Framework\Cache\Backend\AbstractBackend | より良い |
メソッド
メソッド名は何をするかを明確に説明する必要があるため、doSomething、makeSomething、isSomething、hasSomething のような動詞で始まる必要があります。
すべてのメソッド名は lowerCamelCase で書かれます。異なるファイルシステムでの問題を避けるため、メソッド名には a-z、A-Z、0-9 の文字のみが許可されます — 特殊文字は使用しないでください。
メソッド名は説明的に、同時に簡潔に保ってください。コンストラクタは常に __construct() と呼ばれる必要があり、クラス名をメソッド名として使用しないでください。
myMethod()
someNiceMethodName()
betterWriteLongMethodNamesThanNamesNobodyUnderstands()
singYmcaLoudly()
__construct()
プロパティと変数
変数は名詞または形容詞であるべきで、決して動詞であってはなりません。何かを保存し、何を含むかを説明する必要があります。
プロパティに getSomething というキーワードを使用しないでください。get はゲッターとセッター、およびget よりも適切なキーワードがない明示的に何かを行うメソッド用に予約されています。
変数名は lowerCamelCase で書かれ、次のようにすべきです:
- 自己説明的
- 認識できないほど短縮されていない、意味を明確にするためならむしろ長い
次の例は、同じ意味だが命名が異なる 2 つの変数を示しています。長いバージョンのほうが良いことに同意していただけるはずです (そうでしょう…?)。
変数の良い命名
$singletonObjectsRegistry
$argumentsArray
$aLotOfHtmlCode
renderHTMLtoScreen
変数の悪い命名
$sObjRgstry
$argArr
$cx
特別な例外として、それらの意味が一目で明確な場合、for ループの数値インデックスに $i、$j、$k のような変数名を使用できます。ただし、それでもそれらを避けたいと思うべきです。
i18n、sprintf()、esc_html_* および gettext()
翻訳可能な文字列にパラメータがある場合、常に最初に gettext() 関数を使用し、sprintf() で包んでください。
誤り:
esc_html_e(sprintf('There are %1$d monkeys in the %2$s'), $number, $string), 'text-domain');
正解:
// Correct (multi-line): sprintf( /* translators: number of monkeys, location. */ __( 'There are %1$d monkeys in the %2$s', 'text-domain' ), (int) $number, esc_html( $string ) ); // Correct (single-line): /* translators: number of monkeys, location. */ printf( __( 'There are %1$d monkeys in the %2$s', 'text-domain' ), intval( $number ), esc_html( $string ) );
printf や sprintf を使用する場合、文字列の周りのシングルクォート (‘) は必須です。なぜなら、ダブルクォート (“) では PHP が $s を s 変数として解釈してしまい、これは望むものではないからです。
wporg 翻訳ツールと標準化するために、翻訳者のプレースホルダーを含める必要があります。
/* translators: %s: name */
sprintf(esc_html__('string %s to translate', 'text-domain'), esc_html($string));
/* translators: %1$s = name1, %2$s = name2 */
sprintf(esc_html__('string %1$s to translate for %2$s', 'text-domain'), esc_html($string1), esc_html($string2));
if else 条件
追加の括弧と if else 文が必要な場合や、比較する複数の状態がある場合は、インライン条件を避けてください。
そうでなければ、インラインまたは別の早期リターン条件で書くのは問題ありません。
悪い:
return ((!$this->isWindowsOs() && is_executable($fileName))) && is_writable($fileName) || ($this->isWindowsOs()) && is_writable($fileName);
良い:
if (!$this->isWindowsOs && is_executeable && is_writeable()) {
return true;
}
if ($this->isWindowsOs && is_writeable()) {
return true;
}
return false;
Actions と Filters
- フィルター名を宣言するには定数を使用してください。定数名は
FILTER_*パターンに従う必要があります。 - フィルター名は常に
wpstgで始め、wpstg.backups.listing_tableのようにドットで名前空間を区切ってください。ここでlisting_tableはそのアクションが使用されるメソッド名です。
たとえば:
// Declare const for filter const FILTER_CLONING_UPDATE_ACTIVE_PLUGINS_FILTER = 'wpstg.cloning.update.active_plugins'
そして
apply_filters(self::CLONING_UPDATE_ACTIVE_PLUGINS_FILTER, $activePlugins);
wp_options へのデータ保存
- オプション名を宣言するには定数を使用してください。定数名は
OPTION_*パターンに従う必要があります。 - テーブルオプション名は常に
wpstgで始め、wpstg_backup_database_settingsのように単語をアンダースコアで区切ってください。新しく追加したオプションを uninstall.php に追加するのを忘れないでください。
悪い:
/**
* The option that stores the staging sites
*/
const STAGING_SITES_OPTION = 'wpstg_staging_sites';
良い:
/**
* The option that stores the staging sites
*/
const OPTION_STAGING_SITES = 'wpstg_staging_sites';
SplFileObject の代わりに WPStaging*\FileObject を使用する
- PHP 8.0.1 までのすべての PHP バージョンで一貫した
seek()とfgets()の挙動のために、SplFileObject の代わりに WPStaging\Framework\Filesystem\FileObject を使用してください。 - PHP 8.0.1 までのすべての PHP バージョンで一貫した挙動のために、
fseek()の後にfgets()の代わりにreadAndMoveNext()を使用してください。
パスの扱い
- パスを扱うときは常に
WPSTG_PLUGIN_DIRやWPSTG_PLUGIN_URLのような既存の定数の 1 つを使用してください。 - 常にスラッシュ (/) を使用し、
DIRECTORY_SEPARATORは決して使用しないでください。スラッシュは Linux と Windows に互換性がありますが、バックスラッシュ (\) は Windows でのみ動作します。これにより複雑さが軽減され、コードが読みやすくなり、混合ホスト環境や Linux から Windows システム (またはその逆) へのデータ移行時、または検索・置換のパス処理を行う際の予期しない問題を防止できます。 - 必要に応じて、バックスラッシュ (\) をスラッシュ (/) に置き換えるには wp_normalize_path 関数を使用してください。