لماذا نتحقق من بداية ونهاية النصوص في PHP؟
\n\nتخيل أنك تبني موقعًا باستخدام PHP، وتحتاج للتحقق مما إذا كان اسم الملف ينتهي بـ .jpg؟ أو هل يبدأ البريد الإلكتروني بـ admin؟ في السابق، كان عليك استخدام حلول معقدة مثل substr() أو التعبيرات المنتظمة. لكن منذ PHP 8.0، أصبح لدينا حل أنيق — الدوال str_starts_with() و str_ends_with().
هذه الدوال ليست مجرد تحسين شكلي. إنها طرق سريعة وقابلة للقراءة وآمنة للتعامل مع النصوص، يجب على كل مطور PHP معرفتها. في هذا المقال، سنشرحها بأمثلة عملية، ونقارنها بالطرق القديمة، ونوضح كيف تتجنب الأخطاء الشائعة.
\n\nما هما str_starts_with و str_ends_with؟
\n\nظهرت كلتا الدالتين في PHP 8.0 (صدرت في نوفمبر 2020). تحلان مشكلة بسيطة: التحقق مما إذا كان النص يحتوي على بادئة (بداية) أو لاحقة (نهاية) محددة.
\n\nتوقيع الدوال
\n\nstr_starts_with(string $haystack, string $needle): bool\nstr_ends_with(string $haystack, string $needle): bool\n\n- \n
$haystack— النص الذي نبحث فيه (كومة القش). \n $needle— النص الفرعي الذي نبحث عنه (الإبرة). \n - ترجع
trueأوfalse. \n
مثال بسيط
\n\necho str_starts_with('مرحبًا بالعالم!', 'مرحبًا'); // true\necho str_ends_with('مرحبًا بالعالم!', 'بالعالم!'); // true\necho str_starts_with('مرحبًا بالعالم!', 'بالعالم'); // false\n\nهام: الدوال حساسة لحالة الأحرف. str_starts_with('PHP', 'php') سترجع false. إذا كنت بحاجة لمقارنة غير حساسة لحالة الأحرف، استخدم strtolower() أو strtoupper() لكلا النصين.
أمثلة عملية للاستخدام
\n\n1. التحقق من امتداد الملف
\n\n$filename = 'تقرير_2024.pdf';\n\nif (str_ends_with($filename, '.pdf')) {\n echo "هذا مستند PDF";\n} elseif (str_ends_with($filename, '.jpg')) {\n echo "هذه صورة";\n} else {\n echo "تنسيق غير معروف";\n}\n\nفي السابق، كان يتم ذلك باستخدام substr($filename, -4) — وكان من السهل الخطأ في طول اللاحقة. الآن الكود يُقرأ كجملة إنجليزية بسيطة: «النص ينتهي بـ».
2. التحقق من صحة الرابط أو البريد الإلكتروني
\n\n$email = 'user@gmail.com';\n$url = 'https://pythonlib.ru';\n\nif (str_ends_with($email, '@gmail.com')) {\n echo "مستخدم Gmail";\n}\n\nif (str_starts_with($url, 'https://')) {\n echo "اتصال آمن";\n}\n\n3. تصفية مصفوفة من النصوص
\n\n$files = ['صورة.jpg', 'مستند.pdf', 'صورة2.png', 'ملاحظات.txt'];\n\n$images = array_filter($files, function($file) {\n return str_ends_with($file, '.jpg') || str_ends_with($file, '.png');\n});\n\nprint_r($images); // ['صورة.jpg', 'صورة2.png']\n\nكيف كان يتم ذلك سابقًا (ولماذا الدوال الجديدة أفضل)
\n\nقبل PHP 8.0، كان المطورون يستخدمون عدة طرق. دعنا نقارنها بالدوال الجديدة.
\n\nالطريقة 1: substr()
\n\n// الطريقة القديمة: التحقق من البداية\nif (substr($string, 0, strlen('بادئة')) === 'بادئة') { ... }\n\n// الطريقة الجديدة\nif (str_starts_with($string, 'بادئة')) { ... }\n\nعيوب الطريقة القديمة:
\n- \n
- كثرة الكود: تحتاج لحساب طول النص الفرعي. \n
- خطر الخطأ عند الطول السالب (إذا كان
$needleأطول من$haystack). \n - الكود أقل قابلية للقراءة. \n
الطريقة 2: strpos()
\n\n// الطريقة القديمة: التحقق من البداية\nif (strpos($string, 'بادئة') === 0) { ... }\n\n// الطريقة الجديدة\nif (str_starts_with($string, 'بادئة')) { ... }\n\nمع strpos، من السهل ارتكاب خطأ منطقي: إذا لم تضع === 0، واكتفيت بـ == false أو == 0، فقد تحصل على نتائج غير متوقعة.