مقدمة: من التاريخ إلى المشكلة
\n\nإذا سبق لك أن كتبت كودًا بلغة PHP وتعاملت مع قواعد بيانات MySQL، فبالتأكيد صادفت كودًا مثل mysql_connect() أو mysql_query(). قبل 10-15 سنة، كان هذا هو المعيار الفعلي. لكن الأوقات تتغير، واليوم استخدام دوال mysql_* يشبه محاولة تشغيل نظام Windows 95 على جهاز MacBook جديد. يمكنك ذلك، ولكن لماذا؟
على موقع Stack Overflow، السؤال "لماذا لا يجب علي استخدام دوال mysql_* في PHP؟" حصد آلاف المشاهدات ومئات الأصوات. هذا ليس من قبيل الصدفة: موضوع الأمان والنهج الحديث في التعامل مع قواعد البيانات أمر بالغ الأهمية لأي مطور. في هذه المقالة، سنشرح لماذا دوال mysql_* ليست مجرد "قديمة"، بل تشكل خطرًا صريحًا، وسنوضح البدائل المناسبة لها.
المشكلة الأولى: دوال mysql_* تمت إزالتها بالكامل من PHP 7
\n\nالسبب الأكثر وضوحًا: بدءًا من PHP 5.5.0، تم وضع علامة مهملة (deprecated) على دوال mysql_*، وفي PHP 7.0 تمت إزالتها بالكامل. إذا تم تحديث خادمك إلى PHP 7+، فإن أي كود يستخدم mysql_connect() أو mysql_query() أو ما شابه ذلك سيتوقف عن العمل تمامًا. ستحصل على خطأ فادح:
Fatal error: Call to undefined function mysql_connect()\n\nهذا ليس "قد لا يعمل"، بل هو انهيار مضمون للموقع. لذلك، السبب الأول والرئيسي هو: التوافقية. عاجلاً أم آجلاً، أي مزود استضافة سيُحدّث PHP، وسيجد مشروعك نفسه في منطقة ميتة.
\n\nالمشكلة الثانية: عدم وجود حماية ضد هجمات حقن SQL
\n\nلنلقِ نظرة على كود نموذجي يستخدم دوال 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 "مرحبًا بك!";\n} else {\n echo "اسم المستخدم أو كلمة المرور غير صحيحة";\n}\n?>\n\nيبدو غير ضار؟ والآن تخيل أن مخترقًا يُدخل في حقل username السلسلة التالية:
admin' OR '1'='1\n\nيتحول الاستعلام إلى:
\n\nSELECT * FROM users WHERE username = 'admin' OR '1'='1' AND password = '...'\n\nوفويلا — '1'='1' دائمًا صحيحة، لذلك سيعيد الاستعلام أول سجل من الجدول. المخترق يدخل إلى النظام بدون كلمة مرور. هذا هو هجوم حقن SQL (SQL Injection) الكلاسيكي. دوال mysql_* لا توفر أي وسائل مدمجة لتنقية البيانات — يجب عليك يدويًا استخدام mysql_real_escape_string()، والذي هو أيضًا مهمل.
قارن هذا مع الأساليب الحديثة حيث تكون الحماية مدمجة في البنية التحتية (المزيد عن هذا لاحقًا).
\n\nالمشكلة الثالثة: بنية قديمة وغياب الدعم
\n\nmysql_* هي واجهة إجرائية لا تدعم:
- \n
- الاستعلامات المحضرة (prepared statements) — الأداة الرئيسية للحماية من الحقن. \n
- الأسلوب الكائني (OOP) — في PHP الحديثة، من المعتاد العمل مع الكائنات. \n
- الاستعلامات المتعددة — لا يمكن تنفيذ عدة أوامر SQL في استدعاء واحد. \n
- المعاملات (Transactions) — على الرغم من إمكانية محاكاتها، لا يوجد دعم مدمج. \n
- الإجراءات المخزنة (Stored Procedures) — التعامل معها غير مريح للغاية. \n
علاوة على ذلك، لم يتم تحديث إضافة mysql_* منذ عام 2014. مطورو PHP توقفوا ببساطة عن دعمها. هذا يعني أن أي ميزات جديدة لقواعد البيانات، أو تحسينات أمنية، أو تحسينات أداء — كل هذا يمر بك دون أن تستفيد منه.
ماذا تستخدم بدلاً من mysql_*؟
\n\nلدى PHP خياران حديثان ومدعومان