php : التعابير العادية

طريقة إنشاء الببكود

آخر تحيين: 08-05-2014

الببكود : أمثلة تطبيقية preg_replace : البحث و الإستبدال


ما هو الببكود ؟

الببكود طريقة لصياغة مجموعة من التعليمات ، لتحديد كيفية تنسيق الخط . هذه التعليمات ، نُسمّيها "وسوم الببكود" .
عندما نريد عرض نص على المتصفح ، يحتوي على الببكود . نقوم باستبدال جميع وسوم الببكود بوسوم html الخاصة بكل واحد .

لماذا الببكود ؟

أغلب المواقع الحالية ، للتفاعل مع زوارها ، تُتيح لهم إمكانية إضافة مشاركاتهم من مواضيع و تعاليق ... إلخ . مع تمكينهم غالبا من تنسيق خطّهم و تزيينه .
في الحالات العادية . لحماية موقعنا ، من المشاركات الملغومة لبعض الأعضاء ، و تجنب ثغرات XSS . نستعمل htmlspecialchars . بهذا نمنع تنفيذ جميع وسوم html . و نحرم بذلك حتى الزوار ، حسنوا النوايا ، من دعم محتواهم بالصور و الروابط و تنسيق خطهم و تزيينه .
مثلا إذا أراد الزائر إعطاء أهمية لجزء من النص و كتب : <strong>هذا نص مهم </strong> . عند إرسال الإستمارة ، فإن نصه سيُعرض على المتصفح ، كما كتبه . أي : "<strong>هذا نص مهم </strong>" . لأن htmlspecialchars منعت تنفيذه .
الحل ، لن نستغني عن htmlspecialchars طبعا ، مجرد التفكير في هذا ممنوع عليكم . بل سنستعمل وسوم الببكود . و بها سنسمح لجميع وسوم html التي نريد إتاحتها لزوارنا . ستعتبر htmlspecialchars وسومنا الجديدة كنص عادي ، و تسمح بمرورها بسلام كما كتبناها . أثناء العرض ، سيتم كل شيء ، إذ سنقوم بتحويل جميع وسوم الببكود إلى وسوم html الخاصة بها ، حتى يتم التعرف عليها من قبل المتصفّح و تنفيذها .
لاستبدال الوسوم سنستعمل الدالة preg_replace .

طريقة كتابة الببكود

لإنشاء الببكود ، سنتبع تقريبا نفس الطريقة التي تستعملها لغة html . لكننا أحرار في اختيار إسم الوسم أو الرّموز التي تُحدّده . مثلا لإنشاء وسم بديل للوسم strong :
[strong]هذا النص مهم[/strong] استعملت المعقوفتين "[ ]" بدل الرمزين أصغر و أكبر "< >" المألوفين . يمكنني أيضا استعمال رموز أخرى ، مثلا : {strong}هذا النص مهم{/strong} .
بما أن هذه لغتنا و من صنع أيدينا . يمكننا إعطاء أسماء قصيرة لوسومنا بدل strong نستعمل مثلا حرف "b" الذي يعني bold أي سميك :
[b]هذا النص مهم[/b] .
أو يمكنكم تسميتها كما شئتم ، مثلا
[samik]هذا النص مهم[/samik] أو
[سميك/]هذا النص مهم[سميك]

المبدأ كالتالي نقوم بإنشاء الببكود مثلا [b] [/b] . ثم باستعمال preg_replace نقوم بتبديله بالوسم الحقيقي الذي يخصه مثلا <strong> </strong>

<?php 
$text = "this is [b]the bold[/b] text ";

$ijad = "#\[b\]the bold\[/b\]#"; // إيجاد وسم الببكود
$tabdil = "<strong>the bold</strong>"; // الذي يخصه html استبداله بوسم

$text = nl2br(htmlspecialchars($text));
$text = preg_replace ($ijad, $tabdil, $text);
echo $text;
?>

لاحظوا أنني استعملت علامة backslash "\" في النمط ، قبل جميع المعقوفات : "\[ \]" ، لأنها جزء من النص الذي نريد البحث عنه ، و ليست بتاتا مصفوفات .
بما أننا لن نعرف مُسبقا ما هو النص الذي سيضعه الزائر داخل وسم الببكود . سنُبدّل النص "the bold" برمز النقطة "." الذي يتيح جميع مكونات النص ، ما عدا رمز السطر الجديد "n\" .

الشيء المهم في هذه الشيفرة ، هما القوسين اللذين يحيطان النقطة "(.*?)" . القوسان يعنيان أن مايوجد داخلهما عبارة عن متغيّر . نُسمّي هذا المتغير "1$" . سيقوم بتخزين النص الذي أُدخِل بين وسمي الببكود ، حتّى نقوم بعرضه :

$tabdil = "<strong>$1</strong>";



كلما استعملنا القوسين في النمط ، سيتم إنشاء متغير "1$" تلقائيا للقوس الأول "( )" . ثم متغير "2$" للقوس الثاني و "3$" للقوس الثالث و دواليك .


استعملنا القوسين سابقا ، لإضافة معاملات التكرار و الإختيار . و تعرّفنا الآن على وظيفة أخرى لهما . و هي استعمالهما كمتغيّرات .

سؤال : كيف يمكنناالتمييز بين قوسي التكرار و قوسي المتغير ؟

عندما نريد استعمال القوسين لغرض التكرار أو الإختيار ، نضيف نقطتين مسبوقتين بعلامة استفهام مباشرة بعد فتح القوس الأول " (?: " . لنأخذ المثال التالي :
(.?*)\.(?:jpg|gif|png)
لدينا في هذه الحالة مُتغيّر "1$" فقط ، الذي يُمثّل القوسين الأولين (.?*) أمّا القوسان المتبقيان (?:jpg|gif|png) ، فقد جرّدتهما من صفة متغير . و أصبحا لغرض الإختيار .

مُحوّل النمط

بما أن رمز النقطة "." لا يُتيح لنا السطر الجديد ، لتفعيل هذا الأخير ، تلاحظون أنني أضفت المُحوِّل "s" في نهاية النمط " s# " . هذا المحول يتيح لنا تطبيق النمط على أكثر من سطر . خاصة أثناء بداية سطر جديد . إذا لم نُضف المحول "s" ، سيتم تطبيق النمط على السطر الأول فقط . و لن يُطبق على الباقي .
يمكنكم أيضا إضافة المُحوّل "i" إذا أردتم السماح للحروف الكبيرة في الوسم ، مثلا : [B] [/B]

"#\[b\](.*?)\[/b\]#is"

يوجد مُحوّل ثالث "U" : و هو ضروري في حالة تكرار استعمال نفس وسم الببكود مرات عدة في النص . مثلا :
"this [b]text is bold[/b] , also [b]this one[/b] , but this one is not".
إذا نسينا إضافة المُحوّل ، سيتم تطبيق النمط على كل النص ، و ليس على النصوص التي حدّدتموها .
يمكننا الإستغناء عن المُحوّل "U" في حالة مثالنا . لقد عوّضت المُحوّل باستعمال رمز الإستفهام "?" . الذي يعني أن المكوّن الذي قبله "*"، يمكن أن يظهر إما مرّة واحدة أو لا شيء . حتى يتم الفصل بين نفس وسوم الببكود في النص .
خلاصة ، لدينا خياران لكتابة نمط الببكود "[b] [/b]" :

// "?" استعمال رمز الإستفهام
"#\[b\](.*?)\[/b\]#s"
// "U" أو استعمال المُحوّل 
"#\[b\](.*)\[/b\]#sU"

مثال تطبيقي

<?php 
$_POST['text'] = "هذا نص عادي . [b]هذا نص مهم[/b] . هذا أيضا نص عادي ";

if(!empty($_POST['text']))
{
  $text = nl2br(htmlspecialchars($_POST['text']));
  
  $ijad = "#\[b\](.*?)\[/b\]#s";
  $tabdil = "<strong>$1</strong>";

  $text = preg_replace ($ijad, $tabdil, $text);
  echo $text;
}
?>

النتيجة : " هذا نص عادي . هذا نص مهم . هذا أيضا نص عادي "

كل ما تبقى لكم الآن ، هو إضافة جميع الببكودات التي ترغبون فيها . سنرى في الدّرس المقبل ، أهمها .