Introduction : de l'histoire au problème
\n\nSi vous avez déjà codé en PHP et travaillé avec des bases de données MySQL, vous avez forcément croisé du code comme mysql_connect() ou mysql_query(). Il y a encore 10 ou 15 ans, c'était le standard de facto. Mais les temps changent, et aujourd'hui utiliser les fonctions mysql_*, c'est un peu comme essayer de lancer Windows 95 sur un nouveau MacBook. C'est possible, mais pourquoi s'infliger ça ?
Sur Stack Overflow, la question « Why shouldn't I use mysql_* functions in PHP? » a cumulé des milliers de vues et des centaines de votes. Ce n'est pas un hasard : la sécurité et les bonnes pratiques modernes pour interagir avec une base de données sont cruciales pour tout développeur. Dans cet article, nous allons voir pourquoi mysql_* n'est pas simplement « vieux », mais carrément dangereux, et par quoi les remplacer.
Problème n°1 : les fonctions mysql_* ont été supprimées de PHP 7
\n\nLa raison la plus évidente : à partir de PHP 5.5.0, les fonctions mysql_* ont été marquées comme obsolètes (deprecated), puis complètement supprimées dans PHP 7.0. Si votre serveur passe à PHP 7+, tout le code utilisant mysql_connect(), mysql_query() et autres cessera simplement de fonctionner. Vous obtiendrez une erreur fatale :
Fatal error: Call to undefined function mysql_connect()\n\nCe n'est pas un « peut-être que ça ne marchera pas », c'est un crash garanti de votre site. La première et principale raison est donc la compatibilité. Tôt ou tard, votre hébergeur mettra à jour PHP, et votre projet se retrouvera en zone morte.
\n\nProblème n°2 : aucune protection contre les injections SQL
\n\nRegardons un code typique avec 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 "Bienvenue !";\n} else {\n echo "Identifiant ou mot de passe incorrect";\n}\n?>\n\nCela semble inoffensif ? Imaginez maintenant qu'un attaquant saisisse dans le champ username la chaîne suivante :
admin' OR '1'='1\n\nLa requête devient :
\n\nSELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = '...'\n\nEt voilà — '1'='1' est toujours vrai, donc la requête renvoie le premier enregistrement de la table. L'attaquant se connecte sans mot de passe. C'est une injection SQL classique. Les fonctions mysql_* n'offrent aucun moyen intégré d'échapper les données — vous devez utiliser manuellement mysql_real_escape_string(), qui est d'ailleurs également obsolète.
Comparez avec les approches modernes où la protection est intégrée dans l'architecture (nous y reviendrons).
\n\nProblème n°3 : architecture obsolète et absence de support
\n\nmysql_* est une interface procédurale qui ne supporte pas :
- \n
- Les requêtes préparées (prepared statements) — l'outil principal contre les injections. \n
- Le style orienté objet — en PHP moderne, on travaille avec des objets. \n
- Les requêtes multiples — impossible d'exécuter plusieurs commandes SQL en un seul appel. \n
- Les transactions — bien qu'elles puissent être émulées, il n'y a pas de support natif. \n
- Les procédures stockées — leur utilisation est très peu pratique. \n
De plus, l'extension mysql_* n'a pas été mise à jour depuis 2014. Les développeurs de PHP ont tout simplement cessé de la maintenir. Cela signifie que toutes les nouvelles fonctionnalités de base de données, les améliorations de sécurité ou les optimisations vous passent complètement à côté.
Que faut-il utiliser à la place de mysql_* ?
\n\nPHP propose deux alternatives modernes et activement maintenues :