PHP 的运算符,它包含算术运算符、赋值运算符、位运算符、比较运算符、执行运算符、递增递减运算符、逻辑运算符、字符串运算符和数组运算符,它们之间的优先级也非常重要。
算术运算符
常见算术运算符包括
- -$a,取反
- $a + $b,加法,$a 和 $b 的和
- $a - $b,减法,$a 和 $b 的差
- $a * $b,乘法,$a 和 $b 的积
- $a / $b,除法,$a 和 $b 的商
- $a % $b,取余,$a 除以 $b 的余数
- $a ** $b,乘方,$a 的 $b 次方
<?php
$a = 9 / 3;
$b = 9 / 4;
$c = -5 % 3;
$d = 5 % -3;
$e = 2 ** -2;
echo <<<EOT
9 / 3 = $a
9 / 4 = $b
-5 % 3 = $c
5 % -3 = $d
2 ** -2 = $e
EOT;
从结果可以看出
- 除法运算符总是返回浮点数。只有在下列情况例外:两个操作数都是整数(或字符串转换成的整数)并且正好能整除,这时它返回一个整数。
- 取余运算符的操作数在运算之前都会转换成整数(除去小数部分)。 并且结果和被除数的符号(正负号)相同。即 $a % $b 的结果和 $a 的符号相同。
赋值运算符
基本的赋值运算符是 =
,意味着把右边表达式的值赋给左边的运算数。
赋值运算表达式的值也就是所赋的值。也就是说,$a = 3 的值是 3。这样就可以做一些小技巧:
<?php
$a = ($b = 4) + 5; // $a 现在成了 9,而 $b 成了 4。
对于数组 array,对有名字的键赋值是用 => 运算符。此运算符的优先级和其它赋值运算符相同。
<?php
$a = ['a' => 1, 'b' => 3 * 4];
在基本赋值运算符之外,还有适合于所有二元算术,数组集合和字符串运算符的组合运算符,这样可以在一个表达式中使用它的值并把表达式的结果赋给它,例如:
<?php
$a = 3;
$a += 5; //相当于 $a = $a + 5;
$b = "Hello ";
$b .= "There!"; //相当于 $b = $b. "There" ;
注意赋值运算将原变量的值拷贝到新变量中(传值赋值),所以改变其中一个并不影响另一个。这也适合于在密集循环中拷贝一些值例如大数组。
引用赋值
PHP 支持引用赋值,引用赋值意味着两个变量指向了同一个数据,没有拷贝任何东西。
<?php
$arr1 = $arr2 = [1,2,3];
foreach($arr1 as &$a) {
$a++;
}
foreach($arr2 as $a) {
$a++;
}
print_r($arr1);
print_r($arr2);
从结果中可以看出,引用赋值会改变原值,传值赋值则不会。
位运算符
位运算符允许对整型数中指定的位进行求值和操作。
-
$a & $b
,And(按位与),将把 $a 和 $b 中都为 1 的位设为 1。 -
$a | $b
,Or(按位或),将把 $a 和 $b 中任何一个为 1 的位设为 1。 -
$a ^ $b
,Xor(按位异或),将把 $a 和 $b 中一个为 1 另一个为 0 的位设为 1。 -
~$a
,Not(按位取反),将 $a 中为 0 的位设为 1,反之亦然。 -
$a << $b
,Shift left(左移),将 $a 中的位向左移动 $b 次(每一次移动都表示乘以 2)。 -
$a >> $b
,Shift right(右移),将 $a 中的位向右移动 $b 次(每一次移动都表示除以 2)。
<?php
/*
* Ignore the top section,
* it is just formatting to make output clearer.
*/
$format = '(%1$2d = %1$04b) = (%2$2d = %2$04b)'
. ' %3$s (%4$2d = %4$04b)' . "\n";
echo <<<EOH
--------- --------- -- ---------
result value op test
--------- --------- -- ---------
EOH;
/*
* Here are the examples.
*/
$values = array(0, 1, 2, 4, 8);
$test = 1 + 4;
echo "\n Bitwise AND \n";
foreach ($values as $value) {
$result = $value & $test;
printf($format, $result, $value, '&', $test);
}
echo "\n Bitwise Inclusive OR \n";
foreach ($values as $value) {
$result = $value | $test;
printf($format, $result, $value, '|', $test);
}
echo "\n Bitwise Exclusive OR (XOR) \n";
foreach ($values as $value) {
$result = $value ^ $test;
printf($format, $result, $value, '^', $test);
}
?>
以上例程会输出:
--------- --------- -- ---------
result value op test
--------- --------- -- ---------
Bitwise AND
( 0 = 0000) = ( 0 = 0000) & ( 5 = 0101)
( 1 = 0001) = ( 1 = 0001) & ( 5 = 0101)
( 0 = 0000) = ( 2 = 0010) & ( 5 = 0101)
( 4 = 0100) = ( 4 = 0100) & ( 5 = 0101)
( 0 = 0000) = ( 8 = 1000) & ( 5 = 0101)
Bitwise Inclusive OR
( 5 = 0101) = ( 0 = 0000) | ( 5 = 0101)
( 5 = 0101) = ( 1 = 0001) | ( 5 = 0101)
( 7 = 0111) = ( 2 = 0010) | ( 5 = 0101)
( 5 = 0101) = ( 4 = 0100) | ( 5 = 0101)
(13 = 1101) = ( 8 = 1000) | ( 5 = 0101)
Bitwise Exclusive OR (XOR)
( 5 = 0101) = ( 0 = 0000) ^ ( 5 = 0101)
( 4 = 0100) = ( 1 = 0001) ^ ( 5 = 0101)
( 7 = 0111) = ( 2 = 0010) ^ ( 5 = 0101)
( 1 = 0001) = ( 4 = 0100) ^ ( 5 = 0101)
(13 = 1101) = ( 8 = 1000) ^ ( 5 = 0101)
比较运算符
比较运算符,如同它们名称所暗示的,允许对两个值进行比较。
-
$a == $b
,如果类型转换后 $a 等于 $b,返回 TRUE。 -
$a === $b
,如果 $a 等于 $b,并且它们的类型也相同,返回 TRUE。 -
$a != $b
,如果类型转换后 $a 不等于 $b,返回 TRUE。 -
$a <> $b
,等同于 != -
$a !== $b
,如果 $a 和 $b 的值或类型不同,返回 TRUE。 -
$a < $b
,如果 $a 严格小于 $b,返回 TRUE。 -
$a > $b
,如果 $a 严格大于 $b,返回 TRUE。 -
$a <= $b
,如果 $a 小于或者等于 $b,返回 TRUE。 -
$a >= $b
,如果 $a 大于或者等于 $b,返回 TRUE。
如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。此规则也适用于 switch 语句。当用 === 或 !== 进行比较时则不进行类型转换,因为此时类型和数值都要比对。
<?php
var_dump(null == "");
var_dump(null == false);
var_dump(true > false);
var_dump(0 == "a");
var_dump("1" == "01");
var_dump("10" == "1e1"); // 1e1=10
var_dump(100 == "1e2"); // 1e2=100
var_dump([4,5] < [1,2,3]);
var_dump((object)"Test" > "Test");
var_dump((object)"Test" > [2,3]);
switch ("a") {
case 0:
echo "0";
break;
case "a":
echo "a";
break;
}
- null 或 String 和 string 比较时,将 null 转换为 "",进行数字或词汇比较
- bool 或 null 和其他类型比较时,转换为 bool,FALSE < TRUE
- string,resource 或 number 相互比较时,将字符串或资源转换为数字,按普通数字比较
- array 之间比较时,具有较少成员的数组较小
- object 和其他类型比较时,object 总是更大
- array 和其他类型比较时,array 总是更大,但是比对象小
- switch 中第一个条件满足时,不会执行后面满足条件的语句
错误控制运算符
PHP 支持一个错误控制运算符:@
。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。
<?php
$my_file = @file ('non_existent_file') or
die ("Failed opening file: error was '$php_errormsg'");
$value = @$cache[$key];
错误控制运算符只对表达式有效。对新手来说一个简单的规则就是:
- 如果能从某处得到值,就能在它前面加上
@
运算符。例如,可以把它放在变量,函数和 include 调用,常量,等等之前。 - 不能把它放在函数或类的定义之前,也不能用于条件结构例如 if 和 foreach 等。
注意:目前的
@
错误控制运算符前缀甚至使导致脚本终止的严重错误的错误报告也失效。这意味着如果在某个不存在或者敲错了字母的函数调用前用了@
来抑制错误信息,那脚本会没有任何迹象显示原因而死在那里。
执行运算符
PHP 支持一个执行运算符:反引号(``)。注意这不是单引号!PHP 将尝试将反引号中的内容作为外壳命令来执行,并将其输出信息返回(例如,可以赋给一个变量而不是简单地丢弃到标准输出)。
<?php
$output = `ls -al`;
echo "<pre>$output</pre>";
注意,反引号运算符在激活了安全模式或者关闭了 shell_exec() 时是无效的。
递增(减)运算符
常见递增(减)运算符
-
++$a
,$a 的值加一返回 $a。 -
$a++
,返回 $a,然后将 $a 的值加一。 -
--$a
,$a 的值减一返回 $a。 -
$a--
,返回 $a,然后将 $a 的值减一。
递增(减)运算符对布尔和 NULL 类型的影响
<?php
$a = null;
$b = true;
var_dump(++$a, --$a, ++$b, --$b);
布尔值不受影响,NULL 递增为 1,递减为 0
<?php
$a = 0;
$i = 'W';
while($a < 6) {
echo "$a : ".++$i . PHP_EOL;
$a++;
}
从结果可知
在处理字符变量的算数运算时,PHP 沿袭了 Perl 的习惯,而非 C 的。例如
<?php
$a = 'Z';
// Perl 中
$a++;//将把 $a 变成'AA'
//C 中
$a++;//将把 $a 变成 '['('Z' 的 ASCII 值是 90,'[' 的 ASCII 值是 91)
注意字符变量只能递增,不能递减,并且只支持纯字母(a-z 和 A-Z)。递增(减)其他字符变量则无效,原字符串没有变化。
逻辑运算符
常见逻辑运算符
-
$a and $b
,逻辑与,如果 $a 和 $b 都为 TRUE -
$a && $b
,逻辑与,如果 $a 和 $b 都为 TRUE,其中 && 优先级高于 and -
$a or $b
,逻辑或,如果 $a 或 $b 任一为 TRUE -
$a || $b
,逻辑或,如果 $a 或 $b 任一为 TRUE,|| 优先级高于 or -
$a xor $b
,逻辑异或,如果 $a 或 $b 任一为 TRUE,但不同时是,则返回 TRUE -
! $a
,逻辑非,如果 $a 不为 TRUE
<?php
$a = (false && foo());
$b = (true || foo());
$c = (false and foo());
$d = (true or foo());
var_dump($a, $b, $c, $d);
$e = false || true;
$f = false or true;
$g = true && false;
$h = true and false;
var_dump($e, $f, $g, $h);
从结果可知
- foo() 虽然没有定义,但是并没有机会执行,因为之前的表达式已经确定结果,foo() 被短路。
- &&,|| 的优先级高于 =,= 的优先级高于 and,or。
字符串运算符
有两个字符串运算符。
- 第一个是连接运算符
.
,它返回其左右参数连接后的字符串 - 第二个是连接赋值运算符
.=
,它将右边参数附加到左边的参数后。
<?php
$a = "Hello ";
$b = $a . "World!"; // now $b contains "Hello World!"
$a = "Hello ";
$a .= "World!"; // now $a contains "Hello World!"
数组运算符
常见数组运算符
-
$a + $b
,$a 和 $b 的联合 -
$a == $b
,$a 和 $b 键和值都相同则为 TRUE -
$a === $b
,$a 和 $b 键和值且顺序和类型都相同返回 TRUE -
$a != $b
,$a 和 $b 中键或值不同返回 TRUE -
$a <> $b
,等同于 != -
$a !== $b
,$a 和 $b 中键,值,顺序或类型,其中一个不相同则返回 TRUE
<?php
$a = ["a" => "apple", "b" => "banana"];
$b = ["a" => "pear", "b" => "strawberry", "c" => "cherry"];
$c = ["b" => "banana", "a" => "apple"];
var_dump($a + $b, $b + $a);
var_dump($a == $c, $a === $c);
从结果可以看出
-
+
运算符把右边的数组元素(除去键值与左边的数组元素相同的那些元素)附加到左边的数组后面,但是重复的键值不会被覆盖。 - ===,需要数组的键,值,类型和顺序都相同,才返回 TRUE。
PHP7 新增操作符
组合比较符
太空船操作符使用 <=>
表示,用于比较两个表达式。当 $a 小于、等于或大于 $b 时它分别返回-1、0或1。 比较的原则是沿用 PHP 的常规比较规则进行的。
<?php
// 整数
echo 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
// 浮点数
echo 1.5 <=> 1.5; // 0
echo 1.5 <=> 2.5; // -1
echo 2.5 <=> 1.5; // 1
// 字符串
echo "a" <=> "a"; // 0
echo "a" <=> "b"; // -1
echo "b" <=> "a"; // 1
?>
NULL合并运算符
NULL 合并运算符使用 ?? 表示,意味着如果 ?? 之前的变量存在且值不为 NULL,它就会返回自身的值,否则返回 ?? 后的操作数。
<?php
$username = $_GET['user'] ?? 'nobody';
$username = isset($_GET['user']) ? $_GET['user'] : 'nobody';
$username = $_GET['user'] ?? $_POST['user'] ?? 'nobody';
合并运算符通常可用三元运算符作为替换,多个合并运算符的优先级从左到右依次执行。
网友评论