mirror of
https://github.com/alirezarezvani/claude-skills.git
synced 2026-10-11 03:37:58 +00:00
Adds 6 new language files to the code-reviewer skill, expanding coverage from 7 to 13 languages. Each file follows the established hybrid structure — language-specific rules inline, universal rules in rules/universal.md. Files added: - languages/c.md — memory safety, banned functions, pointer ownership, buffer bounds, UB - languages/cpp.md — smart pointers, RAII, reinterpret_cast, virtual destructors, C++17/20 - languages/rust.md — unsafe blocks, .unwrap() in production, Tokio pitfalls, clippy - languages/ruby.md — Rails-aware N+1, strong_parameters, YAML.safe_load, Marshal.load - languages/php.md — SQLi, unserialize, eval, file inclusion, CSRF, XSS, PHP 8.x - languages/dart.md — Dart + Flutter: dispose(), BuildContext across async, const widgets SKILL.md dispatch table and --language valid values updated accordingly.
109 lines
4.9 KiB
Markdown
109 lines
4.9 KiB
Markdown
---
|
|
language: php
|
|
extensions: [".php", ".phtml", ".php3", ".php4", ".php5", ".phps"]
|
|
---
|
|
|
|
# PHP — Language-Specific Review Notes
|
|
|
|
Load this file alongside `rules/universal.md`. Universal rules are not repeated here — only PHP-specific rules and idioms.
|
|
|
|
---
|
|
|
|
## PR Analyzer — PHP Risk Signals
|
|
|
|
- `var_dump` / `print_r` / `echo` debug statements left in production code
|
|
- `@` error suppression operator — masks real errors; verify it is justified
|
|
- `// phpcs:ignore` / `// phpstan-ignore` comments — verify they are justified
|
|
- Hardcoded credentials, database passwords, or API keys in source
|
|
- `eval()` anywhere — almost always a security issue
|
|
- `$_GET` / `$_POST` / `$_REQUEST` / `$_COOKIE` used without sanitization
|
|
|
|
---
|
|
|
|
## Code Quality — PHP Checks
|
|
|
|
- Missing type declarations on function parameters and return types
|
|
- `mixed` return type used broadly — tighten to specific types
|
|
- Global variables (`global $var`) — pass dependencies explicitly
|
|
- Long functions (>50 lines) — PHP functions tend to accumulate logic
|
|
- `isset()` / `empty()` used to mask type errors instead of fixing the root cause
|
|
- Missing `strict_types=1` declaration at the top of the file
|
|
|
|
---
|
|
|
|
## Security
|
|
|
|
- Flag `$_GET` / `$_POST` / `$_REQUEST` used directly in SQL queries — require PDO prepared statements
|
|
- Flag `mysqli_query($conn, "SELECT ... WHERE id = " . $_GET['id'])` — SQL injection
|
|
- Flag `echo $_GET['name']` or any unescaped output — XSS; use `htmlspecialchars()` with `ENT_QUOTES`
|
|
- Flag `include` / `require` with user-controlled paths — local/remote file inclusion
|
|
- Flag `eval()` — remote code execution risk; no legitimate use in application code
|
|
- Flag `shell_exec` / `exec` / `system` / `passthru` with user-controlled input — command injection
|
|
- Flag `unserialize()` on untrusted data — arbitrary object instantiation and code execution
|
|
- Flag `move_uploaded_file` without MIME type validation and extension whitelist — file upload attack
|
|
- Flag `header("Location: " . $_GET['url'])` without validation — open redirect
|
|
- Flag missing CSRF token validation on state-changing form endpoints
|
|
|
|
---
|
|
|
|
## Async / Concurrency
|
|
|
|
- Flag long-running synchronous operations in a request cycle — offload to a queue (Laravel Queue, RabbitMQ)
|
|
- Flag `sleep()` used inside a request handler — blocks the PHP-FPM worker
|
|
- Flag shared mutable state in `static` properties accessed across requests in long-running processes (Swoole, RoadRunner)
|
|
- Flag missing idempotency in queued jobs — jobs can be retried on failure
|
|
|
|
---
|
|
|
|
## Resource Management
|
|
|
|
- Flag database connections not closed or returned to the pool (`$pdo = null` or `$conn->close()`)
|
|
- Flag `fopen` / `fwrite` without a matching `fclose` on all paths
|
|
- Flag `curl_init` without `curl_close` — leaks the curl handle
|
|
- Flag unbounded file uploads with no size or type restriction
|
|
- Flag sessions not explicitly closed (`session_write_close()`) before long operations — session locking blocks other requests
|
|
|
|
---
|
|
|
|
## Exception Handling
|
|
|
|
- Flag empty `catch` blocks — swallowed exceptions
|
|
- Flag `catch (Exception $e) {}` without logging — silent failure
|
|
- Flag `die()` / `exit()` used for error handling in library code — use exceptions
|
|
- Flag `@` operator used to suppress errors from functions that can fail — check return values instead
|
|
- Flag `trigger_error` used in new code — prefer exceptions
|
|
|
|
---
|
|
|
|
## Performance
|
|
|
|
- Flag N+1 Eloquent / Doctrine queries — use eager loading (`with()`, `load()`, `join`)
|
|
- Flag `count($array)` called repeatedly in a loop condition — cache the result
|
|
- Flag `array_push($arr, $val)` — use `$arr[] = $val` which is faster
|
|
- Flag `in_array` on large arrays without the strict third argument — use `isset` on a flipped array for O(1) lookup
|
|
- Flag `file_get_contents` on remote URLs in a request cycle — use an HTTP client with timeout and async where possible
|
|
- Flag Eloquent `all()` without pagination — loads entire table into memory
|
|
|
|
---
|
|
|
|
## Idioms and Best Practices
|
|
|
|
### Type Safety
|
|
- Always declare `declare(strict_types=1)` at the top of every file
|
|
- Use union types (`int|string`) and nullable types (`?string`) rather than `mixed`
|
|
- Use typed properties on classes — avoid untyped `public $foo`
|
|
- Use constructor promotion for simple value objects
|
|
|
|
### Modern PHP (8.x)
|
|
- Prefer `match` expressions over `switch` — strict comparison, no fall-through
|
|
- Use named arguments for functions with many optional parameters
|
|
- Use `enum` for fixed sets of values instead of class constants
|
|
- Use `readonly` properties for immutable data
|
|
- Use nullsafe operator (`?->`) instead of nested `isset` checks
|
|
- Use `first-class callable syntax` (`strlen(...)`) instead of string references
|
|
|
|
### Laravel / Symfony Specific
|
|
- Keep controllers thin — logic belongs in service classes or action classes
|
|
- Use form requests for validation — never validate in the controller directly
|
|
- Prefer Eloquent relationships over manual joins for readability
|
|
- Flag raw queries where the ORM can express the same intent safely
|