اذهب إلى المحتوى

بنى التحكم والحلقات التكرارية في PHP


سارة محمد2

التعليمات الشرطية

if else

تسمح لنا تعليمة if بتنفيذ شيفرة معينة إذا تحقق شرط معين، ونستخدم else لتنفيذ شيفرة ما عندما لا يتحقق هذا الشرط.

if ($a > $b) {
    echo "a is greater than b";
} else {
    echo "a is NOT greater than b";
}

العامل الثلاثي كصياغة مختصرة لعبارة if-else

يقيّم العامل الثلاثي تعبيرًا بالاعتماد على شرط قد تكون نتيجته true أو false، وهو عامل موازنة يُستخدم ليعبّر عن شرط if-else بصيغة مختصرة فهو يسمح باختبار سريع للشرط ويختزل تعليمة if المكونة من عدّة أسطر إلى سطر واحد، سنعيد كتابة الشيفرة السابقة باستخدام العامل الثلاثي وبفرض ‎$a=1‎، ‏‎$b=2:

echo ($a > $b) ? "a is greater than b" : "a is NOT greater than b";

/*
a is NOT greater than b.
*/

صياغة بديلة لبنى التحكم

توفر PHP صياغة بديلة لبعض بنى التحكم: if، ‏while، ‏for، ‏foreach و‏switch.

بالموازنة مع الصياغة العادية، الفرق هو أنّ القوس المفتوح يُستبدل بنقطتين : والقوس المفتوح يُستبدل ب endif;‎، ‏endwhile;‎، ‏endfor;‎، ‏endforeach;‎ أو endswitch;‎ على الترتيب، مثال:

if ($a == 42):
    echo "The answer to life, the universe and everything is 42.";
endif;

تعليمات elseif باستخدام الصياغة المختصرة:

if ($a == 5):
    echo "a equals 5";
elseif ($a == 6):
    echo "a equals 6";
else:
    echo "a is neither 5 nor 6";
endif;

if elseif else

elseif

تجمع elseif بين if وelse، وسِّعت تعليمة if لتنفيذ تعليمة مختلفة في حال كانت نتيجة تعبير if الأساسي هي FALSE، وينفَّذ التعبير البديل فقط في حال كانت نتيجة تعبير elseif الأساسي هي TRUE.

تعرض الشيفرة التالية إحدى العبارات "a is bigger than b" أو "a is equal to b" أو "a is smaller than b":

if ($a > $b) {
    echo "a is bigger than b";
} elseif ($a == $b) {
    echo "a is equal to b";
} else {
    echo "a is smaller than b";
}

تعليمات elseif متعددة

يمكن استخدام تعليمات elseif متعددة ضمن تعليمة if نفسها:

if ($a == 1) {
    echo "a is One";
} elseif ($a == 2) {
    echo "a is Two";
} elseif ($a == 3) {
    echo "a is Three";
} else {
    echo "a is not One, not Two nor Three";
}

if

تسمح لك بنية if بتنفيذ أجزاء من الشيفرة اعتمادًا على شروط معينة.

if ($a > $b) {
    echo "a is bigger than b";
}

switch

تؤدي بنية switch نفس وظيفة سلسلة من تعليمات if لكن بعدد أسطر شيفرة أقل. تُقارَن القيمة التي نريد اختبارها والمعرَّفة في تعليمة switch مع كل القيم الموجودة في عبارات case وعند المساواة ستنُنفَّذ الشيفرة الخاصة بتلك العبارة وإذا لم تتساوى مع أي قيمة تُنفّّذ كتلة default إن وجدت.

كل كتلة شيفرة في تعليمة case أو default يجب أن تنتهي بتعليمة break، توقف هذه التعليمة تنفيذ بنية switch ويتابع تنفيذ الشيفرة مباشرةً بعد ذلك، إذا تجاهلت تعليمة break ستُنفَّذ تعليمة case التالية حتى لو لم تحدث مساواة، ويمكن أن يسبب لك هذا تنفيذ غير متوقع للشيفرة لكن أيضًا قد يكون مفيدًا عند الحاجة إلى مشاركة عدة تعليمات case لنفس الشيفرة.

switch ($colour) {
case "red":
    echo "the colour is red";
    break;

case "green":

case "blue":
    echo "the colour is green or blue";
    break;

case "yellow":
    echo "the colour is yellow";
    // لذا ستُنفَّذ كتلة الشيفرة التالية break لاحظ عدم وجود

case "black":
    echo "the colour is black";
    break;

default:
    echo "the colour is something else";
    break;
}

بالإضافة لاختبار القيم الثابتة يمكن للبنية اختبار التعليمات الديناميكية بإعطاء تعليمة switch قيمة منطقية وإعطاء تعليمة case أي تعبير، مثال:

$i = 1048;
switch (true) {
case ($i > 0):
    echo "more than 0";
    break;

case ($i > 100):
    echo "more than 100";
    break;

case ($i > 1000):
    echo "more than 1000";
    break;
}

// more than 100

الحلقات

تعدّ الحلقات جانبًا أساسيًا من البرمجة فهي تسمح للمبرمجين بإنشاء شيفرة تُكرَّر لعدد من المرات أو التكرارات، قد يكون عدد التكرارات محددًا بشكلٍ صريح (6 تكرارات مثلًا) أو يستمر حتى حدوث شرط ما نحدده.

for

تُستخدم حلقات for عندما يكون لديك كتلة شيفرة تريد تكرارها عددًا محددًا من المرات.?

for ($i = 1; $i < 10; $i++) {
    echo $i;
}

// 123456789

نستخدم المُهيئ لضبط القيمة الابتدائية لعداد تكرارات الحلقة، قد يُصرَّح عنه هنا لهذا الغرض واسمه التقليدي ‎$i.

يُكرر المثال التالي 10 مرات ويعرض الأعداد من 0 إلى 9:

for ($i = 0; $i <= 9; $i++) {
    echo $i, ',';
}

# مثال 2
for ($i = 0; ; $i++) {
    if ($i > 9) {
        break;
    }
    echo $i, ',';
}

# مثال 3
$i = 0;
for (; ; ) {
    if ($i > 9) {
        break;
    }
    echo $i, ',';
    $i++;
}

# مثال 4
for ($i = 0, $j = 0; $i <= 9; $j += $i, print $i. ',', $i++);

/*
خرج كل مثال من الأمثلة السابقة
0,1,2,3,4,5,6,7,8,9,
*/

foreach

تسمح لنا بنية foreach باستخدام التكرار على المصفوفات والكائنات بسهولة.

$array = [1, 2, 3];
    foreach ($array as $value) {
echo $value;
}

// 123

ولاستخدامها مع الكائنات نحتاج إلى تنفيذ الواجهة Iterator.

لاستخدام التعليمة foreach للتنقل بين عناصر المصفوفات، تُسند قيمة عنصر المصفوفة الحالي في كل تكرار إلى متغير ‎$value‎ ويتحرك مؤشر المصفوفة خطوة واحدة وفي التكرار التالي سيُعالج العنصر التالي، إليك مثال يعرض عناصر المصفوفة:

$list = ['apple', 'banana', 'cherry'];
foreach ($list as $value) {
    echo "I love to eat {$value}. ";
}
/*
I love to eat apple. I love to eat banana. I love to eat cherry.
*/

يمكنك أيضًا أن تحصل على مفتاح/فهرس القيمة باستخدام foreach:

foreach ($list as $key => $value) {
    echo $key . ":" . $value . " ";
}

// 0:apple 1:banana 2:cherry

إنّ ‎$value بشكلٍ افتراضي هي نسخة من القيمة في ‎$list لذا فإنّ التغييرات التي تحدث داخل الحلقة لن تؤثر على ‎$list بعد ذلك:

foreach ($list as $value) {
    $value = $value . " pie";
}

echo $list[0]; 
// "apple"

نستخدم العامل & لتعديل قيم المصفوفة داخل حلقة foreach إذ تُسند القيمة ‎$value بالمرجع، ويجب بعد ذلك استخدام unset للمتغير حتى لا تسبب إعادة استخدام ‎$value في مكانٍ آخر الكتابة فوق المصفوفة.

foreach ($list as &$value) { // foreach ($list as $key => &$value) { أو
    $value = $value . " pie";
}
unset($value);

echo $list[0]; 
// "apple pie"

يمكنك أيضًا تعديل عناصر المصفوفة داخل حلقة foreach بمرجعية مفتاح المصفوفة للعنصر الحالي.

foreach ($list as $key => $value) {
    $list[$key] = $value . " pie";
}

echo $list[0]; 
// "apple pie"

ونستطيع استخدامها لتكرار مصفوفة ترابطية كما في الشيفرة التالية:

$array = ['color'=>'red'];
foreach($array as $key => $value){
    echo $key . ': ' . $value;
}

// color: red

while

تكرّر حلقة while كتلة شيفرة طالما أنّ الشرط محقق.

$i = 1;
while ($i < 10) {
    echo $i;
    $i++;
}

/*
123456789
*/

يُكرَّر المثال التالي حتى تصبح قيمة المجموع 100:

$i = true;
$sum = 0;
while ($i) {
    if ($sum === 100) {
        $i = false;
    } else {
        $sum += 10;
    }
}

echo 'The sum is: ', $sum;

/*
The sum is: 100
*/

do-while

تنفّذ حلقة do-while كتلة الشيفرة لمرة واحدة بدايةً ثمّ تكرر كتلة الشيفرة طالما أنّ الشرط محقق.

$i = 0;
do {
    $i++;
    echo $i;
} while ($i < 10);

/*
`12345678910`
*/

سيزيد المثال التالي قيمة المتغير ‎$i مرة واحدة على الأقل ويستمر بزيادة قيمته ما دامت أصغر من 25.

$i = 0;
do {
    $i++;
} while($i < 25);

echo 'The final value of i is: ', $i;
// The final value of i is: 25

تعليمات التحكم

goto

يسمح لنا العامل goto بالانتقال إلى جزء آخر من البرنامج ومتوفر منذ الإصدار PHP 5.3، ويتبعه اسم لافتة (label) الهدف المطلوب: goto MyLabel;‎.

يوصف الهدف المطلوب الانتقال إليه باسم اللافتة يتبعه نقطتين مثل: MyLabel:‎.

<?php
goto MyLabel;
echo 'This text will be skipped, because of the jump.';

MyLabel:
echo 'Hello World!';
?>

/*
Hello World!
*/

return

تُرجع تعليمة return تحكم البرنامج إلى الوحدة التي قامت بالاستدعاء، وسيستمر التنفيذ إلى التعبير الذي يلي تعبير الاستدعاء.

عندما تُستدعى return من ضمن دالة فإنّ تنفيذها سينتهي.

function returnEndsFunctions()
{
    echo 'This is executed';
    return;
    echo 'This is not executed.';
}

// This is executed

إذا استدعيت return داخل دالة لها وسيط فإنّها ستنهي تنفيذها على الفور وتعيد الوسيط كقيمة لاستدعاء الدالة.

continue

توقف الكلمة المفتاحية continue التكرار الحالي للحلقة وينتقل إلى التكرار التالي لها، وتوضع مثل تعليمة break داخل جسم الحلقة.

تطبع الحلقة في المثال التالي رسالة بالاعتماد على القيم في مصفوفة لكنها تتجاوز قيمة معينة:

$list = ['apple', 'banana', 'cherry'];

foreach ($list as $value) {
    if ($value == 'banana') {
        continue;
    }
    echo "I love to eat {$value} pie.".PHP_EOL;
}

/*
I love to eat apple pie.
I love to eat cherry pie.
*/

قد تُستخدم تعليمة continue لينتقل التنفيذ بشكلٍ مباشر إلى مستوى خارجي من الحلقة بوصف عدد مستويات الحلقة التي نريد تجاوزها. بفرض لدينا المعلومات التالية:

Fruit Color Cost
Apple Red 1
Banana Yellow 7
Cherry Red 2
Grape Green 4

نريد تنفيذ شيفرة معينة عند الفاكهة التي تكلف أقل من 5:

$data = [
    [ "Fruit" => "Apple", "Color" => "Red", "Cost" => 1 ],
    [ "Fruit" => "Banana", "Color" => "Yellow", "Cost" => 7 ],
    [ "Fruit" => "Cherry", "Color" => "Red", "Cost" => 2 ],
    [ "Fruit" => "Grape", "Color" => "Green", "Cost" => 4 ]
];

foreach($data as $fruit) {
    foreach($fruit as $key => $value) {
        if ($key == "Cost" && $value >= 5) {
            continue 2;
        }
        /* الشيفرة التي نريد تنفيذها */
    }
}

عندما تُنفَّذ التعليمة continue 2 سينتقل التنفيذ مباشرةً إلى ‎$‎data as $fruit‎ لتستمر الحلقة الخارجية (وستتجاهل باقي الشيفرة بما في ذلك الشرط في الحلقة الداخلية).

break

تُنهي الكلمة المفتاحية break تنفيذ الحلقة الحالية مباشرةً، بشكلٍ مشابه للتعليمة continue لكن الفرق هو أنّ break توقف الحلقة ولا تنفذ التعليمة الشرطية بعد ذلك.

$i = 5;
while(true) {
    echo 120/$i.PHP_EOL;
    $i -= 1;
    if ($i == 0) {
        break;
    }
}

/*
24
30
40
60
120
*/

لن تُنفَّذ الحلقة عندما يكون ‎$i == 0 إذ أنّ تنفيذها سيرمي خطأً فادحًا بسبب القسمة على 0.

قد تُستخدم تعليمة break للخروج عدة مستويات من الحلقة ويعدّ هذا مفيدًا عند تنفيذ الحلقات المتداخلة، فمثلًا لنسخ مصفوفة سلاسل نصية إلى السلسلة النصية الخرج، بعد حذف رموز # ?حتى تصبح السلسلة النصية في الخرج 160 محرفًا تمامًا.

$output = "";
$inputs = array(
    "#soblessed #throwbackthursday",
    "happy tuesday",
    "#nofilter",
    /* المزيد من الدخل */
);

foreach($inputs as $input) {
    for($i = 0; $i < strlen($input); $i += 1) {
        if ($input[$i] == '#') continue;
        $output .= $input[$i];
        if (strlen($output) == 160) break 2;
    }
$output .= ' ';
}

توقف التعليمة break 2 تنفيذ الحلقتين الداخلية والخارجية مباشرةً.

بنى تحكم أخرى

declare

تُستخدم بنية declare لتعيين موجّه التنفيذ (execution directive) لكتلة شيفرة.

التوجيهات المعرَّفة:

بفرض أننا نريد تعيين قيمة ticks هي 1:

declare(ticks=1);

لتمكين نمط الكتابة الصارم نستخدم تعليمة declare التالية:

declare(strict_types=1);

include وrequire

require

العبارة require مطابقة للعبارة include باستثناء أنّها تطلق خطأ من نوع E_COMPLE_ERROR في حالة الفشل أي أنّها توقف عمل الشيفرة تمامًا أما include تطلق تحذيرًا E_WARNING والذي لا يؤدي إلى إيقاف الشيفرة عن العمل.

require 'file.php';

include

تعمل تعليمة include على تضمين ومعالجة الملف المحدّد.

بفرض لدينا الملفين variables.php وmain.php في نفس المجلد، محتوى الملف variables.php:

$a = 'Hello World!';

ومحتوى الملف main.php:

include 'variables.php';
echo $a;

// `Hello World!`

يجب أن تكون حذرًا عند اتّباع هذه الطريقة فهي يمكن أن تؤدي إلى مشاكل في الشيفرة عند تضمين ملف قد يغيّر في كمية ومحتوى المتغيّرات المعرّفة ضمن النطاق المُعطى.

يمكنك أن تضمّن ملفًا يُرجع قيمة وهذا مفيد بشكلٍ خاص في معالجة مصفوفات الإعدادات، مثال لملف configuration.php:

<?php
return [
    'dbname' => 'my db',
    'user' => 'admin',
    'pass' => 'password',
];

نضمّنه ضمن ملف آخر بنفس المجلد الموجود فيه:

<?php
$config = include 'configuration.php';

ستمنع هذه الطريقة الملف المضمَّن من إفساد نطاقك الحالي بالمتغيرات المتغيرة أو المُضافة.

يمكن أن نستخدم include وrequire لإسناد قيم إلى متغير عند إرجاع قيمة ما من ملف. مثال: بفرض لدينا الملف include1.php فيه الشيفرة التالية:

<?php
    $a = "This is to be returned";
    return $a;
?>

والملف index.php:

$value = include 'include1.php';

// $value = "This is to be returned"

الصياغة البديلة لبنى التحكم

تعليمة if/else بديلة

<?php
if ($condition):
    do_something();
elseif ($another_condition):
    do_something_else();
else:
    do_something_different();
endif;
?>

الشيفرة السابقة مكافئة لما يلي:

<?php if ($condition): ?>
    <p>Do something in HTML</p>
<?php elseif ($another_condition): ?>
    <p>Do something else in HTML</p>
<?php else: ?>
    <p>Do something different in HTML</p>
<?php endif; ?>

تعليمة for بديلة

<?php
for ($i = 0; $i < 10; $i++):
    do_something($i);
endfor;
?>

الشيفرة السابقة مكافئة لما يلي:

<?php for ($i = 0; $i < 10; $i++): ?>
    <p>Do something in HTML with <?php echo $i; ?></p>
<?php endfor; ?>

تعليمة while بديلة

<?php
while ($condition):
    do_something();
endwhile;
?>

الشيفرة السابقة مكافئة لما يلي:

<?php while ($condition): ?>
    <p>Do something in HTML</p>
<?php endwhile; ?>

تعليمة foreach بديلة

<?php
foreach ($collection as $item):
    do_something($item);
endforeach;
?>

الشيفرة السابقة مكافئة لما يلي:

<?php foreach ($collection as $item): ?>
    <p>Do something in HTML with <?php echo $item; ?></p>
<?php endforeach; ?>

شيفرة switch بديلة

<?php
switch ($condition):
    case $value:
        do_something();
        break;

    default:
        do_something_else();
        break;
endswitch;
?>

الشيفرة السابقة مكافئة لما يلي:

<?php switch ($condition): ?>
<?php case $value: ?>
    <p>Do something in HTML</p>
    <?php break; ?>
<?php default: ?>
    <p>Do something else in HTML</p>
    <?php break; ?>
<?php endswitch; ?>

ترجمة -وبتصرف- للفصول [Control Structures - Loops - Alternative Syntax for Control Structures] من كتاب PHP Notes for Professionals book

اقرأ أيضًا

 


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...