مقدمة: لماذا تسبب علامات التنصيص في MySQL الإرباك؟
\n\nإذا سبق لك كتابة استعلامات SQL بلغة PHP، فبالتأكيد واجهت حيرة: متى تستخدم علامات التنصيص المفردة (' ')، ومتى تستخدم المزدوجة (" ")، ومتى تستخدم علامات backticks الغامضة (` `)؟ خطأ في حرف واحد قد يؤدي إلى خطأ نحوي في MySQL، أو الأسوأ من ذلك، ثغرة أمنية.
هذا الموضوع من أكثر الأسئلة شيوعًا على Stack Overflow (أكثر من 2 مليون مشاهدة!). وليس من دون سبب. حتى المطورين المحترفين يخطئون أحيانًا. اليوم سنضع النقاط على الحروف نهائيًا. ستتعلم:
\n\n- \n
- وظيفة كل نوع من علامات التنصيص في MySQL \n
- كيفية التعامل مع البيانات بشكل آمن في PHP \n
- لماذا تعتبر علامات التنصيص المزدوجة مشكلة (في معظم الحالات) \n
- كيف تحمي نفسك من هجمات حقن SQL \n
هيا بنا! 🚀
\n\nتشريح استعلام MySQL: ثلاثة أنواع من علامات التنصيص
\n\nفي MySQL، هناك ثلاثة رموز تبدو كعلامات تنصيص، لكن لكل منها وظيفة مختلفة تمامًا:
\n\n1. علامات التنصيص المفردة (' ') — للقيم النصية
\n\nمتى تستخدم: دائمًا عند تمرير قيمة نصية (نص، تاريخ، بريد إلكتروني، كلمة مرور).
\n\nSELECT * FROM users WHERE name = 'أحمد';\nINSERT INTO articles (title) VALUES ('MySQL للمبتدئين');\n\nيتعامل MySQL مع كل ما داخل علامات التنصيص المفردة على أنه قيمة حرفية. هذا يعني أنك تقول لقاعدة البيانات: "هذه قيمة، لا تحاول تفسيرها كاسم عمود أو أمر".
\n\n2. علامات التنصيص المزدوجة (" ") — نفس الوظيفة تقريبًا، لكن مع فارق
\n\nفي SQL القياسي، تُستخدم علامات التنصيص المزدوجة للمُعرّفات (أسماء الجداول والأعمدة). لكن MySQL تعمل افتراضيًا في وضع حيث تكون علامات التنصيص المزدوجة مكافئة للمفردة. هذا غالبًا ما يسبب الارتباك.
\n\n-- هذا سيعمل، لكن من الأفضل عدم فعله\nSELECT * FROM users WHERE name = "سارة";\n\nالمشكلة: إذا فعّلت الوضع الصارم ANSI_QUOTES، ستبدأ علامات التنصيص المزدوجة في العمل مثل backticks. سيتعطل كودك. لذلك:
القاعدة رقم 1: استخدم علامات التنصيص المفردة للنصوص. دائمًا. استخدم المزدوجة فقط إذا كنت متأكدًا تمامًا مما تفعله، أو للتوافق مع أنظمة إدارة قواعد البيانات الأخرى.
\n\n3. Backticks (` `) — لأسماء الجداول والأعمدة
\n\nBackticks (علامات التنصيص العكسية) هي مُعرّفات. تُستخدم من أجل:
\n\n- \n
- استخدام الكلمات المحجوزة كأسماء (ممارسة سيئة، لكنها تحدث) \n
- التعامل مع أسماء تحتوي على مسافات أو رموز خاصة \n
- تجنب التعارض مع الكلمات المفتاحية في MySQL \n
-- خطأ: 'select' كلمة محجوزة\nSELECT * FROM select;\n\n-- صحيح: نستخدم backticks\nSELECT * FROM `select`;\n\n-- إلزامي: اسم يحتوي على مسافة\nSELECT `user name` FROM users;\n\n-- موصى به: استخدم backticks دائمًا لأسماء الجداول والأعمدة\nSELECT `id`, `name` FROM `users` WHERE `status` = 'active';\n\nهام: لا يمكن استخدام backticks للقيم. هذا سيؤدي إلى خطأ.
\n\n-- خطأ: MySQL سيعتقد أن 'أحمد' هو اسم عمود\nSELECT * FROM users WHERE name = `أحمد`;\n\nPHP + MySQL: كيف لا تخلط بين علامات التنصيص
\n\nالآن الجزء الممتع — كيف يعمل كل هذا في PHP. PHP نفسه يستخدم علامات التنصيص المفردة والمزدوجة للنصوص، ومن السهل ارتكاب الأخطاء هنا.
\n\nالحالة رقم 1: إدخال المتغير مباشرة (خطير!)
\n\n// سيء: ثغرة حقن SQL\n$name = "أحمد'; DROP TABLE users; --";\n$query = "SELECT * FROM users WHERE name = '$name'";\n// النتيجة: SELECT * FROM users WHERE name = 'أحمد'; DROP TABLE users; --'\n\nهذا هو حقن SQL الكلاسيكي. لا تفعل هذا أبدًا!
\n\n