Why mysql_* Functions in PHP Are 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

Introduction: From History to the Problem

\n\n

If you've ever written PHP and worked with MySQL databases, you've likely encountered code like mysql_connect() or mysql_query(). About 10–15 years ago, this was the de facto standard. But times change, and today using mysql_* functions is like trying to run Windows 95 on a new MacBook. You can, but why?

\n\n

On Stack Overflow, the question «Why shouldn't I use mysql_* functions in PHP?» has gathered thousands of views and hundreds of votes. This is no coincidence: the topic of security and modern approaches to working with databases is critically important for any developer. In this article, we'll break down why mysql_* is not just "old," but frankly dangerous, and show you what to use instead.

\n\n

Problem #1: mysql_* Completely Removed in PHP 7

\n\n

The most obvious reason: starting with PHP 5.5.0, the mysql_* functions were marked as deprecated, and in PHP 7.0 they were completely removed. If your server updates to PHP 7+, any code using mysql_connect(), mysql_query(), and similar functions will simply stop working. You'll get a fatal error:

\n\n
Fatal error: Call to undefined function mysql_connect()
\n\n

This isn't "it might not work," it's a guaranteed site crash. Therefore, the first and main reason is: compatibility. Any hosting provider will eventually update PHP, and your project will end up in a dead zone.

\n\n

Problem #2: Lack of Protection Against SQL Injections

\n\n

Let's look at typical code using mysql_*:

\n\n
<?php\n$connection = mysql_connect('localhost', 'user', 'password');\nmysql_select_db('my_database', $connection);\n\n$username = $_POST['username'];\n$password = $_POST['password'];\n\n$query = "SELECT * FROM users WHERE username = '$username' AND password = '$password'";\n$result = mysql_query($query, $connection);\n\nif (mysql_num_rows($result) > 0) {\n    echo "Welcome!";\n} else {\n    echo "Invalid login or password";\n}\n?>
\n\n

Looks harmless? Now imagine an attacker enters the following string into the username field:

\n\n
admin' OR '1'='1
\n\n

The query becomes:

\n\n
SELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = '...'
\n\n

And voilà — '1'='1' is always true, so the query returns the first record from the table. The attacker logs into the system without a password. This is a classic SQL injection. The mysql_* functions provide no built-in means for escaping data — you have to manually use mysql_real_escape_string(), which, by the way, is also deprecated.

\n\n

Compare this with modern approaches where protection is built into the architecture (more on this below).

\n\n

Problem #3: Outdated Architecture and Lack of Support

\n\n

mysql_* is a procedural interface that does not support:

\n\n
    \n
  • Prepared statements — the main tool for protecting against injections.
  • \n
  • Object-oriented style — modern PHP uses objects.
  • \n
  • Multiple queries — you cannot execute several SQL commands in one call.
  • \n
  • Transactions — although they can be emulated, there is no built-in support.
  • \n
  • Stored procedures — working with them is extremely inconvenient.
  • \n
\n\n

Furthermore, the mysql_* extension has not been updated since 2014. The PHP developers simply stopped supporting it. This means any new database features, security improvements, or optimizations — all of this passes you by.

\n\n

What to Use Instead of mysql_*?

\n\n

PHP has two modern, supported

Blogs

Book Recommendations