The Story of a Mistake: Why mysql_* is a Thing of the Past
\n\nImagine: 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.
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\nWhat are mysql_* and Why Were They Removed?
\n\nThe 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.
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.
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
Live Example: How mysql_* Kills Your Website
\n\nLet'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\nWhat's the problem? If an attacker passes the value ' OR 1=1 -- into the username parameter, the query becomes:
SELECT * FROM users WHERE username = '' OR 1=1 --\n\nThe 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.
Of course, you could use mysql_real_escape_string(), but:
- \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
What to Replace mysql_* With: Two Modern Approaches
\n\nIn modern PHP, there are two worthy extensions for working with MySQL: mysqli (MySQL Improved) and PDO (PHP Data Objects). Both supp