تالار گفتمان nCIS.ir

نسخه‌ی کامل: آموزش مرحله به مرحله PHP - جلسه دوم
شما در حال مشاهده نسخه آرشیو هستید. برای مشاهده نسخه کامل کلیک کنید.
اولین قانون در PHP
اولین و در عین حال ساده ترین قانون PHP که مهمترین قانون نیز میباشد، آن است که هر دستور، باید با سمی کالِن ; خاتمه یابد. برای مثال، دستور زیر موجب بروز خطا خواهد شد:
echo "Hello"


برای اصلاح آن، باید اینگونه بنویسید:
echo "Hello";

نکته: آخرین دستور موجود در بلاک PHP نیاز به سمی کالن ندارد اما بهتر است برای رعایت استاندارد و جلوگیری از بروز مشکلات درصورت اضافه شدن دستورات در آینده، در پایان تمام دستورات، سمی کالن را قرار دهید.

توضیحات در PHP
همان طور که احتمالاً میدانید، PHP یک زبان برنامه نویسی است. ساختار این زبان بسیار شبیه زبان ++C/C میباشد. یکی از امکانات بسیار سودمند در زبانهای برنامه نویسی، توضیحات هستند که برای کسی که بعداً قصد مطالعه کد را دارد، منبع مفیدی محسوب میشوند. در PHP برای درج توضیحات تک سطری در برنامه میتوان از علامتهای # و // استفاده نمود. برای مثال، عبارات زیر، هر دو توضیح هستند و پردازش نمیشوند:
#This is a comment
//This is also a comment

PHP هرگاه با یکی از علامتهای # یا // مواجه شود، از آنجا تا انتهای همان سطر را نادیده گرفته و پردازش نمیکند. برای توضیحات چند سطری یا تبدیل قسمتی از یک سطر نیز میتوانید با */ شروع توضیحات و با /* پایان آنرا مشخص کنید:
/*This is
a multiline
comment*/

متغیرها
هر زمان صحبت از زبانهای برنامه نویسی به میان آید، بدون شک اولین مفهومی که مطرح میشود، متغیر است. متغیر به مکانی از حافظه میگویند که دارای نام است. توسط نام متغیر میتوان آنرا مورد دستیابی قرار داد و درصورت لزوم، آنرا تغییر داد. در PHP متغیرها با استفاده از علامت دلار $ تعریف میشوند. مثلاً $myVariable یک متغیر به نام myVariable است. نام متغیرها در PHP نسبت به بزرگی و کوچکی حروف حساس است. برای مثال، دو متغیر $var و $VAR در PHP با هم متفاوت هستند. برای نامگذاری متغیرها در PHP باید از قوانین زیر پیروی کنید:
  • نام متغیر فقط میتواند شامل اعداد، حروف کوچک و بزرگ الفبای انگلیسی و کارکتر Underscore _ باشد.
  • نام متغیر نمیتواند با عدد شروع شود.
بنابراین از بین اسامی زیر، فقط سه مورد اول صحیح است:
$name        //ok
$_Name20     //ok
$my_1st_Name //ok
$2_name      //error

در PHP نوع متغیر تعیین نمیشود. در عوض یک متغیر میتواند هر نوع مقدار را بپذیرد و نوع آن بطور خودکار بر اساس محتوای جدیدی که در آن ذخیره میشود، تغییر خواهد کرد:
$var = 5;
$var = 'PHP';
$var = 3.14;
$var = true;

تمام دستورات فوق صحیح هستند.

استفاده از متغیرها به دو روش مقداری و ارجاعی
به دستورات زیر دقت کنید:
$x = 5;
$y = $x;
$x = 6;

بعد از اجرای دستورات فوق، مقدار متغیر y$ همچنان برابر با 5 خواهد بود زیرا در زمان مقداردهی، یک کپی از مقدار x$ درون متغیر y$ قرار گرفته است و درصورت تغییر مقدار x$ مقدار y$ بدون تغییر خواهد ماند. حال به دستورات زیر توجه کنید:
$x = 5;
$y = &$x;
$x = 6;

در این مثال بدلیل استفاده از کارکتر & قبل از متغیر x$، بجای قراردادن یک کپی از مقدار آن درون متغیر y$، یک ارجاع به x$ در متغیر y$ ذخیره خواهد شد و درنتیجه، هر دو متغیر x$ و y$ به یک محل از حافظه اشاره میکنند و درواقع y$ یک اسم مستعار برای x$ خواهد بود. به چنین شرایطی، استفاده از متغیر به روش ارجاعی یا بطور خلاصه، مقداردهی ارجاعی میگویند. بنابراین، بعد از اجرای دستورات فوق، متغیر y$ نیز مقدار 6 را در خود خواهد داشت.

انواع مقادیر در PHP
بطور کلی هر متغیر در PHP میتواند یکی از انواع مقادیر زیر را بپذیرد:
Integer
Floating-Point
String
Object
Array

که به ترتیب برای نگهداری اعداد صحیح، اعداد اعشاری، رشته ها، اشیاء و آرایه ها بکار میروند.

آشنایی با دستور echo
دستور echo، هرچه که بعنوان پارامتر دریافت کند را در محل قرارگرفتن مکان نما در فایل HTML خروجی (که تحویل مرورگر کاربر داده خواهد شد)، مینویسد. برای مثال، دستورات زیر را درنظر بگیرید:
<!doctype html>
<html>
<head>
<title>echo DEMO</title>
<meta charset="utf-8" />
</head>
<body>
<?php
   $x = 5;
   $y = 6;
   $z = $x + $y;
   echo $z . '<br />' . PHP_EOL;
?>
</body>
</html>

کد فوق را با نام 2.php در مسیر ریشه سرویس دهنده وب خود ذخیره کنید و با واردکردن نشانی localhost/2.php در مرورگر، آنرا اجرا کنید. با مشاهده کد منبع صفحه، خواهید دید که این کد به مرورگر تحویل داده شده است:
<!doctype html>
<html>
<head>
<title>echo DEMO</title>
<meta charset="utf-8" />
</head>
<body>
11<br />
</body>
</html>

حال اجازه دهید بررسی کنیم که دقیقاً چه اتفاقی رخ داده است که این خروجی برای مرورگر ارسال میشود؟
  1. کاربر در مرورگر نشانی localhost/2.php را وارد میکند.
  2. درخواست به سرویس دهنده وب نصب شده روی Server میرسد (در اینجا، Server و Client هر دو، کامپیوتر شما است).
  3. سرویس دهنده وب با بررسی آدرس متوجه میشود که فایل درخواستی از نوع php. است و درنتیجه مفسر PHP را فراخوانی کرده و فایل را برای تفسیر، تحویل آن میدهد.
  4. مفسر PHP در حافظه محلی را برای نگه داشتن محتوایی که باید برای درخواست کننده، ارسال شود، ایجاد میکند و شروع به تفسیر فایل بصورت خط به خط مینماید.
  5. هر بخش از فایل که خارج از تگهای PHP قرار دارد (محتوای HTML که در اینجا، از ابتدای فایل تا پایان خط 7 است) عیناً در حافظه در محلی که در مرحله قبل ایجاد شده و به آن بافر (Buffer) میگوییم، نوشته میشود.
  6. با رسیدن به تگ شروع PHP مفسر وارد فاز عملیاتی میشود و شروع به پردازش دستورات PHP میکند. در فاز عملیاتی، هیچ چیزی در بافر نوشته نمیشود، مگر آنکه صراحتاً توسط دستور echo از مفسر بخواهیم.
  7. ابتدا یک متغیر به نام x$ تعریف شده و مقدار 5 در آن قرار میگیرد.
  8. سپس یک متغیر دیگر به نام y$ تعریف شده و مقدار 6 در آن قرار میگیرد.
  9. در ادامه یک متغیر دیگر به نام z$ تعریف شده و حاصل جمع مقدار متغیرهای x$ و y$ یعنی 11 در آن قرار میگیرد.
  10. توسط دستور echo مقدار متغیر z$ و سپس تگ </ br> و سپس یک ثابت خاص در PHP بنام PHP_EOL که معادل کارکتر رفتن به سطر بعد است، در ادامه محتوای بافر (بعد از <body>) درج میشود.
  11. با رسیدن به علامت بستن تگ PHP، مفسر از فاز عملیاتی خارج و مجدداً وارد فاز نوشتن میشود و بقیه محتوای فایل در انتهای بافر خروجی درج شده و کار پردازش فایل تمام میشود.
  12. با پایان یافتن پردازش فایل، مفسر محتوای بافر خروجی را برای سرویس دهنده وب ارسال میکند تا بعنوان نتیجه پردازش، تحویل مرورگر کاربر دهد.
  13. سرویس دهنده وب نتیجه دریافت شده از مفسر را برای مرورگر کاربر ارسال میکند و مرورگر آنرا نمایش میدهد.
کار با رشته ها
رشته ها در PHP مجموعه ای از کارکترهای متوالی هستند که بین دو گیومه (کوتِیشِن) تک ' ' یا جفت " " قرار میگیرند. مثال:
$a = 'This is a text.';
$b = "This is also a text.";

درصورتی که بخواهید از خود کارکتر گیومه (تک یا جفت) در وسط رشته ای که ابتدا و انتهای آن توسط همان نوع گیومه مشخص شده است، استفاده کنید، باید قبل از گیومه میان رشته، کارکتر استفاده کنید.
echo 'It's mine. My name is "Mohammad"';
echo "My friend's name is "Ali".";

به کارکتر اصطلاحاً Escape (فرار) میگویند؛ زیرا برای فرار از معنای اصلی کارکترهای بعد از آن و ایجاد معنای دیگری برای آنها بکار میرود. بدیهی است که کارکتر گیومه تک در داخل رشته محصور به گیومه جفت و همچنین کارکتر گیومه جفت در داخل رشته محصور به گیومه تک نیاز به Escape ندارد. در جدول زیر، تعدادی از کدهای Escape متداول را در PHP مشاهده میکنید:
n\ حرکت به سطر بعد
r\ حرکت به ابتدای سطر جاری
t\ کارکتر Tab (معادل 8 کارکتر Space)
\\ کارکتر \
'\ کارکتر ' (در رشته های محصور به گیومه تک)
"\ کارکتر " (در رشته های محصور به گیومه جفت)
$\ کارکتر $
[0-7]\ کارکتری که کد ASCII آن در مبنای 8 در جلوی \ نوشته شده است
[x[0-F\ کارکتری که کد ASCII آن در مبنای 16 در جلوی x\ نوشته شده است

اگر بخاطر داشته باشید، در برخی از کدها از یک ثابت خاص به نام PHP_EOL استفاده شده بود. این ثابت، بطور خودکار تبدیل به کارکتر رفتن به سطر جدید میشود. در سیستم عامل ویندوز، برای رفتن به سطر بعد، باید از ترکیب دو کارکتر rn استفاده نمود، درحالی که در سایر سیستمهای عامل، کارکتر n به تنهایی این وظیفه را انجام میدهد و استفاده از ترکیب دو کارکتری فوق، موجب رفتن به دو سطر بعد خواهد شد که ظاهر نازیبایی به کدها خواهد داد. برای جلوگیری از این مشکل، ثابت PHP_EOL در PHP درنظر گرفته شده است که بطور خودکار برحسب نوع سیستم عامل Server، ترکیب مناسب را برای کارکتر رفتن به ابتدای سطر جدید انتخاب میکند. الته باید به این نکته نیز دقت کنید که این علائم فقط در کد منبع درج میشوند و نحوه تفسیر آنها بستگی به محل قرارگیری آنها در داخل کد منبع دارد. برای مثال، درج کارکتر رفتن به ابتدای سطر جدید، در HTML موجب رفتن به سطر جدید نمیشود و برای اینکه در خروجی، به سطر جدید برویم، باید تگ </ br> را بکار ببریم. البته همین کارکتر (رفتن به ابتدای سطر جدید) اگر درون تگهای خاصی مثل pre و xmp و... مورد استفاده قرار گیرد، در خروجی نیز موجب رفتن به سطر جدید خواهد شد. برای درک بهتر، مطالعه مقاله «آموزش طراحی صفحات وب با HTML» را توصیه میکنیم.

ادغام رشته ها
برای ادغام رشته ها در PHP از کارکتر نقطه . استفاده میشود:
$a = 'PHP';
$b = 'Programming';
echo $a . ' ' . $b . ' is full of enjoy.<br />' . PHP_EOL;

خروجی کد فوق بصورت زیر خواهد بود:
PHP Programming is full of enjoy.<br />

در PHP میتوانید رشته ها را با اعداد نیز ترکیب کنید:
$num = 5;
echo 'Test' . $num; //output: Test5

تفاوت رشته های محصور در گیومه جفت و تک
دستورات زیر را درنظر بگیرید:
$x = 5;
$text1 = "X is $x";
$text2 = 'X is $x';

با اجرای دستورات فوق، عبارت X is 5 در متغیر $text1 و عبارت X is $x در متغیر $text2 ذخیره خواهد شد. علت این تفاوت در عملکرد، آن است که اسامی متغیرها در رشته هایی که بین دو گیومه جفت قرار دارند، پردازش شده و بجای نام آنها، مقدارشان در عبارت مورد استفاده قرار میگیرد. درمقابل رشته های محصور به گیومه تک، مورد هیچ پردازشی قرار نمیگیرند و به همان شکل که نوشته میشوند، مورد استفاده قرار خواهند گرفت. بنابراین اگر در رشته موردنظرتان، متغیری وجود ندارد، بهتر است آنرا در گیومه تک بگذارید تا سرعت پردازش کد شما افزایش یابد. همچنین باید دقت کنید که پردازش رشته های محصور در گیومه جفت نیز تنها محدود به اسامی متغیرهاست و هیچگونه فراخوانی توابع یا عمل محاسباتی ریاضی و... مورد پردازش قرار نخواهد گرفت. برای مثال، حاصل دستورات زیر:
$x = 5;
$text = "X = ($x + 5)";

ذخیره شدن عبارت (X = (5 + 5 در متغیر text$ است. درواقع برای محاسبه صحیح مجموع و درج آن در رشته، باید بصورت زیر عمل کنید:
$x = 5;
$text = 'X = ' . ($x + 5);

که به موجب آن، ابتدا نتیجه محاسبه ($x + 5) با حاصل 10 و سپس استفاده از نتیجه این محاسبه در عبارت و ادغام با رشته ' = X' و درنتیجه ذخیره عبارت نهایی X = 10 در متغیر text$ است.

استفاده از رشته بعنوان عدد
همانطور که در مثال قبل ملاحظه کردید، تبدیل عدد به رشته در زمان نیاز بطور خودکار انجام میشود. عکس این موضوع نیز صحیح است و رشته ها درصورت استفاده در عبارات محاسباتی، بطور خودکار به عدد تبدیل خواهند شد؛ بدین ترتیب که از ابتدای رشته، تا زمان رسیدن به اولین کارکتر غیر عددی، جدا شده و بصورت عدد تعبیر میشود. البته اگر رشته موردنظر با عدد شروع نشده باشد، یک ثابت خاص به نام NaN (مخفف Not a Number) بازگردانده خواهد شد. مثال:
$text = '52Ali';
$sum = 7 + $text; //$sum = 59

محاسبه طول رشته
توسط دستور strlen میتوان طول یک رشته را محاسبه کرد:
$text = 'Alireza';
echo strlen($text); //output: 7

البته اگر رشته ما فارسی باشد، از آنجا که حروف فارسی طبق استاندارد کدگذاری Unicode ذخیره میشوند، هر حرف معادل 2 بایت در حافظه فضا اشغال میکند و درنتیجه تابع strlen نتیجه صحیح تولید نخواهد کرد:
$text = 'علیرضا';
echo strlen($text); //output: 12

برای حل این مشکل، باید از تابع mb_strlen استفاده کنید. این تابع یک پارامتر دیگر نیز دریافت میکند که نوع کدگذاری رشته موردنظر را تعیین خواهد کرد که درمورد حروف فارسی، باید از utf-8 استفاده کنید:
$text = 'علیرضا';
echo mb_strlen($text, 'utf-8'); //output: 6

بطور کلی، اکثر توابع کار برروی رشته ها در PHP یک نسخه مخصوص کار با رشته های حاوی کارکترهای چندبایتی (MultiByte) نیز دارند که نیاز به تعریف یک پارامتر اضافه جهت مشخص کردن نوع کدگذاری دارد و در زمان توضیح توابع، به نسخه چندبایتی آن که با پیشوند _mb شروع میشود، اشاره خواهیم کرد.

عملگرها در PHP
تا اینجا روش تعریف و مقداردهی متغیرها را یاد گرفتید. حال قصد داریم روش تغییر و دستکاری آنها را بیان کنیم. برای این کار از عملگرها استفاده میشود. ساده ترین عملگر در PHP عملگر انتساب است که قبلاً با آن آشنا شده اید و با نماد = مشخص میشود:
$x = 5;

دستور فوق، مقدار 5 را به متغیر x$ نسبت میدهد.

عملگرهای ریاضی
PHP از پنج نوع عملگر ریاضی پشتیبانی میکند:
+ جمع
- تفریق
* ضرب
/ تقسیم
% باقیمانده

برای مثال، اگر بخواهید حاصل ضرب متغیرهای x$ و y$ را در متغیر z$ ذخیره کنید، باید اینگونه بنویسید:
$z = $x * $y;

همچنین اگر بخواهید به مقدار قبلی متغیر a$ مقدار 5 واحد اضافه کنید، باید از این دستور استفاده کنید:
$a = $a + 5;

البته در چنین حالتهایی که متغیر سمت چپ تساوی، بلافاصله بعد از عملگر انتساب ظاهر میشود، ساختار بهینه تری نیز وجود دارد:
$a += 5;

دقت کنید که اگر بلافاصله بعد از عملگر انتساب، متغیر سمت چپ تساوی وجود نداشته باشد، نمیتوان از این ساختار خلاصه شده استفاده کرد و نتیجه آن در عملگرهایی مثل تفریق و تقسیم و باقیمانده و... که خاصیت جابجایی ندارند، اشتباه خواهد بود:
$b = 5 - $b;
$b -= 5; //wrong, means $b = $b - 5, not $b = 5 - $b

بعلاوه، برای افزایش و کاهش به میزان 1 واحد، باز هم ساختار خلاصه تری وجود دارد:
$a = $a + 1;   $a += 1;   $a++;   ++$a;

$b = $b - 1;   $b -= 1;   $b--;   --$b;

نتیجه اجرای تمامی دستورات هر کدام از سطرهای فوق، با بقیه دستورات همان سطر یکسان است (تمام دستورات سطر اول، مقدار متغیر a$ را یک واحد افزایش میدهند و تمام دستورات سطر دوم، از مقدار متغیر b$ یک واحد کم میکنند). به دو دستور انتهای هر سطر دقت کنید. بسیار شبیه هم بنظر میرسند. درحقیقت تنها تفاوت آنها در زمان افزایش یا کاهش است. برای درک بهتر، به مثال زیر دقت کنید:
$a = $5;
$x = 'A=' . $a++;

در این دستور، چون ابتدا a$ ذکر شده و سپس عملگر افزایش یک واحدی مورد استفاده قرار گرفته است، درنتیجه ابتدا مقدار فعلی متغیر یعنی 5 در عبارت مورد استفاده قرار گرفته و متغیر x$ حاوی مقدار A=5 خواهد شد و سپس، مقدار متغیر a$ یک واحد افزایش یافته و برابر با 6 میشود. حال اگر دستور فوق را بصورت$x = 'A=' . ++$a; بنویسیم، ابتدا به متغیر a$ یک واحد افزوده شده و مقدار آن برابر با 6 خواهد شد و سپس، مقدار جدید آن در عبارت، مورد استفاده قرار میگیرد و درنتیجه مقدار متغیر x$ برابر با A=6 خواهد شد.

عملگرهای مقایسه ای
از این عملگرها برای مقایسه دو عبارت بصورت ریاضی استفاده میشود:

== بررسی تساوی مقدار (5 و 5 و 5.0 و '5' با هم برابرند)
=== بررسی تساوی مقدار و نوع (5 و 5 با هم برابر ولی با 5.0 و '5' متفاوتند)
=! بررسی عدم تساوی مقدار (5 و 6 با هم متفاوتند ولی 5 و 5.0 و '5' با هم برابرند)
==! بررسی عدم تساوی مقدار و نوع (5 و 6 و 5.0 و '5' با هم متفاوتند)
< بررسی کوچکتر بودن
=< بررسی کوچکتر یا مساوی بودن
> بررسی بزرگتر بودن
=> بررسی بزرگتر یا مساوی بودن
<> بررسی نامساوی بودن

عملگرهای منطقی
این عملگرها برای ترکیب شرطهای مختلف و تولید شرطهای ترکیبی بکار میروند:

and هر دو شرط باید برقرار باشند
&& هر دو شرط باید برقرار باشند
or کافی است یکی از دو شرط برقرار باشد
|| کافی است یکی از دو شرط برقرار باشد
xor فقط باید یکی از دو شرط برقرار باشد
^ فقط باید یکی از دو شرط برقرار باشد
! شرط نباید برقرار باشد

عملگرهای بیتی
این عملگرها برروی بیتهای اعداد عمل میکنند؛ بدین ترتیب که عددهای موردنظر را به مبنای دو برده و عملیات مربوط به عملگر را برروی تک تک بیتهای اعداد، اجرا میکنند:

& به ازای هر بیت که در هر دو عدد 1 باشد، در نتیجه 1 نوشته شده و بقیه بیتها صفر خواهد شد
| به ازای هر بیت که حداقل در یکی از دو عدد 1 باشد، در نتیجه 1 نوشته شده و بقیه بیتها صفر خواهد شد
^ به ازای هر بیت که فقط در یکی از دو عدد 1 باشد، در نتیجه 1 نوشته شده و بقیه بیتها صفر خواهد شد
~ بیتهای عدد را معکوس میکند و 0 را به 1 و 1 را به 0 تبدیل مینماید
>> بیتهای عدد اول را به تعداد عدد دوم به چپ منتقل میکند و از سمت راست، صفر وارد میکند (عدد تقسیم بر 2 میشود)
<< بیتهای عدد اول را به تعداد عدد دوم به راست منتقل میکند و از سمت چپ، صفر وارد میکند (عدد ضرب در 2 میشود)

یک نکته که باید درمورد عملگرهای بیتی به آن دقت زیادی داشته باشید، آن است که بدلیل نوع خروجی عملگرهای شرطی (true یا false که درواقع یک بیت با مقدار 1 یا 0 است)، میتوانید از عملگرهای بیتی برروی نتیجه شرطها نیز استفاد کنید. برای مثال، دستورات $a < 5 & $b > 2 و $a < 5 | $b > 2 کاملاً صحیح هستند، اما توصیه میکنیم از عملگرهای مخصوص شرطها (عملگرهای منطقی) برای ترکیب شرطها استفاده کنید؛ زیرا برای این منظور، بهینه تر کار میکنند. برای مثال، عملگر && یا and هرگاه شرط اول نتیجه false تولید کند، دیگر شرط دوم را بررسی نمیکند چون نتیجه کلی درهرحال false خواهد بود و بررسی شرط دوم، نتیجه شرط کلی را تغییر نخواهد داد. همچنین عملگر || یا or نیز درصورت true بودن نتیجه شرط اول، دیگر شرط دوم را مورد بررسی قرار نمیدهد چون بهرحال، بدون اهمیت دادن به نتیجه شرط دوم، نتیجه شرط کلی، true خواهد بود.

اولویت عملگرها
درصورتی که در یک عبارت از چند عملگر استفاده کنید، نتیجه عبارت با توجه به اینکه کدام عملگر ابتدا ارزیابی شود، متفاوت خواهد بود. برای مثال در عبارت 5 + 4 * 2 اگر ابتدا عملگر جمع عمل کند، نتیجه 18 و درصورتی که ابتدا عملگر * عمل نماید، نتیجه 13 خواهد بود. در چنین شرایطی، همانطور که مشاهده میکنید، اولویت (تقدم) عملگرها نقش تعیین کننده و اساسی در نتیجه محاسبات دارد. بطور کلی اولویت عملگرها در PHP مطابق فهرست زیر است (عملگرهای سطرهای بالاتر اولویت بیشتر دارند و اولویت عملگرهای یک سطر یکسان است و درصورتی که با هم بکار روند، به ترتیبی که در پرانتز در ابتدای آن سطر نوشته شده است، ارزیابی خواهند شد) :
(none)  clone new
(left)  [ (
(right) ++ -- ~ (int) (float) (string) (array) (object) (bool) @
(none)  instanceof
(right) !
(left)  * / %
(left)  + - .
(left)  << >>
(none)  < <= > >=
(none)  == != === !== <>
(left)  &
(left)  ^
(left)  |
(left)  &&
(left)  ||
(left)  ? :
(right) = += -= *= /= .= %= &= |= ^= <<= >>= =>
(left)  and
(left)  xor
(left)  or
(left)  ,

با توجه به توضیحات فوق، اکنون متوجه میشوید که نتیجه عبارت فوق، 13 است. البته هر زمان که بخواهید، میتوانید با کمک پرانتزها اولویت عملگرها را تغییر دهید. برای مثال، نتیجه عبارت (5 + 4) * 2 برابر با 18 خواهد بود. اگر چند پرانتز تودرتو داشته باشید، به ترتیب از داخلی ترین پرانتز به سمت بیرون محاسبه خواهند شد. ضمناً نگران عملگرهایی که در فهرست فوق میبینید و هنوز با آنها آشنا نشده اید نیز نباشید. به مرور همه آنها را توضیح خواهیم داد.

کنترل روند اجرای برنامه
تمامی کدهایی که تاکنون بررسی کردیم، در یک ویژگی مشترک بودند و آن، اجرای خطی آنها بود؛ بدین معنا که برنامه ها از ابتدا تا انتها بصورت خط به خط و به ترتیب اجرا میشدند. گاهی اوقات نیازمند تغییر این روش هستیم. مثلاً بخشی از کد فقط در زمانهای مشخصی اجرا شود یا بخشهایی از کد چند بار تکرار شوند. PHP چنین قابلیتهایی را با استفاده از ساختارهای کنترلی قدرتمند خود، در اختیار شما قرار میدهد.

ساختار if
ساختار if برای کنترل یک یا چند شرط و اجرای یک یا چند دستور برحسب برقراری یا عدم برقراری آن شرایط بکار میرود. ساختار کلی این دستور بصورت زیر است:
if (CONDITIONS 1) {
   //true #1 block
}
elseif (CONDITIONS 2) {
   //true #2 block
}
.
.
.
elseif (CONDITIONS n) {
   //true #n block
}
else {
   //false block
}

توضیح: درصورتی که شرط یا شرایط 1 برقرار باشند، بلاک true #1 اجرا میشود. درغیر اینصورت شرط یا شرایط 2 بررسی میشوند و درصورت برقرار بودن آنها، بلاک true #2 اجرا میگردد. درصورت عدم برقراری این شرط یا شروط نیز شرط یا شرایط بعدی تا n (هر اندازه که باشند) مورد بررسی قرار میگیرند و درصورت برقراری هرکدام از شروط، بلاک مربوط به همان شرط اجرا میشود و درصورت عدم برقراری،‌شرط بعدی بررسی میشود. درنهایت اگر هیچکدام از شرایط برقرار نباشند، بلاک false (کد مربوط به else) اجرا میشود. در ساختار فوق، تمامی بخشهای elseif و else اختیاری هستند (ممکن است یک شرط قسمت elseif یا else نداشته باشد) ولی اگر این بخشها وجود داشته باشند، ترتیب آنها به همان شکلی است که در ساختار فوق مشاهده میکنید، یعنی if اولین بخش، elseif قسمت میانی و else قسمت پایانی است و برای مثال، نمیتوان else را قبل از elseif نوشت. همچنین قسمت if اجباری است و نمیتوان قسمت else را بدون قسمت if قبل از آن، در کد مورد استفاده قرار داد. برای درک بهتر، به مثال زیر دقت کنید:
if ($day == 0) {
   echo 'Saturday';
}
elseif ($day == 1) {
   echo 'Sunday';
}
elseif ($day == 2) {
   echo 'Monday';
}
elseif ($day == 3) {
   echo 'Tuesday';
}
elseif ($day == 4) {
   echo 'Wednesday';
}
elseif ($day == 5) {
   echo 'Thursday';
}
elseif ($day == 6) {
   echo 'Friday';
}
else {
   echo 'ERROR';
}

در مثال فوق، مقدار متغیر day$ به ترتیب با مقادیر 0 تا 6 مقایسه میشود و درصورت برابر بودن با هرکدام از آنها، نام روز مربوطه در خروجی نوشته خواهد شد. درصورتی که مقدار متغیر فوق با هیچکدام از مقادیر مجاز برابر نباشد، عبارت ERROR در خروجی درج خواهد شد.

ساختار switch
اگر به خوبی به ساختار if مثال قبل دقت کنید، خواهید دید که در آن، مقدار متغیر day$ با مقادیر مختلف مقایسه شده و درصورت برابر بودن با هرکدام از مقادیر، یک بلاک کد اجرا میشود. در چنین مواردی (ارزیابی یک متغیر و انجام کارهای مختلف برحسب مقادیر متفاوت آن)، ساختار بهینه تری به نام switch وجود دارد:
switch (VARIABLE) {
case VALUE 1:
   //true #1 block
   break;
case VALUE 2:
   //true #2 block
   break;
.
.
.
case VALUE n:
   //true #n block
   break;
default:
   //false block
   break;
}

در این ساختار، مقدار VARIABLE بصورت بسیار سریع با تمامی case ها مقایسه میشود و درصورت تساوی با هرکدام از مقادیر، بلاک مربوط به همان بخش اجرا خواهد شد و درصورتی که مقدار آن با هیچکدام از case ها برابر نباشد، بلاک کد مربوط به قسمت default اجرا خواهد شد. برای درک بهتر، مثال قبل را با این ساختار بازنویسی میکنیم:
switch ($day) {
case 0:
   echo 'Saturday';
   break;
case 1:
   echo 'Sunday';
   break;
case 2:
   echo 'Monday';
   break;
case 3:
   echo 'Tuesday';
   break;
case 4:
   echo 'Wednesday';
   break;
case 5:
   echo 'Thursday';
   break;
case 6:
   echo 'Friday';
   break;
default:
   echo 'Invalid day';
   break;
}

البته در این ساختار، وجود بخش default اختیاری است (مشابه قسمت else در دستور if). همچنین باید دقت کنید که استفاده از این ساختار بعنوان جایگزین if، همیشه ممکن نیست. درحقیقت برای استفاده از این ساختار، باید شرایط زیر فراهم باشد:
  • اجرای بلاکهای مختلف کد بستگی به مقادیر مختلف یک متغیر داشته باشد (اگر بخواهیم چند شرط ترکیبی یا چند متغیر را مورد بررسی قرار دهیم، باید از if استفاده کنیم)
  • مقادیر باید کاملاً مشخص و متمایز باشند (برای مثال اگر بخواهیم درصورت بزرگتر بودن متغیر از یک مقدار کارهایی انجام شود، باید از if استفاده کنیم)
ضمناً در پایان هر case باید از دستور ;break استفاده شود؛ درغیر اینصورت، دستورات case مربوطه، تا زمان رسیدن به اولین ;break یا تا زمان رسیدن به پایان ساختار switch اجرا خواهند شد. البته این مسئله در برخی موارد سودمند است. برای مثال:
switch ($operator) {
case '+':
   $result = $x + $y;
   break;
case '-':
   $result = $x - $y;
   break;
case '/':
   if ($y != 0) {
       $result = $x / $y;
   }
   else {
       $result = 'DIVISION BY ZERO';
   }
   break;
case '*':
case 'x':
case 'X':
   $result = $x * $y;
   break;
default:
   $result = 'INVALID OPERATOR';
   break;
}

در مثال فوق، درصورتی که operator$ برابر با هرکدام از مقادیر * یا x یا X باشد، حاصل ضرب x$ و y$ در متغیر result$ قرار خواهد گرفت.

ساختار شرطی سه گانه : ?
معمولاً بسیاری از دستورات if با ساختاری مشابه مثالهای زیر مورد استفاده قرار میگیرند:
//1st example
if ($y != 0) {
   $result = $x / $y;
}
else {
$result = 'DIVISION BY ZERO';
}
//2nd example
if ($x % 2 == 0) {
   echo 'X is even.<br />' . PHP_EOL;
}
else {
   echo 'X is odd.<br />' . PHP_EOL;
}

اگر دقت کنید، خواهید دید که بخش عمده بلاکهای true و false مشابه است. در چنین حالتهایی که فقط یک مقدار در دو بلاک true و false متفاوت است و این تفاوت هم دقیقاً بستگی به درستی یا نادرستی یک شرط دارد (و بعبارت دیگر در دستور if قسمت elseif نداریم و فقط قسمت else وجود دارد)، میتوان از ساختار خلاصه شده ای به نام Ternary Operator بصورت زیر استفاده کرد:
CONDITIONS ? TRUE BLOCK : FALSE BLOCK

برای درک بهتر، مثالهای قبلی را با این ساختار، بازنویسی میکنیم:
//1st example
$result = ($y != 0 ? $x / $y : 'DIVISION BY ZERO');
//2nd example
echo 'X is ' . ($x % 2 == 0 ? 'even' : 'odd') . '.<br />' . PHP_EOL;

همانطور که مشاهده میکنید، قسمتهای تکراری در مثالهای فوق، از این ساختار خارج شده است و فقط قسمتی که تفاوت میکند، درون این ساختار قرار میگیرد. همچنین از پرانتزها برای مشخص کردن محدوده اعتبار این ساختار استفاده شده است. دقت کنید که وجود پرانتز در این ساختار الزامی نیست؛ اما بهتر است به استفاده از آن عادت کنید زیر به خوبی محدوده ساختار را مشخص میکنند. مثلاً در دستور دوم، اگر از پرانتزها استفاده نکنیم، قسمت . '.<br />' . PHP_EOL نیز جزو بلاک false قرار میگرفت و موجب میشد که خروجی موردنظر ما به شکل صحیح تولید نشود.

ساختار while
از ساختار while برای تکرار بخشی از دستورات تا زمانی که یک شرط برقرار است، استفاده میشود و ساختار آن بصورت زیر است:
while (CONDITIONS) {
   //code block
}

در این ساختار، بلاک کد تا زمانی که شرط یا شرایط مشخص شده در دستور while برقرار باشند، تکرار خواهد شد. بنابراین باید در بدنه بلاک، شرایطی درنظر گرفته شود که بالأخره در مرحله ای، شرط یا شرایط while نقض شود تا برنامه بتواند از حلقه تکرار بیرون آید؛ درغیر اینصورت برنامه در یک حلقه بینهایت گرفتار خواهد شد و نمیتواند کار خود را به درستی انجام دهد. به مثال زیر دقت کنید:
<!doctype html>
<html>
<head>
<title>while DEMO</title>
<meta charset="utf-8" />
</head>
<body>
<?php
$i = 1;
while ($i <= 100) {
   echo 'Hello ' . $i . '<br />' . PHP_EOL;
   $i++;
}
?>
</body>
</html>

کد فوق را با نام 3.php در مسیر ریشه سرویس دهنده وب خود ذخیره کنید و در مرورگر با واردکردن نشانی localhost/3.php آنرا اجرا کنید. همانطور که ملاحظه میکنید، 100 بار عبارت Hello همراه با عدد موجود در متغیر $i در خروجی نوشته شده است. حال اگر در مثال فوق، دستور $i++; را ننویسیم، برنامه در حلقه بینهایت گرفتار خواهد شد؛ زیرا همیشه i$ برابر با 1 خواهد بود و شرط 100 => 1 همیشه برقرار است.

ساختار do...while
ساختار while شرط خود را در ابتدا بررسی میکند. درنتیجه اگر در زمان ورود به حلقه، شرط حلقه برقرار نباشد، برنامه حتی یک بار هم وارد حلقه نخواهد شد. اما در برخی مواقع لازم است که حلقه حداقل یکبار اجرا شود و سپس، شرط یا شرایطی را بررسی کنیم و درصورت برقرار بودن آن شروط، حلقه مجدداً تکرار شود. در چنین حالتی، حلقه do...while کاربرد دارد:
do {
   //code block
} while (CONDITIONS);

این ساختار، شروط خود را در پایان کار، بررسی میکند و درصورتی که شرط یا شرایط همچنان برقرار باشند، یکبار دیگر بلاک کد تکرار خواهد شد.

ساختار for
دستور for کاملترین و در عین حال پیچیده ترین ساختار تکرار در PHP و بطور کلی در تمام زبانهای خانواده ++C/C محسوب میشود. در این ساختار، سه بخش در بدنه حلقه درنظر گرفته شده است: آماده سازی حلقه (Initialization)، شرط یا شرایط تکرار حلقه (Conditions) و بخش گام حلقه (Iteration). این سه بخش توسط سمی کالِن از هم جدا میشوند. ساختار کلی این دستور بصورت زیر است:
for ( INITIALIZATION ; CONDITIONS ; ITERATION ) {
    //code block
}

روش کار این ساختار بدین ترتیب است که ابتدا بخش Initialization اجرا میشود. سپس شرط یا شرایط موجود در قسمت Conditions مورد بررسی قرار میگیرد و درصورت برقراری شروط، برنامه وارد حلقه شده و دستورات موجود در بلاک کد آنرا اجرا میکند. در پایان هربار اجرای بلاک کد، بخش Iteration اجرا میشود و مجدداً شروط حلقه بررسی میشوند و اگر همچنان این شروط برقرار بود، مجدداً حلقه تکرار میگردد و این روند تا زمانی که بالأخره شروط حلقه نقض شوند، ادامه خواهد یافت. برای درک بهتر، اجازه دهید همان مثال while که صدبار پیغام Hello را همراه با مقدار متغیر حلقه، در خروجی درج میکرد، با این ساختار بازنویسی کنیم:
for ($i = 1; $i <= 100; $i++) {
   echo "Hello {$i}<br />" . PHP_EOL;
}

اگر دقت کنید، در اطراف متغیر i$ از یک جفت آکولاد باز و بسته استفاده شده است. بهتر است شما نیز عادت کنید در زمان استفاده از متغیرها در رشته های محصور بین گیومه جفت، این کار را انجام دهید. بدین ترتیب، هم خوانایی برنامه شما بیشتر خواهد شد و هم مشکلی در چسبیدن حروف الفبا به اسامی متغیرها ایجاد نمیشود. برای مثال، دستورات زیر را درنظر بگیرید:
$name = 'ali';
echo "$namereza<br />" . PHP_EOL;   //error: Undefined variable $namereza
echo "{$name}reza<br />" . PHP_EOL; //ok, output: alireza

میتوانید هرکدام از قسمتهای فوق را نادیده بگیرید، البته مشروط بر آنکه سمی کالِن آنرا حذف نکنید و همچنین در اجرای حلقه، مشکلی ایجاد نشود:
$i = 1;
for(; $i <= 100;) {
   echo "Hello {$i}<br />" . PHP_EOL;
   $i++;
}

البته استفاده از ساختار for بدین شکل مرسوم نیست. نکته دیگر که باید مدنظر داشته باشید آن است که در هرکدام از بخشهای Initialization و Conditions و Iteration میتوان بیش از یک دستور قرار داد. برای مثال، کد زیر را با نام 4.php در پوشه ریشه سرویس دهنده وب خود ذخیره کنید و با وارد کردن نشانی localhost/4.php اجرا نمایید:
<!doctype html>
<html>
<head>
<title>for DEMO</title>
<meta charset="utf-8" />
</head>
<body>
<?php
for ($i = 1, $j = 10; $i <= 10, $j >= 1; $i++, $j--) {
   echo "I={$i},J={$j}<br />" . PHP_EOL;
}
?>
</body>
</html>

همچنین میتوان حلقه ها را بصورت تودرتو نیز ایجاد نمود. برای مثال، کد زیر را با نام 5.php ذخیره کرده و ازطریق نشانی localhost/5.php اجرا کنید و نتیجه آنرا مشاهده نمایید:
<!doctype html>
<html>
<head>
<title>Some fun with PHP loops</title>
<meta charset="utf-8" />
</head>
<body>
<table border="1px" cellpadding="5px" cellspacing="0">
<?php
for ($i = 1; $i <= 10; $i++) {
   echo '<tr align="center">';
   for ($j = 1; $j <= 10; $j++) {
       echo ($i == 1 || $j == 1 ? '<th' : '<td') . ' width="10%">' . ($i * $j) . ($i == 1 || $j == 1 ? '</th>' : '</td>');
   }
   echo '</tr>' . PHP_EOL;
}
?>
</table>
</body>
</html>

خروج از حلقه و رد کردن دورهای حلقه در مواقع نیاز
قبلاً در ساختار switch با دستور ;break آشنا شدید. این دستور در حلقه های تکرار نیز کاربرد دارد و برنامه هر زمان که به این دستور برسد، بدون صبر کردن برای اتمام قانونی حلقه (با نقض شدن شرط حلقه) از آن خارج میشود و برنامه را از اولین دستور بعد از حلقه، ادامه میدهد. در PHP دستور دیگری نیز به نام ;continue وجود دارد که درصورت استفاده در داخل حلقه، برنامه با رسیدن به آن، تا انتهای بلاک کد حلقه را نادیده گرفته و به سراغ دور بعدی تکرار حلقه میرود. مثالی از کاربرد دستور ;break را مشاهده کنید:
$i = 1;
while (true) {
   echo $i++ . '<br />' . PHP_EOL;
   if ($i > 100) {
       break;
}
}

این حلقه که کمی هم عجیب بنظر میرسد، اعداد 1 تا 100 را در خروجی مینویسد. مثالی از کاربرد دستور ;continue را نیز مشاهده کنید:
for ($i = 1; $i <= 100; $i++) {
   if ($i % 3 == 0) {
       continue;
}
   echo $i . '<br />' . PHP_EOL;
}

این حلقه نیز تمام اعداد از 1 تا 100، بجز مضارب 3 را مینویسد. دقت کنید که چگونه مضارب 3 توسط دستور ;continue نادیده گرفته شده اند و حلقه به سراغ تکرارهای بعدی خود میرود.
عملگرهای بیتی کجا استفاده میشن
من تاالا هیچ جایی ندیدم از اینا استفاده بشه
هرکدوم در مکانهای مناسب و بسته به نیازتون قابل استفاده هستن. تا حالا چنین کدهایی ندیدین؟
error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING & ~E_DEPRECATED);
$user->setPermissions(ADMIN | MODERATOR);
توجه نکرده بودم درست میگین