PHP 运算符
在 PHP 中,运算符是一种特殊的符号,它告诉编译器或解释器执行特定的数学或逻辑操作。运算符可以作用于一个、两个或三个操作数(即值或变量),并返回一个结果。这个结果可以被赋值给一个变量或者作为更大表达式的一部分。
运算符优先级
在同一个表达式中,如果有多个运算符,它们之间的运算顺序并不是简单的从左向右。运算符优先级就规定了这些运算符的执行顺序。
1. 运算符优先级
• 运算符优先级决定了表达式中运算符的计算顺序。
• 例如,在表达式 1 + 5 * 3 中,乘法(*)的优先级高于加法(+),所以先进行乘法运算,再进行加法运算。因此,结果是 1 + 15 = 16。
• 如果你希望改变默认的计算顺序,可以使用括号。例如,(1 + 5) * 3 先进行括号内的加法运算,结果是 6 * 3 = 18。
2. 运算符结合方向
• 当运算符具有相同的优先级时,结合方向决定了运算顺序。
• 例如,减法运算符(-)是左结合的,所以表达式 1 – 2 – 3 等同于 (1 – 2) – 3,结果是 -4。
• 赋值运算符(=)是右结合的,所以表达式 $a = $b = $c 等同于 $a = ($b = $c)。
3. 无法连用的运算符
• 有些具有相同优先级的运算符不能连用。例如,比较运算符 < 和 > 不能连用,表达式 1 < 2 > 1 在 PHP 中是不合法的。
• 但是,比较运算符 <= 和 == 可以连用,因为 == 的优先级低于 <=,所以 1 <= 1 == 1 是合法的。
4. 结合方向的意义
• 结合方向只对二元或三元运算符有意义。一元运算符要么是前缀(如 !),要么是后缀(如 ++),所以不适用结合方向的概念。
• 例如,表达式 !!$a 只能被解析为 !(!$a)。
5. 括号的使用
• 使用括号可以明确运算顺序,增加代码的可读性,即使在不需要括号的情况下,括号仍然有助于理解代码。
算术运算符
PHP 中算术运算符如下:
运算符 | 描述 | 示例 | 结果 |
---|---|---|---|
+ | 正号(一元运算符),或加法(二元运算符) | +$a, $a + $b | 将$a转换为数字,或将两个数相加 |
– | 负号(一元运算符),或减法(二元运算符) | -$a, $a – $b | 求$a的相反数,或将两个数相减 |
* | 乘法 | $a * $b | 求$a和$b的乘积 |
/ | 除法 | $a / $b | 求$a除以$b的商 |
% | 取模(求余) | $a % $b | 求$a除以$b的余数 |
** | 求幂 | $a ** $b | 求$a的$b次方 |
递增/递减运算符
PHP 中,前/后递增与递减运算符是一类特殊的一元运算符,它们的作用是对变量的值进行加1或减1的操作。示例如下:
$a = 5;
// 前递增
echo ++$a; // 输出 6,$a 的值变为 6
// 后递增
echo $a++; // 输出 6,$a 的值变为 7
// 前递减
echo --$a; // 输出 6,$a 的值变为 6
// 后递减
echo $a--; // 输出 6,$a 的值变为 5
赋值运算符
除了基本的=
赋值运算符外,PHP还支持一些复合赋值运算符,它们可以简化一些常见的赋值操作:
+=
:加法赋值,例如:$a += 3
等同于$a = $a + 3
。-=
:减法赋值*=
:乘法赋值/=
:除法赋值%=
:取模赋值.=
:字符串连接赋值
引用赋值
引用赋值是一种特殊的赋值方式,它让两个或多个变量指向同一个内存地址。也就是说,这些变量实际上是同一个变量的不同名称。当其中一个变量的值发生改变时,其他指向它的变量的值也会随之改变。语法如下:
$var = &$othervar;
&
符号表示引用。$var
和 $othervar
是两个变量名。
位运算符
位运算符直接作用于整数的二进制表示,对每一位进行操作。由于直接操作硬件,位运算的效率通常比普通的算术运算更高。
位运算可以实现很多有趣的算法,例如:
- 判断奇偶数: 一个数与1做按位与,如果结果为1,则为奇数,否则为偶数。
- 交换两个变量的值: 不用临时变量,通过异或运算可以实现。
- 实现简单的集合操作: 用二进制位表示集合的元素,通过位运算实现集合的交集、并集、补集等操作。
例子 | 名称 | 结果 |
---|---|---|
$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在比较数字和字符串时,会尝试将字符串转换为数字。这种转换遵循以下规则:
- 纯数字字符串: 直接转换为对应的数字。
- 包含非数字字符的字符串: 转换失败,结果为0。
- 空字符串: 转换为0。
严格比较
===
和 !==
运算符进行严格比较,要求比较的两个操作数不仅值相等,数据类型也必须相同。如:
$a = "123";
$b = 123;
if ($a === $b) {
echo "严格相等";
} else {
echo "严格不相等";
}
上述代码中,虽然 $a
和 $b
的值相等,但类型不同,因此 ===
比较的结果为不相等。
PHP 8.0.0之前存在的一些问题
在PHP 8.0.0之前,如果一个字符串以数字开头,即使后面跟着非数字字符,也会被转换为数字。这可能导致一些意想不到的结果。如:
$a = "123abc";
$b = 123;
if ($a == $b) {
echo "相等"; // 在PHP 8.0.0之前会输出相等
}
PHP 8.0.0开始,这种自动类型转换的行为被改变。如果一个字符串包含非数字字符,即使开头是数字,也不会被转换为数字。
错误控制运算符
@运算符,又称错误控制运算符,它的作用是抑制错误信息。当你在一个表达式前加上@符号时,即使这个表达式出现了错误,PHP也不会显示出传统的错误提示,而是将错误“吞掉”。可以在以下场景使用:
隐藏错误: 有时候,你可能不想让用户看到详细的错误信息,而是想提供一个更友好的提示。
避免脚本终止: 一些非致命性的错误,比如文件不存在,你可能只想记录下来,而不希望整个脚本终止。
对于致命的错误(例如语法错误),@运算符是无能为力的。并且@运算符只能放在表达式之前,不能放在函数或类的定义之前,也不能用于条件结构。示例如下:
$my_file = @file ('non_existent_file') or
die ("Failed opening file: error was '" . error_get_last()['message'] . "'");
这段代码尝试打开一个不存在的文件。如果文件不存在,file
函数会产生一个错误,但由于前面加了@符号,这个错误被抑制了。然后,程序会执行or
后面的语句,输出一条自定义的错误消息。error_get_last()
函数用来获取最近发生的错误信息,即使错误被抑制了,也可以通过这个函数获取到。
执行运算符
反引号(``
)是一个特殊的运算符,它用于执行系统命令,并将命令的输出结果作为字符串返回。换句话说,你可以在反引号中写一条shell命令,PHP会将其当作系统命令来执行,然后把执行的结果返回给你。
$output = `ls -la`;
ls -la
: 这是一个Linux/Unix系统中的命令,用于列出当前目录下的所有文件和目录的详细信息。
output
: 一个变量,用于存储命令执行后的输出结果。
反引号与shell_exec()
的区别
两者功能相同,都可以执行系统命令并获取输出。反引号是一种更简洁的写法,而shell_exec()
是一个函数。它们本质上都是通过调用系统的shell来执行命令的。
注:若关闭了 shell_exec() 时反引号运算符是无效的。
逻辑运算符
逻辑运算符用于对一个或多个表达式进行逻辑判断,并返回一个布尔值(true 或 false)。在PHP中,逻辑运算符主要用于控制程序的流程,例如在条件语句(if、else if、else)和循环语句(while、for)中。
例子 | 名称 | 结果 |
---|---|---|
$a and $b | And(逻辑与) | true ,如果 $a 和 $b 都为 true 。 |
$a or $b | Or(逻辑或) | true ,如果 $a 或 $b 任一为 true 。 |
$a xor $b | Xor(逻辑异或) | true ,如果 $a 或 $b 任一为 true ,但不同时是。 |
! $a | Not(逻辑非) | true ,如果 $a 不为 true 。 |
$a && $b | And(逻辑与) | true ,如果 $a 和 $b 都为 true 。 |
$a || $b | Or(逻辑或) | true ,如果 $a 或 $b 任一为 true 。 |
字符串运算符
字符串运算符主要用于对字符串进行操作,最常见的两种是:
- 连接运算符(.): 将两个字符串连接成一个新的字符串。
- 连接赋值运算符(.=): 将右侧的字符串添加到左侧字符串的末尾,并把结果赋值给左侧的变量。
使用例子:
$firstName = "张";
$lastName = "三";
$fullName = $firstName . $lastName; // $fullName 的值为 "张三"
$greeting = "Hello, ";
$greeting .= $fullName . "!"; // $greeting 的值为 "Hello, 张三!"
数组运算符
PHP中的数组运算符主要用于对数组进行合并、比较等操作。与其他编程语言不同,PHP对数组的运算有一些特殊的规则。PHP 中常用的数组运算符及其作用:
运算符 | 名称 | 结果 |
---|---|---|
$a + $b | 联合 | 将数组$b中的元素附加到数组$a的后面,生成一个新的数组。如果两个数组中有相同的键名,则只保留第一个数组中的键值对。 |
$a == $b | 相等 | 判断两个数组是否相等。如果两个数组具有相同的键/值对,则为true。 |
$a === $b | 全等 | 判断两个数组是否完全相等。除了键/值对相同外,还要求键的顺序和值的数据类型也完全相同。 |
$a != $b | 不等 | 判断两个数组是否不相等。只要两个数组不完全相同,就返回true。 |
$a <> $b | 不等 | 与$a != $b相同,表示不相等。 |
$a !== $b | 不全等 | 判断两个数组是否不完全相等。只要键、值、顺序或类型有一个不同,就返回true。 |
示例:
$array1 = array("color" => "red", "shape" => "round");
$array2 = array("shape" => "square", "size" => "large");
$result = $array1 + $array2;
print_r($result); // 输出: Array ( [color] => red [shape] => round [size] => large )
if ($array1 == $array2) {
echo "两个数组相等";
} else {
echo "两个数组不相等";
}
类型运算符
instanceof 运算符是 PHP 中用于判断一个变量是否为某个类的实例(对象)的运算符。简单来说,它可以回答这样的问题:“这个变量是不是由某个特定的类创建出来的?” 如果变量是该类的实例,则返回 true
,否则返回 false
。
// 定义一个名为 MyClass 的类
class MyClass
{
}
// 定义另一个名为 NotMyClass 的类
class NotMyClass
{
}
// 创建一个 MyClass 类的实例
$a = new MyClass;
// 使用 var_dump 输出 $a 是否是 MyClass 的实例
var_dump($a instanceof MyClass); // 输出:bool(true)
// 使用 var_dump 输出 $a 是否是 NotMyClass 的实例
var_dump($a instanceof NotMyClass); // 输出:bool(false)
instanceof
也可用来确定一个变量是不是继承自某一父类的子类的实例。在面向对象编程中,instanceof
是一个非常重要的工具,可以帮助我们实现多态等特性。