6.2Express troubleshooting
The essentials in 30 seconds
- Reflex: one symptom = likely causes = one targeted action — diagnose before touching the code.
- Read: the error message gives the file and line: the fault is often on the previous line.
- Production: any gap between local and live is handled through versions, case, Docker and environment variables.
Riad thread — the playbook taped next to the screen
Riad keeps this playbook next to his screen. Verdict after one year: three lines served him most — the missing semicolon on the previous line, the concatenated query that opened an injection, and the secret that nearly went into Git. For each, he ended up applying the sequence (read the error, check the cause, fix) instead of editing at random.
Observed symptom, verified causes, actions in order: the reflex holds in three steps.
Diagnose before restarting
A PHP problem is rarely solved at random: each symptom has typical causes and a targeted action. The table below groups the most frequent situations, from syntax to deployment.
| Symptom | Likely causes | Actions |
|---|---|---|
| “syntax error, unexpected...” on a line that looks correct | missing semicolon or brace/parenthesis on the PREVIOUS line | check the previous line; enable error display in dev; indent (0.3, 1.x) |
| My variable does not display (literal $nom text) | single quotes (literal) instead of double; or variable case ($nom ≠ $Nom) | double quotes or concatenation; check the exact case of the variable (1.1) |
| $_POST empty or condition ignoring “0” | wrong method (GET vs POST); “falsy” value (0, '', '0') poorly tested | check the form method; test explicitly (isset, !== '', === 0) rather than if ($x) (1.2, 2.1) |
| Flaw: possible SQL injection | data concatenated into an SQL query | ALWAYS prepared statements (PDO: placeholders + execute); never concatenation (3.1) |
| Flaw: XSS (injected script runs) | data displayed without escaping | escape on display with htmlspecialchars(); template engines escape by default (3.4) |
| A secret (database password, key) leaked | hard-coded or Git-versioned secret | regenerate immediately; move to an environment variable (.env out of the repo); never version .env (3.1, 5.4) |
| Class not found / broken autoload | namespace inconsistent with PSR-4; autoloader not regenerated; missing vendor/ | check namespace ↔ path (PSR-4); composer dump-autoload; composer install (3.3) |
| N+1 query / slow application | one query per item (ORM); unindexed queries; no cache | eager-load relations; index searched columns; cache (Redis); profile BEFORE (5.2) |
| “It works locally but not live” | different environment (PHP version, extensions, Windows/Linux case, config) | align versions; be strict about file case; containerise (Docker); config per environment (0.2, 5.3) |
| Detailed errors displayed in production | display_errors left on (dev config deployed as is) | disable display, log errors; adapt config to production (5.4) |
Ready-to-say script — diagnosing without random edits (30 s)
“My symptom: [syntax error / literal variable / empty POST / injection / slowness / prod gap]. I read the file and line, identify the playbook's likely cause, apply the targeted action and verify.”
Copy-paste template — healthy error base (dev vs prod)
prepare("SELECT id FROM articles WHERE id = :id");
$stmt->execute(["id" => $id]);
} catch (PDOException $e) {
error_log($e->getMessage());
echo $enProd ? "Service unavailable." : $e->getMessage();
}
VSE / small budget
No formal table: one symptom, the playbook's likely cause, the action and the contact noted.
SME Constantine
Fold local realities into diagnosis: installed versions, shared workstations, known activity peaks.
Remote / hybrid
Add immediate written logs to actions: at a distance, an unrecorded symptom looks like a working system.
Intercultural
Spell out findings in writing: what seems obvious (which version, which environment) is not obvious to everyone.
48h challenge — apply tomorrow
Spot 1 current symptom (syntax error, empty POST, slowness), apply the playbook line (message read + cause verified + targeted action).
- I can link a symptom to its likely causes.
- I read file + line before fixing.
- I know the pointer to the level to dig into for my case.
Riad's page renders a script entered by a visitor instead of showing it as text. Which reflex does the playbook apply?
One same returning symptom is not ten breakdowns: it is a missing reflex to anchor (previous line, exact case, strict isset, prepared, htmlspecialchars, .env, dump-autoload).