Skip to content

Latest commit

 

History

History
106 lines (72 loc) · 5.39 KB

File metadata and controls

106 lines (72 loc) · 5.39 KB

チュートリアルの書き方

このリポジトリでは、本文 (*/README.md) と演習用PHPファイル、そしてPHPStanの実際の出力が食い違わないように、composer check で機械的に検査しています。

composer install
composer check

composer check は次を実行します。

  • composer check-toolstools/ 以下を PHPStan で解析します
  • composer check-docstools/check-docs.php で本文とPHPファイルの整合性を検査します

ネットワークを使う composer check-playground (Playground リンクの検査) は check には含めていません。個別に実行してください (後述)。

GitHub Actions でも同じ検査が走ります (.github/workflows/check.yml)。

ディレクトリ構成

beginner/     入門編 (README.md と演習ファイル N.php)
basic/        基礎編
answers/      演習の解答例 (answers/beginner/N.php のように配置)
tools/        検査ツール

演習ファイルと解答例は同名の関数・クラスを定義するため、解答例は phpstan.dist.neonpaths含めない answers/ に置きます。同じディレクトリに置くと phpstan analyse の一括実行で定義が衝突し、誤ったエラーが出ます。

コードブロックの検査

README 中の ```php ブロックは、フェンスに属性を付けると検査対象になります。属性のないブロックは検査されません (件数だけ表示されます)。

file= — 演習ファイルとの一致

```php file=3.php
function search(string $word, string $order, int $page): array
{
    // ...
}
```

ブロックの内容が、README と同じディレクトリにある指定ファイルの連続した行と一致することを検査します。

  • タブとスペースの違い、行末の空白は無視されます (PHPファイルはタブ、README は4スペースで構いません)
  • // ... または // … だけの行は「ここに任意の行が入る」という省略記号として扱われます
  • ファイルの一部だけを抜粋できます

phpstan — スニペット単体の解析

```php phpstan
$word = filter_var($_GET['word'] ?? '');
\PHPStan\dumpType($word); // DumpedType: string|false
```

ブロックの内容を単体のPHPファイルとして PHPStan で解析します。先頭に <?php がなければ <?php declare(strict_types = 1); が補われます。

  • 注釈 (後述) を付けた行は、注釈と実際の出力が完全に一致することを検査します
  • 注釈のない行にエラーが出た場合は失敗します (dumpType() の出力は除く)。本文で触れないエラーが紛れ込むのを防ぐためです

注釈

コードブロック内のコメントで、その行に PHPStan が出力する内容を宣言します。ファイルとの一致検査では注釈は取り除いてから比較されるので、演習ファイル側に注釈を書く必要はありません。

書き方 意味
// DumpedType: int その行の \PHPStan\dumpType() の出力 (// Dumped type: int# Dumped type: int も可)
// Error: Function f() has no return type specified. その行で発生するエラーメッセージ

注釈は行末に書くか、直前の行に1行ずつ書きます。直前の行に書いた注釈は、次のコード行 (注釈でない行) に適用されます。

// Error: Function label() has no return type specified.
// Error: Function label() has parameter $title with no type specified.
function label($title)
{
    return "label:{$title}";
}

\PHPStan\dumpType($x); // DumpedType: int

注釈を付けた行は、注釈で宣言した dump 出力とエラーの集合が、実際の出力と過不足なく一致しなければなりません (順序は問いません)。

解答例

answers/*/*.php はそれぞれ単体で PHPStan を実行し、dumpType() の出力以外のエラーが出ないことを検査します。

Playground のリンク

各節の NOTE ブロックにある PHPStan Playground のリンクは、tools/playground.php で検査・更新できます。

composer check-playground    # リンク先に保存されたコード・設定が演習ファイルと一致するか (読み取りのみ)
composer update-playground   # 一致しない/TODO のリンクを新規発行して README を書き換える

update は Playground の Share ボタンと同じ API (POST https://api.phpstan.org/analysesaveResult: true) を叩き、返ってきた ID で https://phpstan.org/r/<id> を README に書き込みます。NOTE ブロック直後に <!-- TODO: ... Playground ... --> があれば取り除きます。--dry-run を付けると発行せず対象だけ表示します。

保存する設定はローカルの phpstan.dist.neon に合わせて tools/playground.php の先頭に定数で定義しています (Level 10, bleedingEdge オン, strictRules オフ)。設定を変えたら両方を揃えてください。

演習ファイルを変更したら composer update-playground を実行し、README のリンク更新をコミットに含めてください。CI では composer check-playground が走り、リンク先とファイルの食い違いを検出します。