درآمدی بر اپراتورها در زبان PHP


پیش از این با مفهوم Data Type (دیتاتایپ یا نوع داده) آشنا شدیم. در اکثر زبان‌های برنامه‌نویسی من‌جمله PHP ما این امکان را داریم تا روی دیتاتایپ‌های مختلف یکسری عملیات خاص انجام دهیم که بسیاری از آنها به صورت Built-in (از پیش تعریف شده) در تمامی زبان‌های برنامه‌نویسی تعبیه شده‌اند. حال برای آنکه بتوانیم دست به انجام این عملیات بزنیم، نیاز داریم تا با مفهوم Operator (اپراتور یا عَملگر) آشنا شویم.

در واقع، اپراتورها یکسری دستورات در زبان‌های برنامه‌نویسی هستند که این امکان را در اختیار دولوپر قرار می‌دهند تا به سادگی بتوانند یکسری عملیات رایج -همچون ضرب، تقسیم، جمع، تفریق و غیره- را روی داده‌های مختلف پیاده کنند.

آشنایی با مفهوم Assignment Operator در زبان PHP
پیش از این به کرات از این Assignment Operator (عملگر انتصاب) در حین کار با متغیرها استفاده کرده‌ایم. به عنوان مثال داریم:

<?php
$carName = 'Lexus';

عملگر انتصاب یا همان علامت = مقداری را به یک متغیر اختصاص می‌دهد به طوری که از این پس هر کجا که از متغیر carName$ استفاده کنیم، مقدار استرینگ Lexux را در اختیار خواهیم داشت.

هشدار
همواره به خاطر داشته باشید که برخلاف ریاضیات که علامت = نشانگر تساوی دو چیز است، در کدنویسی این علامت صرفاً برای اختصاص دادن Value (مقدار) مورد استفاده قرار می‌گیرد و چنانچه بخواهیم تساوی را نشان دهیم، می‌بایست از علائم == و === استفاده کنیم که در آینده بیشتر در این باره بحث خواهیم کرد.

آشنایی با مفهوم اپراتورهای به اصطلاح Arithmetic در زبان PHP
امروزه در بسیاری از وب اپلیکیشن‌ها همچون فروشگاه‌های آنلاین، سی‌آر‌ام و غیره نیاز است تا یکسری محاسبات -از محاسبات ابتدایی تا محاسبات پیچیده- را در اختیار کاربران قرار داد و اینجا است که بایستی با اپراتورهای اصطلاحاً Arithmetic (محاسباتی یا ریاضیاتی) آشنا شویم. این اپراتورها عبارتند از:

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

Operant (عملوند) به هر چیزی که در قسمت راست/چپ یک اپراتور قرار گیرد گفته می‌شود. حال به منظور درک بهتر اپراتورهای محاسباتی فوق، مثال‌های زیر را مد نظر قرار دهید:

<?php
$variableOne = 10;
$variableTwo = 3;

$addition = $variableOne + $variableTwo;
$subtraction = $variableOne - $variableTwo;
$multiply = $variableOne * $variableTwo;
$division = $variableOne / $variableTwo;
$modulus = $variableOne % $variableTwo;
$power = $variableOne ** $variableTwo;

var_dump($addition, $subtraction, $multiply, $division, $modulus, $power);

به عنوان خروجی اسکریپت فوق داریم:

int(13)
int(7)
int(13)
float(3.3333333333333)
int(1)
int(1000)

در تفسیر اسکریپت فوق بایستی بگوییم که در خط پنجم با استفاده از اپراتور +  حاصل‌جمع متغیرهای variableOne$ و variableTwo$ را به دست آورد‌ه‌ایم؛ در ادامه با استفاده از اپراتور - این دو متغیر را از یکدیگر کسر کرده‌ایم؛ اپراتور * هم این وظیفه را دارا است تا حاصل‌ضرب عملوندها را به دست آورد و علامت / هم به منظور تقسیم دو عملوند بر یکدیگر استفاده می‌شود و از علامت % هم استفاده کرده تا باقیماندهٔ حاصل تقسیم دو عملوند بر یکدیگر را به دست آوریم و در نهایت هم از اپراتور ** استفاده کرده تا عملوند سمت چپ را به توان عملوند سمت راست برسانیم.

در ارتباط با عملگرهای ضرب و تقسیم حتماً بایستی این نکته را مد نظر داشت که فقط و فقط از علائم * و / به ترتیب برای به دست آوردن حاصل‌ضرب و تقسیم دو عملوند استفاده نمود. به عنوان مثال نقض این قانون داریم:

$multiply = $variableOn × $variableTwo;
$division = $variableOne ÷ $variableTwo;

همان‌طور که مشاهده می‌شود، اگر برای این نوع عملیات از علائم × و ÷ استفاده کنیم، با ارور مواجه خواهیم شد.

آشنایی با نحوهٔ ادغام اپراتور Assignment با اپراتورهای Arithmetic
پیش از این با Assignment Operator (اپراتور انتصاب) آشنا شدیم. لازم به ذکر است که به منظور خلاصه‌نویسی کد، می‌توان اپراتور انتصاب را با اپراتورهای محاسباتی ادغام نمود:

<?php
$variableOne = 10;
$variableTwo = 3;

$variableOne += $variableTwo;
echo $variableOne;

به عنوان خروجی این اسکریپت عدد ۱۳ چاپ خواهد شد. در واقع کاری که در اسکریپت فوق انجام داده‌ایم این است که پس از نام متغیر variableOne$ علائم =+ را پشت سر هم نوشته سپس نام عملوند بعدی (variableTwo$) را نوشته‌ایم. به عبارت دیگر، به مفسر PHP دستور داده‌ایم که مقدار متغیر variableOne$ را در نظر گرفته‌ سپس مقدار متغیر variableTwo$ را با آن جمع کند و حاصل‌جمع را مجدد در متغیر variableOne$ ذخیره سازد. به همین منوال، برای عمل کسر داریم:

<?php
$variableOne = 10;
$variableTwo = 3;

$variableOne -= $variableTwo;
echo $variableOne;

 برای به دست آوردن حاصل‌ضرب داریم:

<?php
$variableOne = 10;
$variableTwo = 3;

$variableOne *= $variableTwo;
echo $variableOne;

برای به دست آوردن حاصل تقسیم داریم:

<?php
$variableOne = 10;
$variableTwo = 3;

$variableOne /= $variableTwo;
echo $variableOne;

برای به دست آوردن باقیمانده داریم:

<?php
$variableOne = 10;
$variableTwo = 3;

$variableOne ٪= $variableTwo; // We have an error here
echo $variableOne;

به عنوان خروجی اسکریپت فوق داریم:

Parse error: syntax error, unexpected '٪' (T_STRING) in /var/www/sokanacademy-php-course/index.php on line 5

مشکلی که در این اسکریپت وجود دارد این است که ما به اشتباه به جای علامت % از علامت ٪ استفاده کرده‌ایم که با کیبورد فارسی تایپ شده است! اکنون اسکریپت فوق را به صورت زیر تصحیح می‌کنیم:

<?php
$variableOne = 10;
$variableTwo = 3;

$variableOne %= $variableTwo;
echo $variableOne;

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

<?php
$variableOne = 2;
$variableTwo = 3;
echo $variableOne ** $variableTwo;

به عنوان خروجی اسکریپت فوق با عدد ۸ مواجه خواهیم شد چرا که در آن عدد ۲ را به توان ۳ رسانده‌ایم؛ به عبارت دیگر، عدد ۲ را ۳ بار در خودش ضرب کرده‌ایم (۲×۲×۲).

آشنایی با Concatenation Operator در زبان PHP
پیش از این دیدیم که با استفاده از علامت . به چه شکل می‌توان استرینگ‌ها را به یکدیگر چسباند؛ به عنوان مثال داریم:

<?php
$variableOne = 'First String ';
$variableTwo = 'Second String';
$total = $variableOne . $variableTwo;
echo $total;

به عنوان خروجی اسکریپت فوق داریم:

First String Second String

حال می‌توان اسکریپت فوق را به صورت خلاصه بدین شکل نوشت:

<?php
$variableOne = 'First String ';
$variableTwo = 'Second String';
$variableOne .= $variableTwo;
echo $variableOne;

همان‌طور که پیش از این دیدیم، با قرار دادن علامت . قبل از علامت = این دستور را به مفسر PHP داده‌ایم تا مقدار متغیر variableOne$ را در نظر گرفته سپس مقدار متغیر variableTwo$ را به آن اصطلاحاً Concat کند یا بچسباند و در نهایت مقدار اولیهٔ متغیر variableOne$ را آپدیت کرده و مقدار متغیرهای variableOne$ و variableTwo$ را در آن ذخیره سازد.

آشنایی با اپراتورهای Increment و Decrement در زبان PHP
گاهی‌اوقات ما نیاز داریم تا به متغیری یک واحد اضافه کرده و یا یک واحد از آن کسر کنیم که در چنین مواردی به سادگی می‌توان از اپراتورهای به اصطلاح Increment و Decrement استفاده کرد که به ترتیب به معنی «افزایش» و «کاهش» هستند:

<?php
$variableOne = 100;

echo $variableOne;
echo "<br>";

$variableOne++;
echo $variableOne;
echo "<br>";

$variableOne--;
echo $variableOne;

به عنوان خروجی اسکریپت فوق داریم:

100
101
100

در تفسر اسکریپت فوق بایستی بگوییم که متغیری ایجاد کرده‌ایم تحت عنوان variableOne$ با مقدار اولیهٔ ۱۰۰. با قرار دادن علائم ++ پس از نام این متغیر و چاپ کردن خروجی، می‌بینیم که مقدار اولیهٔ ۱۰۰ یک واحد افزایش یافته و به عدد ۱۰۱ تبدیل شده است؛ به همین منوال،‌ در آخر هم علائم -- را پس از نام متغیر قرار داده و می‌بینیم که پس از یک واحد کم شدن از مقدار ۱۰۱، مجدد مقدار متغیر به عدد ۱۰۰ آپدیت می‌شود.

اهمیت محل قرارگیری اپراتورهای ++ و -- در کنار متغیرها
اینکه اپراتورهای ++ و -- قبل یا بعد از یک متغیر قرار گیرند از اهمیت بسزایی برخوردار است. برای روشن‌تر شدن این مسئله، مثال زیر را در نظر می‌گیریم:

<?php
$variable = 100;
echo $variable++ + 10;
echo "<br>";
echo $variable;

به عنوان خروجی اسکریپت فوق داریم:

110
101

در تفسیر رفتار فوق از مفسر PHP بایستی بگوییم که در خط سوم مفسر PHP ابتدا متغیر variable$ را با عدد ۱۰ جمع کرده سپس به دلیل قرار گرفتن علائم ++، یک واحد به آن اضافه می‌کند و به همین دلیل در دستور echo آخر می‌بینیم که مقدار پیش‌فرض این متغیر که ۱۰۰ بود، یک واحد افزایش یافته و به ۱۰۱ مبدل شده‌ است. حال شرایط زیر را در نظر می‌گیریم:

<?php
$variable = 100;
echo ++$variable + 10;
echo "<br>";
echo $variable;

به عنوان خروجی داریم:

111
101

در حقیقت، این بار مفسر PHP به دلیل اینکه علائم ++ قبل از متغیر آمده‌اند، ابتدا یک واحد به مقدار پیش‌فرض متغیر variable$ اضافه کرده که می‌شود ۱۰۱ سپس آن را با عدد ۱۰ جمع کرده است. این قانون در مورد علائم -- هم صادق است:

<?php
$variable = 100;
echo $variable-- + 10; // Or --$variable
echo "<br>";
echo $variable;

به عنوان خروجی داریم:

110
99

می‌بینیم که در اسکریپت فوق ابتدا متغیر variable$ را با عدد ۱۰ جمع کرده سپس یک واحد از آن کم کرده‌ایم.

نکته
در نظر داشته باشیم که علائم ++ و یا -- را هم‌ می‌توان بلافاصله پس از متغیر نوشت و هم با قرار دادن یک فاصله نوشت چرا که زبان PHP به فاصله حساس نیست. به طور مثال، هر دو حالت ++variable$ و ++ variable$ عملکرد یکسانی دارند.

آشنایی با اپراتورهای Comparison در زبان PHP
نتیجهٔ اپراتورهای Comparison (مقایسه) همواره یا true است یا false و به طور کلی به منظور مقایسهٔ دو مقدار مورد استفاده قرار می‌گیرند که این اپراتورها عبارتند از:

اپراتور توضیحات
== برابری را نشان می‌دهد.
=== برابری و دیتاتایپ یکسان را نشان می‌دهد.
=! یا <> نابرابری را نشان می‌دهد.
==! نابرابری و عدم برخورداری از دیتاتایپ یکسان را نشان می‌دهد.
< بزرگ‌تر بودن را نشان می‌دهد.
> کوچک‌تر بودن را نشان می‌دهد.
=< بزرگ‌تر یا مساوی را نشان می‌دهد.
=> کوچک‌تر یا مساوی را نشان می‌دهد.
<=> این اپراتور که تحت عنوان Combined Comparison یا Spaceship (سفینه) شناخته می‌شود، یک اپراتور مقایسه‌ای سه‌حالتی است. به عبارت دیگر، حالات «بزرگ‌تر از»، «کوچک‌تر از» و «مساوی با» را مابین عملوندها چک می‌کند. 

از این اپراتورها به کرات در دستورات شرطی (If/Else) استفاده می‌شود که در فصول آتی به تفصیل در مورد آنها بحث خواهیم کرد اما برای آنکه عملکرد آنها را متوجه شوید، در ادامه چند مثال از کاربرد آنها خواهیم زد:

<?php
$variableOne = 2;
$variableTwo = 3;
$variableThree = '3';
var_dump($variableOne == $variableTwo);

خروجی اسکریپت فوق (bool(false است زیرا مقادیر این دو متغیر اصلاً با یکدیگر برابر نیستند اما در ادامه قصد داریم ببینیم که اگر مقادیر متغیرهای variableTwo$ با variableThree$ را با یکدیگر مقایسه کنیم چه اتفاقی خواهد افتاد:

<?php
$variableOne = 2;
$variableTwo = 3;
$variableThree = '3';
var_dump($variableTwo == $variableThree);

می‌بینیم که مقدار (bool(true بازگردانده می‌شود. گرچه مقدار متغیر variableTwo$ یک عدد صحیح است (۳) و مقدار متغیر variableThree$ یک استرینگ یا رشته به صورت '۳' است، اما مفسر PHP هر دو را یکسان تلقی می‌کند فلذا وقتی که با استفاده از اپراتور تساوی == آنها را می‌سنجیم، مقدار true بازگردانده می‌شود. حال اگر بخواهیم دیتاتایپ (نوع داده) را هم در این فرایند مد نظر قرار دهیم،‌ می‌توانیم از اپراتور === استفاده کنیم و اینجا است که تفاوت اپراتورهای == و === به خوبی مشخص خواهد شد:

<?php
$variableOne = 2;
$variableTwo = 3;
$variableThree = '3';
var_dump($variableTwo === $variableThree);

خروجی اسکریپت فوق (bool(false است زیرا مقادیر این دو متغیر اصلاً با یکدیگر برابر نیست؛ به عبارت دیگر، یکی از نوع عدد صحیح است و دیگری از نوع استرینگ (رشته). اکنون ببینیم که کاربرد اپراتورهای =! و ==! چگونه است:

<?php
$variableOne = 2;
$variableTwo = 3;
$variableThree = '3';
var_dump($variableOne != $variableTwo); // We can also use <> instead of !=

خروجی اسکریپت فوق (bool(true است زیرا همان‌طور که پیش از این اشاره کردیم، اپراتور =! مقادیر عملوندها را چک کرده و چنانچه آنها برابر نباشند، مقدار true را باز می‌گرداند (در این مثال هم مقادیر ۲ و ۳ با هم برابر نیستند). در ادامه قصد داریم کاربرد اپراتور ==! را مشاهده کنیم:

<?php
$variableOne = 2;
$variableTwo = 3;
$variableThree = '3';
var_dump($variableTwo !== $variableThree);

خروجی اسکریپت فوق (bool(true است زیرا اگرچه که مقادیر متغیرهای variableTwo$ و variableThree$ به نوعی یکسان است، اما گفتیم که اپراتور ==! علاوه بر چک کردن مقادیر، دیتاتایپ را هم چک می‌کند و اگر آنها باهم برابر نباشند، مقدار true را برمی‌گرداند و از آنجا که دیتاتایپ یکی عدد صحیح و دیگری استرینگ است، مقدار true بازگردانده شده است.

اپراتورهای < و > هم ماهیت‌شان کاملاً مشخص است به طوری که بزرگ‌تری/کوچکتری را چک می‌کنند. به عنوان مثال داریم:

<?php
$variableOne = 2;
$variableTwo = 3;
$variableThree = '3';
var_dump($variableTwo > $variableOne);

خروجی اسکریپت فوق (bool(true است زیرا نیاز به توضیح نیست که مقدار متغیر variableTwo$ بزرگ‌‌تر از variableOne$ است (در غیر این صورت، مقدار false بازگردانده خواهد شد). همچنین اپراتورهای =< (بزرگ‌تر یا مساوی) و => (کوچک‌تر یا مساوی) هم به صورت زیر به کار گرفته خواهند شد:

<?php
$variableOne = 2;
$variableTwo = 3;
$variableThree = '3';
var_dump($variableTwo >= $variableOne);

خروجی اسکریپت فوق (bool(true است زیرا مقدار متغیر variableTwo$ که برابر با ۳ است، بزرگ‌‌تر یا مساوی با مقدار متغیر variableOne$ است که برابر با ۲ می‌باشد. همچنین داریم:

<?php
$variableOne = 2;
$variableTwo = 3;
$variableThree = '3';
var_dump($variableTwo <= $variableThree);

مجدداً خروجی اسکریپت فوق (bool(true است زیرا مقدار متغیر variableTwo$ که برابر با ۳ است، کوچک‌تر یا مساوی با مقدار متغیر variableThree$ است که برابر با '3' می‌باشد.

در نهایت به اپراتور Spaceship یا <=> می‌رسیم که در نسخهٔ ۷ زبان برنامه‌نویسی PHP در اختیار دولوپرها قرار گرفته است. به طور کلی، این اپراتور اگر عملوند سمت چپ کوچک‌تر باشد مقدار ۱-، اگر مقادیر برابر باشند مقدار ۰ و اگر عملوند سمت چپ بزرگ‌تر باشد مقدار ۱ را باز می‌گرداند. به عنوان مثال داریم:

<?php
var_dump(1 <=> 2); 
var_dump(2 <=> 2); 
var_dump(2 <=> 1); 

به عنوان خروجی اسکریپت فوق داریم:

int(-1)
int(0)
int(1)

می‌بینیم با توجه به اینکه در اولین ()var_dump مقدار عملوند سمت چپ کوچک‌تر از مقدار عملوند سمت راست است، مقدار 1-، در دومین ()var_dump باتوجه به اینکه مقدار هر دو طرف معادله برابر است مقدار ۰ و در نهایت هم در سومین ()var_dump باتوجه به اینکه عدد ۲ (عملوند سمت چپ) از عدد ۱ (عملوند سمت راست) بزرگ‌تر است، مقدار ۱ باز گردانده شده است. در ارتباط با استرینگ‌ها نیز می‌توان از اپراتور <=> به صورت زیر استفاده نمود:

<?php
var_dump("x" <=> "x"); 
var_dump("x" <=> "y"); 
var_dump("y" <=> "x"); 

به عنوان خروجی اسکریپت فوق داریم:

int(0)
int(-1)
int(1)

در حین کار با استرینگ‌ها، عدد اختصاص یافته به کاراکترها در سیستم کدگذاری ASCII که پیش از این با آن آشنا شدید مبنا قرار داده می‌شود. در همین راستا، باتوجه به اینکه کد حرف x با کد حرف x در اولین ()var_dump یکسان است، مقدار ۰ بازگردانده شده است؛ در ()var_dump دوم باتوجه به اینکه کد حرف x که برابر با ۱۲۰ است از کد حرف y که برابر با ۱۲۱ است کوچک‌تر است، مقدار 1- بازگردانده شده و در نهایت در ()var_dump سوم باتوجه به اینکه مقدار عملوند سمت چپ (کد حرف y) از مقدار عملوند سمت راست (کد حرف x) بزرگ‌تر است، مقدار ۱ بازگردانده شده است.

آشنایی با اپراتورهای Logical در PHP
عملگرهای Logical (منطقی) به منظور ترکیب چندین Condition (شرط) در کنار یکدیگر مورد استفاده قرار می‌گیرند:

اپراتور توضیحات
and یا && این اپراتور به معنی «و» است و چنانچه دو طرف آن true باشد، مقدار true بازگردانده خواهد شد.
or یا || این اپراتور به معنی «یا» است و چنانچه یکی از عملوندهای راست یا چپ این اپراتور true باشد، مقدار true بازگردانده خواهد شد.
xor یا ^ در صورتی که یکی از عملوندها true باشد (نه هر دوی آنها)، این اپراتور مقدار true را باز خواهد گرداند.
! این اپراتور مقدار true را باز خواهد گرداند چنانچه عملوند قرار گرفته پس از آن true نباشد!

به منظور درک بهتر اپراتورهای منطقی در زبان PHP، مثال‌های زیر را در نظر می‌گیریم:

<?php
$variableOne = true;
$variableTwo = false;
var_dump($variableOne and $variableTwo); // Alternatively we can use AND, And, &&
var_dump($variableOne or $variableTwo); // Alternatively we can use OR, Or, ||
var_dump($variableOne xor $variableTwo); // Alternatively we can use XOR, Xor
var_dump(! $variableTwo); 

ابتدا به مشاهدهٔ خروجی اسکریپت فوق پرداخته، سپس به تفسیر کد می‌پردازیم:

bool(false)
bool(true)
bool(true)
bool(true)

همان‌طور که مشاهده می‌شود، مقدار اولین ()var_dump برابر با (bool(false است و دلیل این مسئله هم آن است که اپراتور منطقی and به معنی «و» چک می‌کند ببیند که آیا هر دو عملوند (متغیرهای راست و چپ) دارای مقدار true است یا خیر که اگر این‌گونه بود، مقدار true را باز می‌گرداند. در واقع، از آنجا که در این مثال مقادیر یکی true است و دیگری false، پس اپراتور and هم به درستی مقدار false را بازگردانده است.

در ()var_dump دوم از اپراتور or به معنی «یا» استفاده کرده‌ایم که این وظیفه را دارا است که اگر یکی از عملوندها مقدار true داشت، مقدار true را باز گرداند و در این مثال هم می‌بینیم که به درستی مقدار true بازگردانده شده است چرا که مقدار یکی از متغیرها true و دیگری false است.

در ()var_dump سوم هم که می‌بینیم مقدار (bool(true بازگردانده شده است زیرا اپراتور xor در صورتی که یکی از عملوندها true باشد (نه هر دوی آنها)، مقدار true را باز خواهد گرداند.

در نهایت هم کاربرد اپراتور ! که معادل انگلیسی آن می‌شود Not به معنی «نَه» را می‌بینیم. کاربرد این اپراتور بدین شکل است که این اپراتور مقدار true را باز خواهد گرداند چنانچه عملوند قرار گرفته پس از آن true نباشد. در همین راستا، باتوجه به اینکه مقدار متغیر variableTwo$ که حاوی مقدار false است را پس از علامت ! قرار داده‌ایم، می‌بینیم که مقدار (bool(true بازگردانده شده است. به عبارت دیگر، گفته‌ایم که اگر مقدار متغیر variableTwo$ برابر با true نبود (که این‌گونه هم هست)، مقدار true بازگردانده شود.

نکته
لازم به ذکر است که علامت ^ در انگلیسی Caret یا Up Arrow Head گفته می‌شود.

مسئلهٔ بسیار مهمی در ارتباط با اپراتورهای منطقی وجود دارد و آن هم تفاوت رفتار اپراتورهای and و or با معادل‌‌های سمبلیک && و || است. برای روشن‌تر شدن این مسئله، مثال زیر را در نظر بگیرید:

<?php
$thisIsTrue = true;
$thisIsFalse = false;
$result = $thisIsTrue and $thisIsFalse;
var_dump($result);

به عنوان خروجی اسکریپت فوق داریم:

bool(true)

حال کدهای فوق را به صورت زیر تغییر می‌دهیم:

<?php
$thisIsTrue = true;
$thisIsFalse = false;
$result = $thisIsTrue && $thisIsFalse;
var_dump($result);

در واقع، تنها کاری که کرده‌ایم این است که اپراتور and را با معادلش که && است جایگزین کرده‌ایم. حال مجدد اسکریپت را اجرا می‌کنیم:

bool(false)

می‌بینیم که این بار در کمال تعجب، مقدار false بازگردانده می‌شود! در تفسیر این رفتار در ظاهر عجیب و غریب مفسر PHP اما در باطن کاملاً منطقی، بایستی بگوییم که Precedence (اولویت) اپراتورهای and و && با یکدیگر کاملاً متفاوت است (برای درک بهتر این موضوع،‌ به جدولی که در ادامه آمده توجه نمایید).

در واقع، در مثال اول که از اپراتور and استفاده کردیم، از آنجا که اپراتور = اولویت بیشتری از اپراتور and دارا است، لذا ابتدا به ساکن مقدار متغیر result$ برابر با مقدار thisIsTrue$ که true است قرار داده شده و در ()var_dump هم این مقدار چاپ شده است اما در مثال دوم که از اپراتور && استفاده کرده‌ایم، اولویت این اپراتور نسبت به اپراتور = بیشتر است، لذا کد به درستی کار می‌کند. برای رفع این مشکل، یا می‌توان از اپراتور && استفاده کرد و یا کدهای فوق را به صورت زیر بازنویسی کرد:

<?php
$thisIsTrue = true;
$thisIsFalse = false;
$result = ($thisIsTrue and $thisIsFalse);
var_dump($result);

می‌بینیم که با استفاده پرانتز،‌ اولویت اپراتور and را نسبت به = که به صورت پیش‌فرض کمتر است، بیشتر نمودیم و نتیجهٔ قابل‌ انتظار مشاهده می‌شود.

به خاطر داشته باشید
باتوجه به چنین رفتاری، همواره توصیه می‌شود که از اپراتورهای && و || به ترتیب به جای and و or استفاده نمایید.

به منظور درک بهتر اپراتورهای منطقی، مثال زیر را مد نظر قرار می‌دهیم:

<?php
$sheIsBeautiful = true;
$sheIsSlim = false;
$sheIs24YearsOld = true;
$sheHasBA = true;
$sheIsRich = false;

var_dump($sheIsBeautiful && $sheIsSlim && $sheIs24YearsOld && $sheIsRich);
var_dump($sheIsBeautiful || $sheIsRich && $sheHasBA);
var_dump($sheIsBeautiful xor $sheIsSlim);

به عنوان خروجی اسکریپت فوق داریم:

bool(false)
bool(true)
bool(true)

حال شروع می‌کنیم به تفسیر اسکریپت فوق بدین صورت که ابتدا پنج متغیر تعریف کرده‌ایم که به ترتیب از بالا به پایین به معنی «او زیبا است»، «او خوش اندام است»، «او ۲۴ ساله است»، «او تحصیلات کارشناسی دارد» و «او پولدار است» و به ترتیب مقادیر درست، غلط، درست، درست و غلط را به عنوان مقدار اولیهٔ آنها در نظر گرفته‌ایم. فرض کنیم که پسرهایی داریم که خواهان ازدواج با دختر خانم فرضی سناریوی فوق هستند.

در ()var_dump اول پسری را در نظر گرفته‌ایم که برایش زیبایی، خوش ‌اندامی، سن ۲۴ سال و پولدار بودن مهم است اما این پسر نمی‌تواند با این دختر ازدواج کند زیرا وی تمامی معیارها را دارا است به جز معیار آخر (پولدار بودن) و همین می‌شود که خروجی false است.

در ()var_dump دوم پسری را در نظر گرفته‌ایم که ترجیح می‌دهد با دختری ازدواج کند که حتماً لیسانس داشته باشد و همچنین از میان معیارهای زیبایی یا ثروتمند بودن، حداقل یکی وجود داشته باشد و از آنجا که دختر لیسانس دارد و زیبا است، جواب true دریافت خواهد شد و می‌تواند با وی ازدواج کند.

در ()var_dump آخر هم پسری را مد نظر قرار داده‌ایم که دختر مد نظرش یا باید زیبا باشد یا خوش اندام و از آنجا که این دختر فرضی صرفاً زیبا است، پس مقدار true بازگردانده شده و می‌تواند با وی ازدواج کند.

اولویت اپراتورها در زبان PHP
به طور کلی، در اکثر زبان‌های برنامه‌نویسی من‌جمله PHP اپراتورها به ترتیب خاصی اعمال می‌شوند که این قوانین تحت عنوان Operator Precedence & Associativity شناخته می‌شوند اما اگر بخواهیم Order (ترتیب) از پیش تعریف شده این زبان را تغییر داده و ترتیب مد نظر خودمان را در معادله اعمال کنیم، می‌توانیم از پرانتز استفاده کنیم که در ادامه با ذکر چند مثال، این موضوع را بررسی خواهیم کرد اما ابتدا نگاهی به جدول Operator Associativity در زبان PHP می‌اندازیم (لازم به ذکر است که حرف R بدان معنا است که اعمال اپراتور از سمت راست صورت می‌گیرد، حرف L بدان معنا است که اعمال اپراتور از سمت چپ صورت می‌گیرد و عبارت NA که مخفف Non Associative است بدان معنا است که اپراتور از هیچ سمتی اولویت ندارد):

اپراتور (Operator) وابستگی (Associativity)
** R
++ R
-- R
(int) R
(float)  R
(string) R
(bool) R
(array) R
(object) R
?? R
! R
* L
/ L
% L
+ L
- L
. L
=< NA
< NA
=> NA
> NA
== NA
=== NA
=! NA
==! NA
<> NA
<=> NA
&& L
|| L
= R
=+ R
=- R
=* R
=** R
=/ R
=. R
=% R
and L
xor L
^ L
or L

برای روشن‌تر شدن این مسئله، معادلهٔ زیر را در نظر می‌گیریم:

<?php
$foo = 5 * 10 - 1;
echo $foo;

پیش از اجرای کد فوق، به عنوان خروجی اسکریپت فوق چند حالت مختلف را می‌توانیم در نظر بگیریم؛ در واقع، اگر ابتدا عدد ۵ را در ۱۰ ضرب کرده سپس عدد ۱ را از حاصل‌ضرب کسر کنیم، با عددی همچون ۴۹ مواجه خواهیم شد اما اگر ابتدا به ساکن عدد ۱ را از ۱۰ کسر کرده سپس نتیجه را در عدد ۵ ضرب کنیم، با عددی همچون ۴۵ مواجه خواهیم شد. حال اسکریپت را اجرا کرده تا ببینیم کدام حالت صدق می‌کند:

49

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

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

<?php
$foo = 5 * (10 - 1);
echo $foo;

در اسکریپت فوق دستور داده‌ایم تا مفسر PHP ابتدا نتیجهٔ معادلهٔ‌ داخل پرانتز را محاسبه کند؛‌ لذا خروجی اسکریپت فوق ۴۵ خواهد بود.

گاهی‌اوقات ترتیب اجرای اپراتورها کمی پیچیده می‌شود. برای مثال،‌ درک اینکه نتیجهٔ معادلهٔ زیر چیست کمی دشوار خواهد بود:

<?php
$foo = 5 - 5 - 5;
echo $foo;

در واقع، مقدار متغیر foo$ را می‌توان به دو شکل مختلف در نظر گرفت: 5 - (5 - 5) یا (5 - 5) - 5 و بسته به اینکه کدام یک توسط مفسر PHP در نظر گرفته شود، خروجی دو چیز کاملاً متفاوت خواهد شد: ۵- یا ۵.

پاسخ درست عدد ۵- است به این دلیل که جهت اجرای اپراتورها در اینجا تعیین‌کننده است. به عبارت دیگر، در دو طرف عدد پنجی که در وسط قرار گرفته است علامت منفی قرار دارد اما از آنجا که - اصطلاحاً Left Associative است (به جدول فوق مراجعه شود)، عملیات سمت چپ ابتدا صورت می‌گیرد. در واقع، ابتدا ۵ - ۵ شده که حاصل می‌شود 0 سپس داریم ۵ - ۰ که نتیجهٔ ۵- نشان داده می‌شود.

هشدار
در زبان PHP ما این اجازه را نداریم تا اپراتورهایی که از Precedence (ترتیب) برابر برخوردار بوده و اولویتی نسبت به یکدیگر ندارند در کنار یکدیگر استفاده کنیم. به عبارت دیگر،‌ معادلهٔ 1 < 2 > 1 هرگز درست نیست و ارور دریافت خواهیم کرد اما معادلهٔ 1 == 1 => 1 درست است زیرا == از اولویت کمتری نسبت به => برخوردار است.

در ارتباط با چهار عمل اصلی جمع، تفریق،‌ ضرب و تقسیم اولویت اول با ضرب، سپس با تقسیم، جمع و در نهایت تفریق است:

<?php
$foo = 7 * 2 / 2 + 3 - 3;
echo $foo;

خروجی اسکریپت فوق عدد ۷ است. در واقع، ابتدا عدد ۷ در ۲ ضرب شده که می‌شود ۱۴؛ سپس حاصل‌ضرب بر عدد ۲ تقسیم شده که می‌شود ۷؛ در ادامه عدد ۷ با عدد ۳ جمع می‌شود که حاصل‌جمع آنها می‌شود ۱۰ و در نهایت هم عدد ۳ از ۱۰ کم شده که نتیجه می‌شود ۷. اگر بخواهیم با استفاده از پرانتز ترتیب اجرای اپراتورهای فوق را نشان دهیم خواهیم داشت:

<?php
$foo = ((((7 * 2) / 2) + 3) - 3);
echo $foo;

در تفسیر اسکریپت فوق بایستی بگوییم که داخلی‌ترین پرانتزها همواره اول اجرا می‌شوند. به عبارت دیگر، ابتدا پرانتزهای دور اعداد (2 * 7)، سپس پرانتزهای دور (2 / 14)، سپس پرانتزهای دور (3 + 7) و در نهایت پرانتز دور (3 - 10) اعمال می‌گردد. 

در جدول فوق، Operator Associativity در زبان PHP را معرفی کردیم. حال به منظور درک این مفهوم، چند مثال کاربردی می‌زنیم:

<?php
$myVariable = 10;
$foo = $myVariable = 4;
echo $foo;

دستور echo مقدار ۴ را چاپ خواهد کرد زیرا همان‌طور که در جدول فوق مشخص است، اپراتور = اصطلاحاً Right Associative است؛‌ به عبارت دیگر، از سمت راست اعمال می‌شود. در واقع،‌ ابتدا عدد ۴ به متغیر myVariable$ اختصاص یافته سپس مقدار این متغیر به متغیر foo$ اختصاص می‌یابد. به عنوان مثالی دیگر داریم:

<?php
$foo = (string) (float) (int) 4;
var_dump($foo);

به عنوان خروجی اسکریپت فوق داریم:

string(1) "4"

در حقیقت از آنجا که Casting که در آموزش‌های گذشته با مفهوم آن آشنا شدیم در زبان PHP اصطلاحاً Right Associative است، ابتدا عدد ۴ به دیتاتایپ int کَست می‌شود، سپس به دیتاتاپیت float و در نهایت string و از آنجا که کَست شدن به استرینگ در مرحلهٔ آخر قرار داشته و کَستی پس از آن صورت نمی‌گیرد، دیتاتاپ استرینگ برای عدد ۴ باقی می‌ماند.

نکته
نوع دیگری از اپراتورها در زبان PHP داریم که تحت عنوان Bitwise شناخته می‌شوند که امکان انجام محاسبات روی بیت‌های یک عدد صحیح را فراهم می‌آورند (Bit کوچک‌ترین واحد ذخیره‌سازی در سیستم‌های کامپیوتری است که مقدار آن ۰ یا ۱ می‌تواند باشد). از آنجا که این نوع اپراتورها مناسب دولوپرهای بسیار حرفه‌ای است، از پرداختن به این نوع اپراتور در این دوره خودداری می‌کنیم.

آشنایی با اپراتور Ternary در زبان PHP
در زبان PHP اپراتوری داریم تحت عنوان Ternary که با علامت ? تعریف می‌شود. به نظر می‌رسد که ذکر یک مثال، به خوبی کاربرد این متغیر را مشخص سازد:

<?php
$isMale = true;
$result = $isMale ? 'Male' : 'Female';
echo $result;

به عنوان خروجی اسکریپت فوق داریم:

Male

حال کدهای فوق را به صورت زیر ریفکتور می‌کنیم:

<?php
$isMale = false;
$result = $isMale ? 'Male' : 'Female';
echo $result;

اکنون به عنوان خروجی اسکریپت فوق داریم:

Female

در تفسیر نحوهٔ عملکرد Ternary Operator بایستی بگوییم که اگر Condition (شرط) یا همان عملوندی که در سمت چپ ? قرار می‌گیرد true بود، عملوندی که در سمت راست اپراتور ? قرار گرفته بازگردانده می‌شود و در غیر این صورت، هر چیزی که پس از علامت : قرار گرفته باشد بازگردانده خواهد شد. در فصول آتی با دستورات شرطی در زبان PHP آشنا خواهید شد اما اگر بخواهیم اپراتور ? را با If/Else جایگزین کنیم، خواهیم داشت:

<?php
$isMale = true;
if ($isMale) {
    $result = 'Male';
} else {
    $result = 'Female';
}
echo $result;

آشنایی با اپراتور Null Coalescing در زبان PHP
Null Coalescing Operator به نوعی همان Ternary Operator است با این تفاوت که فانکشن ()isset هم در آن گنجانده شده است که این وظیفه را دارا است تا چک کند متغیر ورودی اصطلاحاً Set (مقداردهی) شده است یا خیر. به عنوان مثال داریم:

<?php
$firstName = 'Behzad';
$result = $firstName ?? 'Unknown';
echo $result;

به عنوان خروجی اسکریپت فوق داریم:

Behzad

حال کدهای فوق را به صورت زیر بازنویسی می‌کنیم:

<?php
$firstName;
$result = $firstName ?? 'Unknown';
echo $result;

باتوجه به اینکه متغیر firstName$ اصطلاحاً Set (مقداردهی) نشده است، عملوند قرار گرفته پس از اپراتور ?? به متغیر result$ اختصاص می‌یابد (برای آشنایی بیشتر با این اپراتور، به مقالهٔ آشنایی با اپراتور Null Coalesce در PHP نسخهٔ ۷ مراجعه نمایید).

آشنایی با اپراتور Reference در زبان PHP
Reference Operator مبحث گسترده‌ای در زبان PHP است که برای آشنایی بیشتر با این اپراتور، توصیه می‌کنیم به مقالهٔ آشنایی با تفاوت Pass by Value و Pass By Reference در زبان PHP مراجعه نمایید.

آشنایی با اپراتور @ در زبان PHP
برای روشن‌تر شدن کاربرد اپراتور @ در زبان PHP، ابتدا کدهای زیر را در نظر بگیرید:

<?php
$variable = 12;
if ($variable) {
   echo 'It`s set';
}

در اسکریپت فوق متغیری داریم تحت عنوان variable$ که مقدار ۱۲ برای آن در نظر گرفته شده است؛ سپس با یک دستور شرطی، سنجیده‌ایم که اگر این متغیر مقداردهی شده بود، با دستور echo استرینگی را چاپ کنیم. حال کدهای فوق را به صورت زیر تغییر می‌دهیم:

<?php
//$variable = 12;
if ($variable) {
   echo 'It`s set';
}

به عنوان خروجی اسکریپت فوق داریم:

Notice: Undefined variable: variable in /var/www/sokanacademy-php-course/02/index.php on line 3

در حقیقت، با کامنت کردن متغیر مد نظر، مفسر قادر به دیدن این متغیر نخواهد بود و همان‌طور که در اخطار فوق می‌بینیم، مفسر PHP به ما اخطار می‌دهد که هیچ متغیری تحت عنوان variable$ تعریف نشده است. حال اگر بخواهیم Notice (اخطار) فوق را از بین ببریم، می‌توانیم اپراتور @ را به صورت زیر مورد استفاده قرار دهیم:

<?php
//$variable = 12;
if (@$variable) {
   echo 'It`s set';
}

حال اگر این اسکریپت را اجرا کنیم، هیچ‌گونه اخطاری دریافت نخواهیم کرد.

هشدار
توصیه می‌شود که از این اپراتور تا حد ممکن استفاده نکنید چرا که گاهی‌اوقات فرایند دیباگینگ اپلیکیشن را بسیار دشوار می‌سازد و ممکن دولوپر را در یافتن ریشهٔ مشکل سردرگم سازد!

آشنایی با اپراتور `whoami` در زبان PHP
اگر دستور ('shell_exec('whoami را در وب‌ سرورهای Apache یا Nginx اجرا کنیم، خروجی www-data در معرض دیدمان قرار خواهد گرفت. در زبان PHP اپراتوری داریم که اصطلاحاً Backtick Operator نامیده می‌شود که دقیقاً همین کار را انجام می‌دهد:

<?php
echo `whoami`;

لازم به ذکر است که اگر این اپراتور را در محیط کامندلاین اجرا کنیم، نام کاربری که لاگین است چاپ خواهد شد:

$ php -r 'echo `whoami`;'

به عنوان خروجی اسکریپت فوق داریم:

behzadmoradi
لیست نظرات
کاربر میهمان
دیدگاه شما چیست؟
کاربر میهمان
sel3ulba
sel3ulba
به نظر اشکالی تایپی در بیان مقدار عملگر اسپیسشیپ وجود داره.🤔
محسن
محسن
در مورد عملگر چون اگر یکی از طرفین شرط صحیح باشن، نتیجه نهایی صحیح یا True در نظر گرفته میشه
در بسیاری از زبان ها هنگامی که طرف اول شرط درست باشه دیگه طرف دوم اصلا بررسی نمیشه، به این صورت سرعت خواندن و اجرای کدها افزایش پیدا می کنه چون ممکن است تعداد حالات بررسی بسته به کاربرد بسیار زیاد باشد و بررسی تمامی حالات زمان بر باشه
به این ترتیب به محض رسیدن به اولین حالت True در or خواندن اون قسمت از کد خاتمه پیدا می کنه و خط بعدی خونده میشه
Insight
Insight
یکی از مواردی که ممکنه مبتدیان درک درستی ازش نداشته باشن، عملگرهای === و !== هستن.
عملگر اول، زمانی true برمیگردونه که دو عملوند دارای مقدار و نوع‌داده‌ی برابر باشن اما
عملگر دوم، زمانی true برمیگردونه که دو عملوند دارای مقدار یا نوع‌داده‌ی نابرابر باشن لذا به تفاوت [و] و [یا] دقت کنید.
رضا سنگ‌سفیدی
رضا سنگ‌سفیدیطراح رابط کاربری/توسعه‌دهنده php
نمیدونم توی php هم به همین صورت هستش یا نه اما در مدارات منطقی عملگر xor بصورت کلی وقتی تعداد فردی از متغیر ها true باشند، true برمیگردونه.