PHP学习之运算符

一、运算符的优先级

运算符优先级指定了两个表达式绑定得有多“紧密”。必要时可以用括号来强制改变优先级,括号的使用通常能够增加代码的可读性。

如果运算符优先级相同,那运算符的结合方向决定了该如何运算。例如,"-"是左联的, 1 - 2 - 3 等同于 (1 - 2) - 3 并且结果是 -4. 另外,"="是右联的,所以 $a = $b = $c 等同于 $a = ($b = $c)。

没有结合的相同优先级的运算符不能连在一起使用,例如 1 < 2 > 1 在PHP是不合法的。但另外一方面表达式 1 <= 1 == 1是合法的, 因为 == 的优先级低于 <=

下表按照优先级从高到低列出了运算符。同一行中的运算符具有相同优先级,此时它们的结合方向决定求值顺序。




二、算术运算符

除法运算符总是返回浮点数。只有在下列情况例外:两个操作数都是整数(或字符串转换成的整数)并且正好能整除,这时它返回一个整数

取模运算符的操作数在运算之前都会转换成整数(除去小数部分)。取模运算符的操作数在运算之前都会转换成整数(除去小数部分)。


三、赋值运算符

基本的赋值运算符是“=”。一开始可能会以为它是“等于”,其实不是的。它实际上意味着把右边表达式的值赋给左边的运算数

在基本赋值运算符之外,还有适合于所有二元算术,数组集合和字符串运算符的“组合运算符”,这样可以在一个表达式中使用它的值并把表达式的结果赋给它,例如:


注意赋值运算将原变量的值拷贝到新变量中(传值赋值),所以改变其中一个并不影响另一个。这也适合于在密集循环中拷贝一些值例如大数组。

在 PHP 中普通的传值赋值行为有个例外就是碰到对象 object 时,在 PHP 5 中是以引用赋值的,除非明确使用了 clone 关键字来拷贝。

PHP 支持引用赋值,使用“$var = &$othervar;”语法。引用赋值意味着两个变量指向了同一个数据,没有拷贝任何东西


自 PHP 5 起,new运算符自动返回一个引用,因此再对new 的结果进行引用赋值在 PHP 5.3 以及以后版本中会发出一条 E_DEPRECATED 错误信息,在之前版本会发出一条 E_STRICT 错误信息。

去掉引用符号&.

三、位运算符

位移在 PHP 中是数学运算。向任何方向移出去的位都被丢弃。左移时右侧以零填充,符号位被移走意味着正负号不被保留。右移时左侧以符号位填充,意味着正负号被保留。

要用括号确保想要的优先级。例如 $a & $b == true 先进行比较再进行按位与;而 ($a & $b) == true 则先进行按位与再进行比较。


如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。此规则也适用于 switch语句。当用 === 或 !== 进行比较时则不进行类型转换,因为此时类型和数值都要比对


var_dump() 函数用于输出变量的相关信息。显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。语法:var_dump (var,var,bar);

注意:
必须保证var_dump中的变量必须是存在的,如果变量存在但值是空,则返回false;
没有变量时,则返回NULL。
该函数有输出的功能,因此不必加其它的输出函数。)


对于多种类型,比较运算符根据下表比较(按顺序)。


注意:比较浮点数:由于浮点数 float 的内部表达方式,不应比较两个浮点数float是否相等。

三元运算符-》另一个条件运算符是“?:”(或三元)运算符

表达式 (expr1) ? (expr2) : (expr3) 在 expr1 求值为 TRUE 时的值为 expr2,在 expr1 求值为 FALSE 时的值为 expr3

自 PHP 5.3 起,可以省略三元运算符中间那部分。表达式 expr1 ?: expr3 在 expr1 求值为 TRUE 时返回 expr1,否则返回 expr3

Note 注意 三元运算符是个语句,因此其求值不是变量,而是语句的结果 。如果想通过引用返回一个变量这点就很重要。 在一个通过引用返回的函数中语句  return $var == 42 ? $a : $b; 将不起作用,以后的 PHP 版本会为此发出一条警告。

注意:建议避免将三元运算符堆积在一起使用。当在一条语句中使用多个三元运算符时会造成 PHP 运算结果不清晰:


六、错误控制运算符


PHP 支持一个错误控制运算符:@。当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉

如果用 set_error_handler() 设定了自定义的错误处理函数,仍然会被调用,但是此错误处理函数可以(并且也应该)调用 error_reporting(),而该函数在出错语句前有 @ 时将返回 0。

如果激活了 track_errors 特性,表达式所产生的任何错误信息都被存放在变量 $php_errormsg 中。此变量在每次出错时都会被覆盖,所以如果想用它的话就要尽早检查。

Note@ 运算符只对表达式有效。对新手来说一个简单的规则就是:如果能从某处得到值,就能在它前面加上 @ 运算符。例如,可以把它放在变量,函数和 include 调用,常量,等等之前。不能把它放在函数或类的定义之前,也不能用于条件结构例如 if 和 foreach 等。

Warning

目前的“@”错误控制运算符前缀甚至使导致脚本终止的严重错误的错误报告也失效。这意味着如果在某个不存在或者敲错了字母的函数调用前用了“@”来抑制错误信息,那脚本会没有任何迹象显示原因而死在那里。

七、执行运算符

PHP 支持一个执行运算符反引号(``)。注意这不是单引号!PHP 将尝试将反引号中的内容作为 shell 命令来执行并将其输出信息返回(即,可以赋给一个变量而不是简单地丢弃到标准输出)。使用反引号运算符“`”的效果与函数shell_exec() 相同

Note:

反引号运算符在激活了安全模式或者关闭了 shell_exec() 时是无效的。与其它某些语言不同,反引号不能在双引号字符串中使用。

八、递增、递减运算符

Note 递增/递减运算符 不影响布尔值。递减 NULL 值也没有效果,但是递增 NULL 的结果是 1

下面是一个例子,帮助理解:

<?php
header("Content-type: text/html; charset=utf-8"); 


echo "<h3>Postincrement</h3>";
$a = 5;
/* 
此处后加表示变量b获取a的值5,然后a的值再加1(注意b的值并未加1),
所以b的值为5,a的值变为1.
$b = $a++;
echo $b;
echo $a;
*/
echo "should be 5: " . $a++ . "<br />\n";
echo "Should be 6: " . $a . "<br />\n";


echo "<h3>Postincrement</h3>";
$a = 5;
/*此处是先将a的值加1,然后再赋值给b,所以a、b都是6
$b = ++$a;
echo "$a, $b" . "<br />\n";*/
echo "should be 6: " . ++$a . "<br />\n";
echo "should be 6: " . $a . "<br />\n";


echo "<h3>Postincrement</h3>";
$a = 5;
/*此处是先将a的值赋给b,即为5,然后将a的值减1,所以a为4
$b = $a--;
echo "$a, $b" . "<br />\n";*/
echo "should be 5: " . $a-- . "<br />\n";
echo "should be 4: " . $a . "<br />\n";


echo "<h3>Postincrement</h3>";
$a = 5;
/*此处先将a的值-1赋给b,则b为4,a变为4
$b = --$a;
echo "$a, $b" . "<br />\n";*/
echo "should be 4: " . --$a . "<br />\n";
echo "should be 4: " . $a . "<br />\n";
?>

在处理字符变量的算数运算时,PHP 沿袭了 Perl 的习惯,而非 C 的。例如,在 Perl 中 $a = 'Z'; $a++; 将把 $a 变成'AA',而在 C 中,a = 'Z'; a++; 将把 a 变成 '[''Z' 的 ASCII 值是 90,'[' 的 ASCII 值是 91)。注意字符变量只能递增,不能递减,并且只支持纯字母(a-z 和 A-Z)。递增/递减其他字符变量则无效,原字符串没有变化。

注意:PHP 中换行可以用 PHP_EOL 来替代,以提高代码的源代码级可移植性:unix系列用 \n;windows系列用 \r\n;mac用 \r。注意,也可以用“ . "<br />\n"


运行结果:

九、逻辑运算符

“与”和“或”有两种不同形式运算符的原因是它们运算的优先级不同。

十、连接运算符

有两个字符串(string)运算符。第一个是连接运算符(“.”),它返回其左右参数连接后的字符串。第二个是连接赋值运算符(“.=”),它将右边参数附加到左边的参数之后。更多信息见赋值运算符


十一、数组运算符

注意:+ 运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的对应的建和键对应的值都会被忽略


十二、类型运算符

instanceof 用于确定一个 PHP 变量是否属于某一类 class 的实例


instanceof 也可用来确定一个变量是不是继承自某一父类的子类的实例:


检查一个对象是否不是某个类的实例,可以使用逻辑运算符not


最后,instanceof也可用于确定一个变量是不是实现了某个接口的对象的实例:


虽然 instanceof 通常直接与类名一起使用,但也可以使用对象或字符串变量


如果被检测的变量不是对象,instanceof 并不发出任何错误信息而是返回 FALSE。不允许用来检测常量



然而 instanceof 的使用还有一些陷阱必须了解。在 PHP 5.1.0 之前,如果要检查的类名称不存在,instanceof 会调用__autoload()。另外,如果该类没有被装载则会产生一个致命错误。可以通过使用动态类引用或用一个包含类名的字符串变量来避开这种问题: 

避免 PHP 5.0 中 instanceof 引起的类名查找和致命错误问题


instanceof 运算符是 PHP 5 引进的。在此之前用 is_a(),但是后来 is_a() 被废弃而用 instanceof 替代了。注意自 PHP 5.3.0 起,又恢复使用 is_a() 了。