Code From a PHP Version That Died in 2015
The generated page fatals before it renders a single row
Published Oct 29, 2026
Executive Summary
A products page generated with mysql_connect() and mysql_query() — a function family removed from PHP in 7.0. The code is syntactically fine but targets the PHP of the model's training corpus (a decade of pre-2015 tutorials), not the PHP 8 the project runs. It fatals with 'Call to undefined function mysql_query()' on the first request. The fix is PDO with prepared statements.
The Prompt
“Add a products page that lists products by category from the database.”
The Flaw
mysql_connect(), mysql_query(), and the entire mysql_* family were removed in PHP 7.0 — released in 2015. On any PHP 7 or 8 runtime this file fatals with 'Call to undefined function mysql_query()' before it renders a single product. The model wrote code for the PHP it was trained on: years of tutorials and Stack Overflow answers that still use mysql_*, because those pages were written before the removal and never updated.
Risk & Impact
[Availability] The page is dead on arrival. It passes a syntax check and looks plausible, but the first real request throws a fatal error — and every request after it does the same.
Cost: The feature never worked; the bug survives until someone actually loads the page in the PHP version the project runs.
Code Comparison
❌ Vulnerable (AI generated)
❌ Vulnerable (AI generated)
✅ Hardened (production ready)
The Fix
Target the PHP version the project actually runs. Replace the removed mysql_* functions with PDO prepared statements — and pin the runtime in the prompt so the agent never reaches for a dead API.
Prevention
- [linter] PHPStan or Psalm run against a PHP 8 baseline flag 'function mysql_query not found', so a removed API fails CI instead of shipping.
- [ci] Boot the app once in CI (or run one smoke request per route) — the fatal surfaces on the first request, before deploy.
- [manual] Pin the runtime in the prompt (rule 1: 'PHP 8.3, PDO/MySQL') and name the database access layer you expect.
Why This Happened
Root cause: the prompt omitted Rule 1 and Rule 9 — the guardrails that would have caught this. See the full guide →
