Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions skills/php-modernization/references/phpstan-compliance.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,38 @@ public function getItems(): array
public function getConfig(): array
```

### Strict-Rule Bans: short-ternary, `@`-suppression, `(string) $mixed`

Level 9/10 plus a strict ruleset (`phpstan-strict-rules`, or the `ergebnis`
custom rules) reject three idioms that pass at lower levels. New code trips them
repeatedly; the compliant rewrites:

```php
// ternary.shortNotAllowed — the short ternary is banned:
$rows = glob($p) ?: []; // ✗
$rows = glob($p); // ✓
if ($rows === false) { $rows = []; }

// ergebnis.noErrorSuppression — the "@" operator is banned. Wrap the
// warning-emitter and handle the failure explicitly (also catches the case
// where an error handler turns the warning into an exception):
$h = @proc_open($cmd, $spec, $pipes); // ✗
$h = false; // ✓ init first, so the check is safe if proc_open throws
try { $h = proc_open($cmd, $spec, $pipes); }
catch (\Throwable $e) { /* degrade */ }
if (!\is_resource($h)) { /* degrade */ }
// For unlink/file ops, guard instead of suppress: if (is_file($f)) { unlink($f); }

// cast.string — casting a mixed to string is unsafe (it could be an array):
$s = (string) $config->get($key); // ✗
$raw = $config->get($key); // ✓ string-only intent (config keys);
$s = \is_string($raw) ? $raw : ''; // use is_scalar($raw) ? (string) $raw : '' to keep int/bool
```

Run the static analyzer **after** adding the test files, not before — tests are
analyzed too, so a `(string) $mixed` cast or an offset-on-possibly-empty in a
fresh test file fails CI even though the pre-test run was green.

## Type Aliases and Custom Types

### Defining Type Aliases
Expand Down
Loading