Common causes
- Legacy code written for PHP 5 running on PHP 7 or 8
- The host upgraded PHP and old scripts were not updated
- An abandoned plugin, theme or script that still uses mysql_*
- For mysqli_connect(): the mysqli extension is not enabled on this PHP build
How to fix it
- Confirm which function is missing. If it is mysql_*, the code needs migrating. If it is mysqli_connect(), only the extension is missing: enable mysqli in cPanel Select PHP Version or install php8.x-mysql on a VPS.
- Find every mysql_* call. Run grep -rn 'mysql_' --include='*.php' . to list all calls. Typical ones are mysql_connect, mysql_select_db, mysql_query, mysql_fetch_assoc, mysql_num_rows and mysql_real_escape_string.
- Replace the connection with PDO. Create one PDO connection with charset utf8mb4 and ERRMODE_EXCEPTION, then pass it to code that needs the database.
- Convert queries to prepared statements. Replace string-built SQL and mysql_real_escape_string() with placeholders and execute([$value]). This fixes SQL injection at the same time.
- Replace fetch and count functions. mysql_fetch_assoc() becomes $stmt->fetch(PDO::FETCH_ASSOC); mysql_num_rows() becomes rowCount() or a COUNT(*) query.
- Do not rely on old PHP or shims. Running PHP 5.6 is unsupported and insecure. Compatibility shims that recreate mysql_* hide the problem and keep injection-prone code alive; use them only as a short-term bridge.
PDO replacement
$pdo = new PDO(
'mysql:host=localhost;dbname=DB_NAME;charset=utf8mb4',
'DB_USER', 'DB_PASSWORD',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC); How to stop it happening again
- Scan legacy projects for removed functions before a PHP upgrade
- Use prepared statements for every query
- Replace abandoned scripts and plugins with maintained ones