Why mysql_* in PHP is Evil: A Complete Breakdown with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

The Story of a Mistake: Why mysql_* is a Thing of the Past

\n\n

Imagine: you're writing a website in PHP, connecting to a MySQL database, and using the familiar mysql_query() function from your university days. Everything works, the site is live, users are happy. But one day you notice a strange warning in the logs: «Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future». This isn't just the interpreter complaining — it's a red flag that cannot be ignored.

\n\n

On Stack Overflow, the question «Why shouldn't I use mysql_* functions in PHP?» has gathered thousands of views and hundreds of comments. And this is no coincidence. In this article, we'll figure out why mysql_* functions (mysql_connect, mysql_query, mysql_fetch_array, and others) became enemy number one for PHP developers, show real code examples of what to use instead, and provide a step-by-step migration plan.

\n\n

What are mysql_* and Why Were They Removed?

\n\n

The mysql_* extension (original MySQL) appeared in PHP 2.0 back in 1997. It was simple and intuitive: call mysql_connect(), execute a query with mysql_query(), get the result. But this simplicity had a dark side.

\n\n

Starting with PHP 5.5.0, all mysql_* functions were marked as deprecated, and in PHP 7.0 they were completely removed. If you try to use mysql_connect() on PHP 7+, you'll get a fatal error: Call to undefined function mysql_connect(). The reason is not a whim of the PHP developers, but fundamental security and architectural issues.

\n\n

Three Main Reasons to Abandon mysql_*

\n\n
    \n
  • No protection against SQL injections — the functions do not support prepared statements, making manual escaping mandatory but often forgotten.
  • \n
  • Outdated architecture — no support for object-oriented style, stored procedures, multiple queries, or transactions.
  • \n
  • Lack of development — the extension hasn't been updated for years, while MySQL has changed (e.g., new data types, character sets, authentication mechanisms appeared).
  • \n
\n\n

Live Example: How mysql_* Kills Your Website

\n\n

Let's look at classic code that still appears in old textbooks and forums:

\n\n
<?php\n// DEPRECATED CODE - DO NOT USE!\n$link = mysql_connect('localhost', 'root', 'password');\nmysql_select_db('users_db', $link);\n\n$user_input = $_GET['username']; // user enters: ' OR 1=1 --\n$query = "SELECT * FROM users WHERE username = '$user_input'";\n$result = mysql_query($query, $link);\n\nwhile ($row = mysql_fetch_assoc($result)) {\n    echo "Hello, " . $row['username'] . "<br>";\n}\n?>
\n\n

What's the problem? If an attacker passes the value ' OR 1=1 -- into the username parameter, the query becomes:

\n\n
SELECT * FROM users WHERE username = '' OR 1=1 --
\n\n

The double dash -- comments out the rest of the query, and the condition 1=1 is always true. As a result, you get all users from the database, including passwords, emails, and other confidential information. This isn't theory — it's a real vulnerability that breaks thousands of websites every day.

\n\n

Of course, you could use mysql_real_escape_string(), but:

\n
    \n
  • Developers often forget to call it.
  • \n
  • It doesn't protect against all types of attacks (e.g., encoding-based attacks).
  • \n
  • The code becomes messy and hard to read.
  • \n
\n\n

What to Replace mysql_* With: Two Modern Approaches

\n\n

In modern PHP, there are two worthy extensions for working with MySQL: mysqli (MySQL Improved) and PDO (PHP Data Objects). Both supp

Blogs

Book Recommendations