Skip to content

3. أساسيات PHP

3.1. مثال أول

فيما يلي برنامج يعرض الميزات الأولى لـ PHP.

3.1.1. البرنامج (exemple_01)


<?php

// هذا تعليق
// متغير مستخدم دون أن يتم إعلانه
$nom = "dupont";

// عرض على الشاشة
print "nom=$nom\n";

// مصفوفة تحتوي على عناصر من أنواع مختلفة
$tableau = array("un", "deux", 3, 4);

// عدد عناصره
$n = count($tableau);

// حلقة
for ($i = 0; $i < $n; $i++)
  print "tableau[$i]=$tableau[$i]\n";

// تهيئة متغيرين بمحتوى مصفوفة
list($chaine1, $chaine2) = array("chaine1", "chaine2");

// تسلسل السلسلتين
$chaine3 = $chaine1 . $chaine2;

// عرض النتيجة
print "[$chaine1,$chaine2,$chaine3]\n";

// استخدام دالة
affiche($chaine1);

// يمكن معرفة نوع المتغير
afficheType($n);
afficheType($chaine1);
afficheType($tableau);

// يمكن أن يتغير نوع المتغير أثناء التنفيذ
$n = "a changé";
afficheType($n);

// يمكن للدالة أن تُرجع نتيجة
$res1 = f1(4);
print "res1=$res1\n";

// يمكن للدالة أن ترجع مصفوفة من القيم
list($res1, $res2, $res3) = f2();
print "(res1,res2,res3)=[$res1,$res2,$res3]\n";

// كان من الممكن استرداد هذه القيم في مصفوفة
$t = f2();
for ($i = 0; $i < count($t); $i++)
  print "t[$i]=$t[$i]\n";

// اختبارات
for ($i = 0; $i < count($t); $i++)
// يعرض القنوات فقط
  if (getType($t[$i]) == "string")
    print "t[$i]=$t[$i]\n";

// اختبارات أخرى
for ($i = 0; $i < count($t); $i++){
// يعرض فقط الأعداد الصحيحة الأكبر من 10
  if (getType($t[$i]) == "integer" and $t[$i] > 10)
    print "t[$i]=$t[$i]\n";
}

// حلقة while
$t = array(8, 5, 0, -2, 3, 4);
$i = 0;
$somme = 0;
while ($i < count($t) and $t[$i] > 0) {
  print "t[$i]=$t[$i]\n";
  $somme+=$t[$i];   //$somme=$somme+$t[$i]
  $i++;             //$i=$i+1
}
print "somme=$somme\n";

// نهاية البرنامج
exit;

//----------------------------------
function affiche($chaine) {
  // يعرض $chaine
  print "chaine=$chaine\n";
}

//----------------------------------
function afficheType($variable) {
  // يعرض نوع $variable
  print "type[$variable]=" . getType($variable) . "\n";
}

//----------------------------------
function f1($param) {
  // يضيف 10 إلى $param
  return $param + 10;
}

//----------------------------------
function f2() {
  // تُرجع 3 قيم
  return array("un", 0, 100);
}
?>

النتائج:

nom=dupont
tableau[0]=un
tableau[1]=deux
tableau[2]=3
tableau[3]=4
[chaine1,chaine2,chaine1chaine2]
chaine=chaine1
type[4]=integer
type[chaine1]=string
type[Array]=array
type[a changé]=string
res1=14
(res1,res2,res3)=[un,0,100]
t[0]=un
t[1]=0
t[2]=100
t[0]=un
t[2]=100
t[0]=8
t[1]=5
somme=13

تعليقات

  • السطر 5: في PHP، لم يتم تحديد نوع المتغيرات. هذه المتغيرات لها نوع ديناميكي يمكن أن يتغير بمرور الوقت
  • $nom تمثل المتغير ذي المعرف nom
  • السطر 8: للكتابة على الشاشة، يمكن استخدام الأمر print أو الأمر echo
  • السطر 11: تسمح الكلمة الرئيسية array بتعريف مصفوفة. المتغير $nom[$i] يمثل العنصر $i في المصفوفة $tableau.
  • السطر 14: تُرجع الدالة count($tableau) عدد عناصر المصفوفة $tableau
  • السطر 18: السلاسل محاطة بعلامات اقتباس " أو علامات اقتباس مائلة '. داخل علامات الاقتباس، يتم تقييم المتغيرات $variable ولكن ليس داخل علامات الاقتباس المائلة.
  • السطر 21: تتيح الدالة list تجميع المتغيرات في قائمة وتعيين قيمة لها بعملية تعيين واحدة. هنا $chaine1="chaine1" و $chaine2="chaine2".
  • السطر 24: العلامة . هي علامة ربط السلاسل.
  • السطر 88: الكلمة الرئيسية function تُعرّف دالة. تُرجع الدالة قيمًا أو لا تُرجعها بواسطة الأمر return. يمكن للكود المستدعي تجاهل نتائج الدالة أو استردادها. يمكن تعريف الدالة في أي مكان في الكود.
  • السطر 90: الدالة المُعرَّفة مسبقًا getType($variable) تُرجع سلسلة أحرف تمثل نوع $variable. وقد يتغير هذا النوع بمرور الوقت.
  • السطر 79: الدالة المُعرَّفة مسبقًا exit تُوقف تشغيل البرنامج النصي.

3.2. نطاق المتغيرات

3.2.1. البرنامج 1 (exemple_02)


<?php

// نطاق المتغيرات

function f1() {
  // يتم استخدام المتغير العام $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 10;
  print "f1[i,j]=[$i,$j]\n";
}

function f2() {
  // يتم استخدام المتغير العام $i
  $i = &$GLOBALS["i"];
  $i++;
  $j = 20;
  print "f2[i,j]=[$i,$j]\n";
}

function f3() {
  // يتم استخدام متغير محلي $i
  $i = 4;
  $j = 30;
  print "f3[i,j]=[$i,$j]\n";
}

// اختبارات
$i = 0;
$j = 0;  // هاتان المتغيرتان معروفتان لدالة f عبر المصفوفة $GLOBALS
f1();
f2();
f3();
print "test[i,j]=[$i,$j]\n";
?>

النتائج:

1
2
3
4
f1[i,j]=[1,10]
f2[i,j]=[2,20]
f3[i,j]=[4,30]
test[i,j]=[2,0]

تعليقات

  • السطران 29-30: يحددان متغيرين $i و $j من البرنامج الرئيسي. هذه المتغيرات غير معروفة داخل الدوال. وبالتالي، في السطر 9، فإن المتغير $j الخاص بالدالة f1 هو متغير محلي للدالة f1 ويختلف عن المتغير $j في البرنامج الرئيسي. يمكن لدالة الوصول إلى متغير $variable في البرنامج الرئيسي عبر مصفوفة من المتغيرات العالمية تسمى $GLOBALS. في السطر 7، تشير الصيغة $GLOBALS["i"] إلى المتغير العام $i في البرنامج الرئيسي. إذا كتبنا
$i=$GLOBALS["i"]

يتم تعيين قيمة المتغير العام $i إلى المتغير المحلي $i. وهنا لدينا متغيران مختلفان، ولن يؤدي تعديل المتغير المحلي $i إلى تغيير المتغير العام $i. الترميز

$i=&Globals["i"]

يجعل المتغير المحلي $i له نفس عنوان الذاكرة للمتغير العام $i. وبالتالي، فإن التعامل مع المتغير المحلي $i يعادل التعامل مع المتغير العام $i.

3.2.2. البرنامج 2 (exemple_03)


<?php

// نطاق المتغير شامل لجميع كتل الكود
$i = 0; {
  $i = 4;
  $i++;
}
print "i=$i\n";
?>

النتائج:

i=5

تعليقات

في بعض اللغات، يكون نطاق المتغير المُعرَّف داخل الأقواس المتعقبة هو نطاق هذه الأقواس: أي أنه غير معروف خارجها. تُظهر النتائج أعلاه أن الأمر ليس كذلك في لغة PHP. المتغير $i المُعرَّف في السطر 5 داخل الأقواس المتعقوفة هو نفسه المتغير المستخدم في السطرين 4 و8 خارجها.

3.3. الجداول

3.3.1. الجداول التقليدية أحادية البعد (exemple_04)


<?php

// المصفوفات التقليدية
// التعيين
$tab1 = array(0, 1, 2, 3, 4, 5);

// التجول - 1
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// التجول - 2
print "tab1 a " . count($tab1) . " éléments\n";
reset($tab1);
while (list($clé, $valeur) = each($tab1))
  print "tab1[$clé]=$valeur\n";

// إضافة عناصر
$tab1[] = $i++;
$tab1[] = $i++;

// التنقل - 3
print "tab1 a " . count($tab1) . " éléments\n";
$i = 0;
foreach ($tab1 as $élément) {
  print "tab1[$i]=$élément\n";
  $i++;
}

// حذف العنصر الأخير
array_pop($tab1);

// المسار - 4
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// حذف العنصر الأول
array_shift($tab1);

// التنقل - 5
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// إضافة في نهاية الجدول
array_push($tab1, -2);

// مسار - 6
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";

// إضافة في بداية الجدول
array_unshift($tab1, -1);

// التنقل - 7
print "tab1 a " . count($tab1) . " éléments\n";
for ($i = 0; $i < count($tab1); $i++)
  print "tab1[$i]=$tab1[$i]\n";
?>

النتائج:

tab1 a 6 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1 a 6 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1 a 8 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1[6]=6
tab1[7]=7
tab1 a 7 éléments
tab1[0]=0
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1[6]=6
tab1 a 6 éléments
tab1[0]=1
tab1[1]=2
tab1[2]=3
tab1[3]=4
tab1[4]=5
tab1[5]=6
tab1 a 7 éléments
tab1[0]=1
tab1[1]=2
tab1[2]=3
tab1[3]=4
tab1[4]=5
tab1[5]=6
tab1[6]=-2
tab1 a 8 éléments
tab1[0]=-1
tab1[1]=1
tab1[2]=2
tab1[3]=3
tab1[4]=4
tab1[5]=5
tab1[6]=6
tab1[7]=-2

تعليقات

يُظهر البرنامج أعلاه عمليات معالجة مصفوفة من القيم. توجد طريقتان لكتابة المصفوفات في PHP:

$tableau=array("un",2,"trois")
$contraires=array("petit"=>"grand", "beau"=>"laid", "cher"=>"bon marché")

يُطلق على المصفوفة 1 اسم «مصفوفة»، أما المصفوفة 2 فتُسمى «قاموس» حيث تُدوّن العناصر على النحو التالي: المفتاح => القيمة. تشير الصيغة $contraires["beau"] إلى القيمة المرتبطة بالمفتاح "جميل". وهي هنا السلسلة "قبيح". المصفوفة 1 ليست سوى شكل آخر من أشكال القاموس ويمكن تدوينها على النحو التالي:

$tableau=array(0=>"un",1=>2,2=>"trois")

وبذلك نحصل على $tableau[2]="trois". في النهاية، لا يوجد سوى القواميس. في حالة مصفوفة تقليدية مكونة من n عنصرًا، تكون المفاتيح هي الأعداد الصحيحة من النطاق [0,n-1].

  • السطر 15: تسمح الدالة each($tableau) بالتنقل عبر القاموس. وعند كل استدعاء، تُرجع زوجًا (مفتاح، قيمة) منه.
  • السطر 14: تضع الدالة reset($dictionnaire) الدالة each على الزوج الأول (مفتاح، قيمة) من القاموس.
  • السطر 15: تتوقف الحلقة while عندما تُرجع الدالة each زوجًا فارغًا عند نهاية القاموس.
  • السطر 19: تضيف صيغة $tableau[]=قيمة العنصر valeur كآخر عنصر في $tableau.
  • السطر 25: يتم تصفح المصفوفة باستخدام foreach. يسمح هذا العنصر النحوي بتصفح قاموس، وبالتالي مصفوفة، وفقًا لنظامين نحويين:
foreach($dictionnaire as $clé=>$valeur)
foreach($tableau as $valeur)

تُرجع الصيغة الأولى زوجًا (clé,valeur) في كل تكرار، بينما تُرجع الصيغة الثانية العنصر valeur من القاموس فقط.

  • السطر 31: الدالة array_pop($tableau) تحذف العنصر الأخير من $tableau
  • السطر 39: تقوم الدالة array_shift($tableau) بحذف العنصر الأول من $tableau
  • السطر 47: تضيف الدالة array_push($tableau,قيمة) valeur كعنصر أخير في $tableau
  • السطر 39: تضيف الدالة array_unshift($tableau، القيمة) valeur كأول عنصر في $tableau

3.3.2. القاموس (exemple_05)


<?php

// قواميس
$conjoints = array("Pierre" => "Gisèle", "Paul" => "Virginie", "Jacques" => "Lucette", "Jean" => "");

// مسار - 1
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
  print "conjoints[$clé]=$valeur\n";

// فرز القاموس حسب المفتاح
ksort($conjoints);

// مسار - 2
reset($conjoints);
while (list($clé, $valeur) = each($conjoints))
  print "conjoints[$clé]=$valeur\n";

// قائمة مفاتيح القاموس
$clés = array_keys($conjoints);
for ($i = 0; $i < count($clés); $i++)
  print "clés[$i]=$clés[$i]\n";

// قائمة قيم القاموس
$valeurs = array_values($conjoints);
for ($i = 0; $i < count($valeurs); $i++)
  print "valeurs[$i]=$valeurs[$i]\n";

// البحث عن مفتاح
existe($conjoints, "Jacques");
existe($conjoints, "Lucette");
existe($conjoints, "Jean");

// حذف مفتاح وقيمة
unset($conjoints["Jean"]);
print "Nombre d'éléments du dictionnaire : " . count($conjoints) . "\n";
foreach ($conjoints as $clé => $valeur) {
  print "conjoints[$clé]=$valeur\n";
}

// النهاية
exit;

function existe($conjoints, $mari) {
  // التحقق من وجود المفتاح $mari في القاموس $conjoints
  if (isset($conjoints[$mari]))
    print "La clé [$mari] existe associée à la valeur [$conjoints[$mari]]\n";
  else
    print "La clé [$mari] n'existe pas\n";
}

?>

النتائج:

Nombre d'éléments du dictionnaire : 4
conjoints[Pierre]=Gisèle
conjoints[Paul]=Virginie
conjoints[Jacques]=Lucette
conjoints[Jean]=
conjoints[Jacques]=Lucette
conjoints[Jean]=
conjoints[Paul]=Virginie
conjoints[Pierre]=Gisèle
clés[0]=Jacques
clés[1]=Jean
clés[2]=Paul
clés[3]=Pierre
valeurs[0]=Lucette
valeurs[1]=
valeurs[2]=Virginie
valeurs[3]=Gisèle
La clé [Jacques] existe associée à la valeur [Lucette]
La clé [Lucette] n'existe pas
La clé [Jean] existe associée à la valeur []
Nombre d'éléments du dictionnaire : 3
conjoints[Jacques]=Lucette
conjoints[Paul]=Virginie
conjoints[Pierre]=Gisèle

تعليقات

يطبق الكود السابق على القاموس ما سبق أن تناولناه سابقًا بالنسبة لمصفوفة بسيطة. وسنكتفي بالتعليق على العناصر الجديدة فقط:

  • السطر 13: تتيح الدالة ksort (فرز حسب المفتاح) فرز القاموس حسب الترتيب الطبيعي للمفتاح.
  • السطر 21: تعرض الدالة array_keys($dictionnaire) قائمة مفاتيح القاموس في شكل جدول
  • السطر 26: تعرض الدالة array_values($dictionnaire) قائمة قيم القاموس في شكل مصفوفة
  • السطر 47: تعرض الدالة isset($variable) القيمة true إذا تم تعريف المتغير $variable، وإلا تعرض القيمة false.
  • السطر 36: الدالة unset($variable) تحذف المتغير $variable.

3.3.3. المصفوفات متعددة الأبعاد (exemple_06)


<?php

// الجداول التقليدية متعددة الأبعاد
// التهيئة
$multi = array(array(0, 1, 2), array(10, 11, 12, 13), array(20, 21, 22, 23, 24));
// التصفح
for ($i1 = 0; $i1 < count($multi); $i1++)
  for ($i2 = 0; $i2 < count($multi[$i1]); $i2++)
    print "multi[$i1][$i2]=" . $multi[$i1][$i2] . "\n";
// قواميس متعددة الأبعاد
// التهيئة
$multi = array("zéro" => array(0, 1, 2), "un" => array(10, 11, 12, 13), "deux" => array(20, 21, 22, 23, 24));
// التصفح
foreach ($multi as $clé => $valeur)
  for ($i2 = 0; $i2 < count($valeur); $i2++)
    print "multi[$clé][$i2]=" . $multi[$clé][$i2] . "\n";
?>

النتائج:

multi[0][0]=0
multi[0][1]=1
multi[0][2]=2
multi[1][0]=10
multi[1][1]=11
multi[1][2]=12
multi[1][3]=13
multi[2][0]=20
multi[2][1]=21
multi[2][2]=22
multi[2][3]=23
multi[2][4]=24
multi[zéro][0]=0
multi[zéro][1]=1
multi[zéro][2]=2
multi[un][0]=10
multi[un][1]=11
multi[un][2]=12
multi[un][3]=13
multi[deux][0]=20
multi[deux][1]=21
multi[deux][2]=22
multi[deux][3]=23
multi[deux][4]=24

تعليقات

  • السطر 5: عناصر المصفوفة $multi هي نفسها مصفوفات
  • السطر 12: يصبح المصفوفة $multi قاموسًا (clé,valeur) حيث كل valeur هو مصفوفة

3.3.4. الروابط بين السلاسل والجداول (exemple_07)


<?php

// تحويل سلسلة إلى مصفوفة
$chaine = "1:2:3:4";
$tab = explode(":", $chaine);

// التنقل في المصفوفة
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n";

// مصفوفة إلى سلسلة
$chaine2 = implode(":", $tab);
print "chaine2=$chaine2\n";

// إضافة حقل فارغ
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);

// تجول في المصفوفة
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n"; // لدينا الآن 5 عناصر، آخرها فارغ
  
// لنضف حقلًا فارغًا مرة أخرى
$chaine.=":";
print "chaîne=$chaine\n";
$tab = explode(":", $chaine);

// التنقل عبر المصفوفة
print "tab a " . count($tab) . " éléments\n";
for ($i = 0; $i < count($tab); $i++)
  print "tab[$i]=$tab[$i]\n"; // لدينا الآن 6 عناصر، وآخر عنصرين فارغان
?>

النتائج:

tab a 4 éléments
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
chaine2=1:2:3:4
chaîne=1:2:3:4:
tab a 5 éléments
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
tab[4]=
chaîne=1:2:3:4::
tab a 6 éléments
tab[0]=1
tab[1]=2
tab[2]=3
tab[3]=4
tab[4]=
tab[5]=

تعليقات

  • السطر 5: تسمح الدالة explode($séparateur,$chaine) باسترداد حقول $chaine المفصولة بـ $séparateur. وبالتالي، تسمح الدالة explode(":",$chaine) باسترداد عناصر $chaine المفصولة بالسلسلة ":" في شكل مصفوفة.
  • أما الدالة implode($séparateur,$tableau) فتقوم بالعملية المعاكسة للدالة explode. فهي تُرجع سلسلة أحرف مكونة من عناصر $tableau المفصولة بـ $séparateur.

3.4. سلاسل الأحرف

3.4.1. الترميز (exemple_08)


<?php

// تدوين السلاسل
$chaine1 = "un";
$chaine2 = 'un';
print "[$chaine1,$chaine2]\n";
?>

النتائج:

[un,un]

3.4.2. المقارنة (exemple_09)


<?php

// اختبارات مقارنة السلاسل
compare("abcd", "abcd");
compare("", "");
compare("1", "");
exit;

function compare($chaine1, $chaine2) {
  // مقارنة السلسلة 1 بالسلسلة 2
  if ($chaine1 == $chaine2)
    print "[$chaine1] est égal à [$chaine2]\n";
  else
    print "[$chaine1] est différent de [$chaine2]\n";
}

?>

النتائج:

1
2
3
[abcd] est égal à [abcd]
[] est égal à []
[1] est différent de []

3.5. التعبيرات العادية (exemple_10)


<?php

// التعبيرات النمطية في PHP
// استرداد الحقول المختلفة لسلسلة

// النمط: سلسلة من الأرقام محاطة بأي أحرف
// نريد استخراج سلسلة الأرقام فقط
$modèle = "/(\d+)/";
// مقارنة السلسلة بالنموذج
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");

// النموذج: سلسلة من الأرقام محاطة بأي أحرف
// نريد سلسلة الأرقام بالإضافة إلى الحقول التي تليها وتسبقها
$modèle = "/^(.*?)(\d+)(.*?)$/";
// نقوم بمقارنة السلسلة بالنموذج
compare($modèle, "xyz1234abcd");
compare($modèle, "12 34");
compare($modèle, "abcd");

// القالب - تاريخ بتنسيق يوم/شهر/سنة
$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";
compare($modèle, "10/05/97");
compare($modèle, "  04/04/01  ");
compare($modèle, "5/1/01");

// القالب - رقم عشري
$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";
compare($modèle, "187.8");
compare($modèle, "-0.6");
compare($modèle, "4");
compare($modèle, ".6");
compare($modèle, "4.");
compare($modèle, " + 4");

// النهاية
exit;

// --------------------------------------------------------------------------
function compare($modèle, $chaîne) {
  // يقارن السلسلة $chaîne بالنموذج $modèle
  // مقارنة السلسلة بالنموذج
  $correspond = preg_match($modèle, $chaîne, $champs);
  // عرض النتائج
  print "\nRésultats($modèle,$chaîne)\n";
  if ($correspond) {
    for ($i = 0; $i < count($champs); $i++)
      print "champs[$i]=$champs[$i]\n";
  } else
    print "La chaîne [$chaîne] ne correspond pas au modèle [$modèle]\n";
}
?>

النتائج:

Résultats(/(\d+)/,xyz1234abcd)
champs[0]=1234
champs[1]=1234

Résultats(/(\d+)/,12 34)
champs[0]=12
champs[1]=12

Résultats(/(\d+)/,abcd)
La chaîne [abcd] ne correspond pas au modèle [/(\d+)/]

Résultats(/^(.*?)(\d+)(.*?)$/,xyz1234abcd)
champs[0]=xyz1234abcd
champs[1]=xyz
champs[2]=1234
champs[3]=abcd

Résultats(/^(.*?)(\d+)(.*?)$/,12 34)
champs[0]=12 34
champs[1]=
champs[2]=12
champs[3]= 34

Résultats(/^(.*?)(\d+)(.*?)$/,abcd)
La chaîne [abcd] ne correspond pas au modèle [/^(.*?)(\d+)(.*?)$/]

Résultats(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,10/05/97)
champs[0]=10/05/97
champs[1]=10
champs[2]=05
champs[3]=97

Résultats(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,  04/04/01  )
champs[0]=  04/04/01  
champs[1]=04
champs[2]=04
champs[3]=01

Résultats(/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/,5/1/01)
La chaîne [5/1/01] ne correspond pas au modèle [/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/]

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,187.8)
champs[0]=187.8
champs[1]=
champs[2]=187.8

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,-0.6)
champs[0]=-0.6
champs[1]=-
champs[2]=0.6

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,4)
champs[0]=4
champs[1]=
champs[2]=4

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,.6)
champs[0]=.6
champs[1]=
champs[2]=.6

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/,4.)
champs[0]=4.
champs[1]=
champs[2]=4.

Résultats(/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/, + 4)
champs[0]= + 4
champs[1]=+
champs[2]=4

تعليقات

  • السطران 3-4: نستخدم هنا التعبيرات النمطية لاستخراج الحقول المختلفة من سلسلة أحرف. تتيح التعبيرات النمطية تجاوز حدود الدالة implode. المبدأ هو مقارنة سلسلة أحرف بسلسلة أخرى تسمى modèle باستخدام الدالة preg_match:

$correspond = preg_match($modèle, $chaîne, $champs);

تُرجع الدالة preg_match قيمة منطقية إذا كان من الممكن العثور على modèle في chaîne. إذا كان الأمر كذلك، فإن $champs[0] تمثل السلسلة الفرعية المطابقة للنموذج. من ناحية أخرى، إذا كان النموذج يحتوي على نماذج فرعية بين قوسين، فإن $champs[1] هو الجزء من $chaîne المطابق للنموذج الفرعي الأول، و $champs[2] هو الجزء من $chaîne الذي يتوافق مع النموذج الفرعي الثاني، وهكذا دواليك...

لنأخذ المثال الأول. يتم تعريف النموذج في السطر 8: وهو يشير إلى سلسلة من رقم واحد أو أكثر (+) من الأرقام (\d) موضوعة في أي مكان في السلسلة. علاوة على ذلك، يحدد النموذج نموذجًا فرعيًا محاطًا بأقواس.

  • السطر 10: يتم مقارنة النموذج /(\d+)/ (سلسلة من رقم واحد أو أكثر في أي مكان في السلسلة) بالسلسلة "xyz1234abcd". نرى أن السلسلة الفرعية 1234 تتطابق مع النموذج. وبالتالي، سيكون $champs[0] مساويًا لـ "1234". من ناحية أخرى، يحتوي النمط على أنماط فرعية بين الأقواس. فسنحصل على $champs[1] = "1234".
  • السطر 11: يتم مقارنة النمط /(\d+)/ بالسلسلة "12 34". نلاحظ أن السلسلتين الفرعيتين 12 و34 تتطابقان مع النمط. تتوقف المقارنة عند أول سلسلة فرعية تتطابق مع النمط. وبالتالي، سيكون لدينا $champs[0]=12 و $champs[1]=12.
  • السطر 12: يتم مقارنة النمط /(\d+)/ بالسلسلة "abcd". لم يتم العثور على أي تطابق.

دعونا نوضح الأنماط المستخدمة في بقية الكود:


$modèle = "/^(.*?)(\d+)(.*?)$/";

بداية السلسلة (^)، ثم صفر أو أكثر (*) من الأحرف العشوائية (.)، ثم رقم واحد أو أكثر (+)، ثم مرة أخرى صفر أو أكثر (*) من الأحرف العشوائية (.). يشير النمط (.*) إلى صفر أو أكثر من الأحرف العشوائية. سيتطابق هذا النمط مع أي سلسلة. وبالتالي، لن يتم العثور أبدًا على النمط /^(.*)(\d+)(.*)$/ لأن النمط الفرعي الأول (.*) سيستوعب السلسلة بأكملها. أما النمط (.*?)(\d+) فيشير إلى صفر أو أكثر من الأحرف العشوائية حتى النمط الفرعي التالي (؟)، وهو هنا \d+. وبالتالي، لم تعد الأرقام تُستوعب الآن بواسطة النمط (.*). وبالتالي، فإن النمط أعلاه يتطابق مع [début de chaîne (^), une suite de caractères quelconques (.*?), une suite d'un ou plusieurs chiffres (\d+), une suite de caractères quelconques (.*?), la fin de la chaîne ($)].


$modèle = "/^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$/";

يتطابق مع [début de chaîne (^), 2 chiffres (\d\d), le caractère / (\/), 2 chiffres, /, 2 chiffres, une suite de 0 ou plusieurs espaces (\s*), la fin de chaîne ($)]


$modèle = "/^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*/";

[début de chaîne (^), 0 ou plusieurs espaces (\s*), un signe + ou - [+|-] présent 0 ou 1 fois (?), une suite de 0 ou plusieurs espaces (\s*), 1 ou plusieurs chiffres suivis d'un point décimal suivi de zéro ou plusieurs chiffres (\d+\.\d*) ou (|) un point décimal (\.) suivi d'un ou plusieurs chiffres (\d+) ou (|) un ou plusieurs chiffres (\d+), une suite de 0 ou plusieurs espaces (\s*)].

3.6. طريقة تمرير معلمات الدوال (exemple_11)


<?php

// طريقة تمرير المعلمات

function f(&$i, $j) {
  // سيتم الحصول على $i بالرجوع إلى النموذج
  // سيتم الحصول على $j بالقيمة
  $i++;
  $j++;
  print "f[i,j]=[$i,$j]\n";
}

// ----------------------------------------اختبارات
$i = 0;
$j = 0;
// تم تمرير $i و $j بالقيمة
f($i, $j);
print "test[i,j]=[$i,$j]\n";
?>

النتائج:

f[i,j]=[1,1]
test[i,j]=[1,0]

تعليقات

يُظهر الكود أعلاه طريقتين لتمرير المعلمات إلى دالة. لنأخذ المثال التالي:

1
2
3
4
5
6
7
function f(&$a,$b){

}

// البرنامج الرئيسي
$i=10; $j=20;
f($i,$j);
  • السطر 1: يحدد المعلمات الشكلية $a و $b للدالة f. تقوم هذه الدالة بمعالجة هذين المعلمتين الشكليتين وتُرجع نتيجة.
  • السطر 7: استدعاء الدالة f بمعلمتين فعليتين هما $i و $j. يتم تحديد الروابط بين المعلمات الشكلية ($a، $b) والمعلمات الفعلية ($i، $j) في السطر 7
  • &$a: تشير علامة & إلى أن المعلمة الشكلية $a ستأخذ كقيمة عنوان المعلمة الفعلية $i. بعبارة أخرى، $a و $i هما مرجعان لنفس موقع الذاكرة. إن التعامل مع المعلمة الشكلية $a يعادل التعامل مع المعلمة الفعلية $i. وهذا ما يظهره تنفيذ الكود. يناسب هذا النمط من التمرير معلمات الإخراج والبيانات الضخمة مثل المصفوفات والقواميس. ويُطلق على هذا النمط من التمرير اسم «التمرير بالمرجع».
  • $b: ستتخذ المعلمة الشكلية $b القيمة نفسها التي تتخذها المعلمة الفعلية $j. وهذا يمثل تمريرًا بالقيمة. المعلمات الشكلية والفعلية هما متغيران مختلفان. ولا يؤثر التعامل مع المعلمة الشكلية $b بأي شكل من الأشكال على المعلمة الفعلية $j. وهذا ما يوضحه تنفيذ الكود. ويناسب هذا النمط من التمرير معلمات الإدخال.
  • لنفترض أن الدالة échange تقبل معلمتين شكليتين هما $a و $b. تقوم الدالة بتبديل قيمة هذين المعلمتين. وبالتالي، عند إجراء استدعاء تبديل ($i,$j)، يتوقع الكود المستدعي أن يتم تبديل قيم المعلمتين الفعليتين. وبالتالي فهما معلمتان مخرجات (يتم تعديلهما). لذا سنكتب:
function échange(&$a,&$b){....}

3.7. النتائج التي ترجعها الدالة (exemple_12)


<?php

// النتائج التي تعطيها الدالة
// يمكن للدالة أن تُرجع عدة قيم في صفيفة
list($res1, $res2, $res3) = f1(10);
print "[$res1,$res2,$res3]\n";
$res = f1(10);
for ($i = 0; $i < count($res); $i++)
  print "res[$i]=$res[$i]\n";

// يمكن للدالة أن ترجع كائنًا زائفًا
$res = f2(10);
print "[$res->res1,$res->res2,$res->res3]\n";

// نهاية
exit;

// الدالة f1
function f1($valeur) {
  // تُرجع مصفوفة ($valeur+1,$aleur+2,$baleur+3)
  return array($valeur + 1, $valeur + 2, $valeur + 3);
}

// الدالة f2
function f2($valeur) {
  // تُرجع كائنًا زائفًا ($valeur+1,$aleur+2,$baleur+3)
  $res->res1 = $valeur + 1;
  ;
  $res->res2 = $valeur + 2;
  $res->res3 = $valeur + 3;
  // يعرض الكائن
  return $res;
}

?>

النتائج

1
2
3
4
5
[11,12,13]
res[0]=11
res[1]=12
res[2]=13
[11,12,13]

تعليقات

  • يوضح البرنامج السابق أن الدالة PHP يمكنها إرجاع مجموعة من النتائج وليس نتيجة واحدة، في شكل مصفوفة أو كائن. وسيتم توضيح مفهوم الكائن لاحقًا
  • الأسطر 19-22: تُرجع الدالة f1 عدة قيم في شكل مصفوفة
  • الأسطر 25-33: تُرجع الدالة f2 عدة قيم في شكل كائن

3.8. الملفات النصية (exemple_13)


<?php

// استغلال متسلسل لملف نصي
// وهو عبارة عن مجموعة من الأسطر بالشكل login:pwd:uid:gid:infos:dir:shell
// يتم وضع كل سطر في قاموس بالصيغة login => uid:gid:infos:dir:shell

// يتم تحديد اسم الملف
$INFOS = "infos.txt";

// يتم فتحه لإنشائه
if (!$fic = fopen($INFOS, "w")) {
  print "Erreur d'ouverture du fichier $INFOS en écriture\n";
  exit;
}

// يتم إنشاء محتوى عشوائي
for ($i = 0; $i < 100; $i++)
  fputs($fic, "login$i:pwd$i:uid$i:gid$i:infos$i:dir$i:shell$i\n");
// يتم إغلاق الملف
fclose($fic);

// يتم استغلاله - تحافظ fgets على علامة نهاية السطر
// وهذا يمنع استرداد سلسلة فارغة عند قراءة سطر فارغ
// يتم فتحه لكتابة البيانات
if (!$fic = fopen($INFOS, "r")) {
  print "Erreur d'ouverture du fichier $INFOS en lecture\n";
  exit;
}
while ($ligne = fgets($fic, 1000)) {
  // نحذف علامة نهاية السطر إن وجدت
  $ligne = cutNewLineChar($ligne);
  // نضع السطر في مصفوفة
  $infos = explode(":", $ligne);
  // يتم استرداد اسم المستخدم
  $login = array_shift($infos);
  // تجاهل كلمة المرور
  array_shift($infos);
  // يتم إنشاء إدخال في القاموس
  $dico[$login] = $infos;
}
// نغلقه
fclose($fic);

// استغلال القاموس
afficheInfos($dico, "login10");
afficheInfos($dico, "X");

// النهاية
exit;

// --------------------------------------------------------------------------
function afficheInfos($dico, $clé) {
  // عرض القيمة المرتبطة بالمفتاح في القاموس $dico إذا كانت موجودة
  if (isset($dico[$clé])) {
    // القيمة موجودة - هل هي مصفوفة؟
    $valeur = $dico[$clé];
    if (is_array($valeur)) {
      print "[$clé," . join(":", $valeur) . "]\n";
    } else {
      // $valeur ليس مصفوفة
      print "[$clé,$valeur]\n";
    }
  } else {
    // $clé ليس مفتاحًا في القاموس $dico
    print "la clé [$clé] n'existe pas\n";
  }
}

// --------------------------------------------------------------------------
function cutNewLinechar($ligne) {
  // يتم حذف علامة نهاية السطر من $ligne إن وجدت
  $L = strlen($ligne);  // طول السطر
  while (substr($ligne, $L - 1, 1) == "\n" or substr($ligne, $L - 1, 1) == "\r") {
    $ligne = substr($ligne, 0, $L - 1);
    $L--;
  }
  // النهاية
  return($ligne);
}

?>

الملف infos.txt:

login0:pwd0:uid0:gid0:infos0:dir0:shell0
login1:pwd1:uid1:gid1:infos1:dir1:shell1
login2:pwd2:uid2:gid2:infos2:dir2:shell2
...
login98:pwd98:uid98:gid98:infos98:dir98:shell98
login99:pwd99:uid99:gid99:infos99:dir99:shell99

النتائج:

[login10,uid10:gid10:infos10:dir10:shell10]
la clé [X] n'existe pas

تعليقات

  • السطر 11: fopen(nom_fichier,"w") يفتح الملف nom_fichier في وضع الكتابة (w=write). إذا لم يكن الملف موجودًا، يتم إنشاؤه. وإذا كان موجودًا، يتم مسحه. وإذا فشل الإنشاء، فإن fopen تُرجع القيمة false. في العبارة if (!$fic = fopen($INFOS, "w")) {…}، توجد عمليتان متتاليتان: 1) $fic=fopen(..) 2) if( ! $fic) {...}
  • السطر 18: fputs($fic,$chaîne) يكتب chaîne في الملف $fic.
  • السطر 20: fclose($fic) يغلق الملف $fic.
  • السطر 25: fopen(nom_fichier,"r") يفتح الملف nom_fichier للقراءة (r=read). إذا فشل فتح الملف (الملف غير موجود)، فإن fopen تُرجع القيمة false.
  • السطر 29: fgets($fic,1000) يقرأ السطر التالي من الملف بحد أقصى 1000 حرف. في العملية while ($ligne = fgets($fic, 1000)) {…}، هناك عمليتان متتاليتان 1) $ligne=fgets(...) 2) while ( ! $ligne). بعد قراءة الحرف الأخير من الملف، تُفرغ الدالة fgets السلسلة وتتوقف الحلقة while.
  • السطر 31: تقرأ الدالة fgets سطرًا من النص، بما في ذلك حرف نهاية السطر. تقوم الدالة cutNewLineChar في الأسطر 70-79 بإزالة حرف نهاية السطر إن وجد.
  • السطر 72: تعرض الدالة strlen($chaîne) عدد أحرف $chaîne.
  • السطر 73: الدالة substr($ligne, $position, $taille) تُرجع $taille حرفًا من $ligne، بدءًا من الحرف رقم $position، حيث يُعتبر الحرف الأول هو رقم 0. على أجهزة ويندوز، علامة نهاية السطر هي "\r\n". على أجهزة يونكس، هي السلسلة "\n".
  • السطر 35: الدالة array_shift($tableau) تحذف العنصر الأول من $tableau وتعيّنه كنتيجة.
  • السطر 37: يتم استخدام الدالة array_shift($tableau) ولكن يتم تجاهل نتيجتها
  • السطر 57: تُرجع الدالة is_array($variable) القيمة true إذا كانت $variable مصفوفة، وإلا تُرجع false.
  • السطر 58: الدالة join تقوم بنفس الشيء الذي تقوم به الدالة implode التي سبق أن تناولناها