htmlentities() vs. htmlspecialchars(): معركة عمالقة التعقيم في PHP
\n\nإذا سبق لك التعامل مع عرض بيانات المستخدمين على صفحة ويب، فبالتأكيد سمعت عن الدالتين htmlentities() و htmlspecialchars(). هما أداتا PHP الأساسيتان للحماية من هجمات XSS (Cross-Site Scripting) ولعرض رموز HTML بشكل صحيح. لكن ما الفرق بينهما؟ أي منهما مناسب للمبتدئ، وأيهما للمحترف؟ دعنا نفهم الأمر مرة واحدة وإلى الأبد.
تخيل أنك تبني مدونة بـ PHP، وأحد المستخدمين أدخل تعليقًا: <script>alert('XSS')</script>. إذا قمت بعرضه مباشرة، سيقوم المتصفح بتنفيذ الكود. كارثة! هنا يأتي دور htmlspecialchars() و htmlentities(). لكن كل منهما يعمل بطريقة مختلفة.
ما المشترك بين htmlspecialchars() و htmlentities()؟
\n\nكلتا الدالتين تقومان بتحويل الرموز الخاصة في HTML إلى كيانات HTML (entities). على سبيل المثال:
\n- \n
&(علامة العطف) →&\n <(أصغر من) →<\n >(أكبر من) →>\n "(الاقتباس المزدوج) →"\n '(الاقتباس المفرد) →'(أو'حسب العلم) \n
بدونهما، أي إدخال يحتوي على أقواس زاوية أو علامات عطف سيكسر تنسيق الصفحة أو يفتح الباب أمام المخترقين.
\n\nالفرق الرئيسي: نطاق التحويل
\n\nهنا يكمن السر. htmlspecialchars() هي المقاتل الاقتصادي. تقوم بتحويل خمسة رموز أساسية فقط لها معنى مباشر في HTML:
- \n
&→&\n <→<\n >→>\n "→"\n '→'(إذا تم تفعيل العلمENT_QUOTES)
أما htmlentities() فهي المثالية. تقوم بتحويل جميع الرموز التي لها كيانات HTML مقابلة. ليس فقط الأقواس الزاوية، بل أيضًا رموز العملات (€, £, ¥)، العلامات الرياضية (∑, ∂)، الحروف ذات العلامات التشكيلية (é, ñ, ü)، وحتى الرموز التعبيرية (☺).
مثال بسيط: الفرق عمليًا
\n\nلننظر إلى الكود. افترض أن لدينا نصًا بالفرنسية:
\n\n<?php\n$text = "Café & thé <script>alert('test')</script>";\necho "htmlspecialchars: " . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') . "<br>";\necho "htmlentities: " . htmlentities($text, ENT_QUOTES, 'UTF-8');\n?>\n\nالنتيجة:
\nhtmlspecialchars: Café & thé <script>alert('test')</script>\nhtmlentities: Café & thé <script>alert('test')</script>\n\nفي هذا المثال لا يوجد فرق، لأن الحروف مثل "é" ليس لها معنى خاص في HTML. لكن دعنا نجرب مع رموز لها كيانات:
\n\n<?php\n$text = "€ 100 <b>bold</b>";\necho "htmlspecialchars: " . htmlspecialchars($text, ENT_QUOTES, 'UTF-8') . "<br>";\necho "htmlentities: " . htmlentities($text, ENT_QUOTES, 'UTF-8');\n?>\n\nالنتيجة:
\nhtmlspecialchars: € 100 <b>bold</b>\nhtmlentities: € 100 <b>bold</b>\n\nهل ترى؟ htmlentities() حولت رمز اليورو "€" إلى كيان €. بينما htmlspecialchars() تركته كما هو. لماذا؟ لأن "€" ليس رمزًا خطيرًا في HTML — المتصفح سيعرضه بشكل صحيح حتى بدون تعقيم.
متى تستخدم htmlspecialchars()؟
\n\nهذا هو اختيارك الافتراضي. استخدم htmlspecialchars() في 99% من الحالات عند عرض بيانات المستخدم