本节名称暗示,操作符促进操作。PHP中有很多种操作符,常用的有:
PHP同时提供了其他操作符:
作者提示:有极少数情况,PHP的操作符是二元操作符——需要两个操作数,所有的二元操作符都是夹在两个操作数中间(如,2 + 2)。
算术运算可以提供基本的数学算术运算:
加 | $a = 1 + 3.5; |
减 | $a = 4 – 2; |
乘 | $a = 8 * 3; |
除 | $a = 15 / 5; |
取余 | $a = 23 % 7; |
下面是例子:
$a = 1; // 赋 1 给变量 $a echo $a++; // 输出1, $a现在的值是2 echo ++$a; // 输出3, $a现在的值是3 echo --$a; // 输出2, $a现在的值是2 echo $a--; // 输出2, $a现在的值是1
作者提示:过度使用递增递减会让代码难以阅读——甚至经验丰富的程序员有时也会对一些难懂的递增递减操作而头疼。因此,注意控制自己不要滥用。
递增/递减还有一个重点——作用在一个表达式或者一个硬编码的表两值时容易导致解释器抛出一个错误。并且,变量通过递增递减操作会自动转换成数值型——结果就是返回1,因为字符Test被转换为整形时为0,然后自增到了1返回:
$a = (int)('Test'); // $a == 0 echo ++$a;
与很多其他不言不同的是PHP可以把两个字符串连起来:
$string = "foo" . "bar"; // $string 现在的值是 'foobar' $string2 = "baz"; // $string2 现在的值是 'baz' $string .= $string2; // 通过连接两个变量,现在我们得到了'foobarbaz' echo $string; // 显示 'foobarbaz'
这里请记住这是不仅是合适的连接字符串的方法,也是唯一的方法。使用加操作符会使字符串转换成数值,然后进行算术元预算内(结果也就变成了数值)。
位运算符提供手动操作位数据。所有的为操作符都是用来操作整数的——因此,解释器在执行位操作之前试图将操作数转换成整型。
最简单的位操作符是按位非,反转所有整数的位(0设为1,1设为0):
$x = 0; echo ~$x; // 输出 -1
以下列出一组用于位比较的操作符,需要两个操作数:
& | 按位与。把两个操作数中都为1的位设为1 |
| | 按位或。把两个操作数中该位一个0一个1设为1,其余设为0 |
^ | 按位异或。把两个操作数不同的位设为1 |
这些操作符并不难理解——可能OR会稍难一些,第一印象好像是奇数。实际上非常简单:当两个操作数在该位上是不同时,设为1,相同时(比如同时为1或者同时为0)设为0。
第三部分的操作符用来位移:
<< | 左位移。将位左移几位,移出的位用0补齐。 |
>> | 右位移。将位右移几位,移出的位用0补齐。 |
这些操作符可以产生一个有趣的且速度极快的乘法效果,如:
$x = 1; echo $x << 1; // 输出2 echo $x << 2; // 输出4 $x = 8; echo $x >> 1; // 输出4 echo $x << 2; // 输出2
无论如何请明白,位操作符能够估算出两个数之间的相乘或者相除结果,并非精准——尤其是产生溢出的计算中会得到出乎意料的结果。在32位系统中将发生下面情况:
$x = 1; echo $x << 32; echo $x * pow(2, 32);
第二行中的例子,实际上因该输出0——因为所有的位都已经被移走。第三行中返回的实际值4,294,967,296——返回值类型是浮点型,已经能够很好的说明32位系统无法精确计算这样的数值。
Siemen注:这里为什么说pow返回浮点型就说明无法精确计算呢?因为pow在官方手册记载这个方法在可以表达的范围内返回的是整型值,否则返回浮点型,如果无法被计算则返回false。传送门:http://cn.php.net/manual/en/function.pow.php
鉴于本节富有创意的命名可以证明一点,你可能很难想象赋值操作符可以将一个值赋给一个变量。(Siemen注:这句翻得不好,其实没有看的很明白)最简单的赋值操作符就是等号,之前很多例子中都看到过的:
$variable = 'value'; // $variable 现在装载一个字符型值 'value'
另外这个复制操作符还可以配合所有二元算数运算符与位操作符来对自身做的操作:
$variable = 1; // $variable 变量现在装载整型数据 1 $variable += 3; /* $variable 现在装载的值是4了 */
在这个例子中,就等同于执行了$variable = $variable + 3的操作。类似这样的组合适用所有算数二元运算符和位运算符。
默认情况下,赋值操作符作用于值——确实,这实质上是一种复制的行为。赋值的两个变量没有任何联系,只是内容完全相同,如果赋值完成后其中一个变量发生了改变,与另一个没有任何关系(也就是另一个还是保持赋值之前的值),不存在引用关系:
$a = 10; $b = $a; $b = 20; echo $a; // 输出 10
很显然你可以预料到这个结果,但你想要让$a与$b存在引用关系,也就是两者相互联系:
$a = 10; $b = &$a; // 建立引用关系 $b = 20; echo $a // 输出20
作者提示:赋值操作符可以作用于任何类型数据(这里只建立复制关系),除了对象,不管你在用等号时有没有用到&符号都是建立引用关系。
使用引用关系的变量有的时候非常有用,同时伴随着风险,引用会使变量长期存在不容易释放内存,甚至只是单独的方法也不例外。另外,不像其他语言那样,PHP使用引用变量往往效率没有使用非引用变量来的高,其原因就是PHP采用“延时拷贝”的机制优化了普通赋值的效率。
比较操作符是建立在两个值之间的是否相等操作的二元操作符。可以在任意两个值之间进行等相等和大小的比较。比较返回的结果通常是布尔类型的。以下是一组相等比较符:
== | 相等。两边值相等返回true,不等则返回false,不需要两个值的类型都相等。 |
=== | 全等。这个不仅要值相等,值的数据类型也必须相等才会返回true,否则返回false。 |
!= | 不等。两边值不相等返回true,相等则返回false,不检查值类型是否相等。 |
!== | 全不等。只有两边值不相等并且值得类型也不相等时才返回true,否则返回false。 |
你可以想像,赋值操作符与相等操作符非常容易混淆,事实上,这是程序员经常犯迷糊的地方。这里提供一条避免发生这类问题的建议,如果是一个变量和一个直接量比较,那么把直接量作为第一个操作数,比如:
echo $a == 10;
你可以把它写成:
echo 10 == $a;
这样就可以很明显的区分赋值符与相等符——赋值符左边必须是变量,如果你不小心把 == 写成了 = 或者反过来,那么这样可以让解释器帮助你找到错误,解释器会抛出一个异常,警告你什么地方发生了错误。
下面有一组不同的比较操作符,用于比较出两个中哪个更大些:
< 和 <= | 左边小于(小于等于)右边,返回true,否则返回false |
> 和 >= | 左边大于(大于等于)右边,返回true,否则返回false |
很明显,比较的规则与比较值得类型有关。比较数值就是比较位数据;比如说字符床的比较就是比较两个值的比特数据,直到出现了不同的比特值,然后将其作为数值对这两个不同的比特进行比较。例如:
$left = "ABC"; $right = "ABD"; echo (int)($left > $right);
以上代码输出0(也就是false),因为在$right中字母D高于对应在$left中的字母C。你可能会觉得这只是在利用字母顺序来比较,与现实中的字母比较没有差别。那么请考虑下面例子:
$left = 'apple'; $right = 'Apple'; echo (int)$left > $right;
这个例子的结果是1(也就是true),因为小写a的ascii码是97大于大写A的65。显然这样的处理不利于对文本的比较,我们需要利用其他方法来解决,这点会在字符串章节中有介绍。
作者提示:将比较操作符作用于数组时,比较规则另有不同,具体会在数组章节详细介绍。
逻辑运算福通常被用于比较两个布尔值得出第三个布尔值。PHP中有四种逻辑运算符,其中三种是二元运算符。唯一一个不是一元运算符就是逻辑非,用于逆转单个操作数:
$a = false; echo !$a; // 输出1 (true)
所有逻辑运算符都是基于布尔值的;因此PHP会首先将要进行逻辑运算的两个操作数转换成布尔值。三个二元运算符:
&& / and | 当两边同时为true时返回true,其余情况返回false。 |
|| / or | 只有两边同时为false时返回false,其余情况返回true。 |
XOR | 只有当两边其中之一为true时才返回true,全true全false的情况都返回false。 |
记住一点,简洁为逻辑运算的上上策。例如,AND运算中第一个操作符就是false,那么第二个操作符解释器就不会上去判断了,会立刻返回false。
提高逻辑运算效率的救命稻草有很多种,万变不离其中的是尽可能在第一个操作符上就可以敲定结果。
除了之前讲过的所有操作符外,PHP也会在某些任务中使用一些特殊的操作符。其中一个就是错误抑制符@;当它出现在一个表达式之前,那个表达式产生的几乎所有错误信息都会被解释器忽略:
$x = @mysql_connect();
以上代码可以抑制调用mysql_connect()时输出的错误信息,仅限于PHP内部功能性的错误。沮丧的是,一些类库会立刻输出错误信息,然后再移交至PHP,因此很难去抑制此种错误消息的输出。
反引号(Siemen注:具体位置是键盘Esc正下方)操作符可以执行系统指令并返回输出值。例如,我们可以输出UNIX执行ls命令的结果存入变量$a:
$a = `ls -l`;
作者提示:弄清楚这个是反引号,不要与但引号混淆。
我们学完了操作符,那么不是所有操作符的优先级都相同。当我们使用一系列的操作符组成一个表达式的时候会出现很多歧义的地方需要理顺。这些可以歧义有两种方法可以解决:使用括号表示那些操作符应该先执行,或者记住这些操作符内部的默认优先顺序。
即使我们确定了每个操作符的优先级,但我们仍然缺少一个重要的规则:我们怎么去执行拥有相同优先级的操作符?这个要取决于操作符的关联性,有些从左往右,有些从右往左或者没有任何关联性。
下面这个表格展示了每一个操作符的优先级和关联性:
关联性 | 操作符 |
左 | [ |
- | ++ -- |
- | ~ – (int) (float) (string) (array) (object) @ |
- | instanceof |
右 | ! |
左 | * / % |
左 | + - . |
左 | << >> |
- | < <= > >= |
- | == != === !== |
左 | & |
左 | ^ |
左 | | |
左 | && |
左 | || |
左 | ? : |
右 | = += –= *= /= .= %= &= |= ^= <<= >>= |
左 | and |
左 | xor |
左 | or |
左 | , |
修正:
2010年04月06日 —— Siemen
1. 代码部分使用csdn代码重新插入