Introduction: From History to the Problem
\n\nIf 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?
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.
Problem #1: mysql_* Completely Removed in PHP 7
\n\nThe 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:
Fatal error: Call to undefined function mysql_connect()\n\nThis 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\nProblem #2: Lack of Protection Against SQL Injections
\n\nLet's look at typical code using mysql_*:
<?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\nLooks harmless? Now imagine an attacker enters the following string into the username field:
admin' OR '1'='1\n\nThe query becomes:
\n\nSELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = '...'\n\nAnd 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.
Compare this with modern approaches where protection is built into the architecture (more on this below).
\n\nProblem #3: Outdated Architecture and Lack of Support
\n\nmysql_* is a procedural interface that does not support:
- \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
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.
What to Use Instead of mysql_*?
\n\nPHP has two modern, supported