表达式和运算符

表达式

表达式是PHP最重要的基石。在PHP中,几乎所写的任何东西都是一个表达式。简单但却最精确的定义一个表达式的方式就是“任何有值的东西”。

PHP是一种面向表达式的语言,从这一方面来讲几乎一切都是表达式。

运算符

运算符优先级

如果运算符优先级相同,那运算符的结合方向决定了该如何运算。

没有结合的相同优先级的运算符不能连在一起使用。

算术运算符

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

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

取模运算符%的结果和被除数的符号(正负号)相同。即$a%$b的结果和$a的符号相同。

 赋值运算符

注意赋值运算将原变量的值拷贝到新变量中(传值赋值)。在PHP中普通的传值赋值行为有个例外就是碰到对象object时,在PHP5中是以引用赋值的,除非明确使用了clone关键字来拷贝。

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

位运算符

位运算符允许对整型数中指定的位进行求值和操作。

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

比较运算符

$a<=>$b     太空船运算符(组合比较符),当$a小于、等于、大于$b时分别返回一个小于、等于、大于0的integer值。PHP7开始提供。

$a??$b??$c  NULL合并操作符,从左往右第一个存在且不为NULL的操作数。如果都没有定义且不为NULL,则返回NULL。PHP7开始提供。

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

表达式和运算符

Warning

比较浮点数

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

三元运算符

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

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

错误控制运算符

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

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

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

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

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

执行运算符

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

Note:反引号运算符在**了安全模式或者关闭了shell_exec()时是无效的。

Note:与其它某些语言不同,反引号不能在双引号字符串中使用。

递增/递减运算符

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

在处理字符变量的算数运算时,PHP沿袭了Perl的习惯,而非C的。注意字符变量只能递增,不能递减,并且只支持纯字母(a-z和A-Z)。递增/递减其他字符变量则无效,原字符串没有变化。

逻辑运算符

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

字符串运算符

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

 数组运算符

+运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的被忽略。

类型运算符

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

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

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

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

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

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

在PHP5.1.0之前,如果要检查的类名称不存在,instanceof会调用_autoload()。另外,如果该类没有被装载则会产生一个致命错误。可以通过使用动态类引用或用一个包含类名的字符串变量来避开这种问题。

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