运算符是可以通过一个或者多个值来产生另一个值的东西。按照其能接收几个值来分组,一元运算符只能接收一个值,例如递增运算符(++)和取反运算符(!);二元运算符可以接收两个值,例如常见的算术运算符(+,-,*,/,%);还有一个唯一的三元运算符(?:),可以接收三个值。
【1】算术运算符
通常使用算术运算符,操作的变量都会被php转化成数值进行运算。
表示 | 名称 | 结果 |
---|---|---|
-$a | 取反 | $a的负值 |
$a+$b | 加法 | $a 和 $b 的和 |
$a - $b | 减法 | $a 和 $b 的差 |
$a *$b | 乘法 | $a 和 $b 的积,0不能做除数 |
$a / $b | 除法 | $a 除以 $b 的商,0不能做除数 |
$a % $b | 取模 | $a 除以 $b 的余数,0不能做除数 |
// 下面的这种就常规操作,和数学中整数运算差不多
var_dump(5+3);//int 8
var_dump(5-3);//int 2
var_dump(5*3);//int 15
var_dump(5/5);//int 1
var_dump(5%3);//int 2
- 除法运算符总是返回浮点数。只有在下列情况例外:两个操作数都是整数(或字符串转换成的整数)并且正好能整除,这时它返回一个整数。
var_dump(5/5);
var_dump('5'/'5');
var_dump(5.0/5.0);
var_dump(5.0/5);
var_dump(5/3);
//其中前两个,操作结果都是int 1,因为可以转成整数而且两边可以整除。
//第三第四个,操作结果都是float 1,因为两边类型中有float类型的。
//最后一个, 操作结果是float 1.6666666666667,不能整除
- 取模运算符的操作数在运算之前都会转换成整数(除去小数部分)。而且符号问题的话,取模运算符 % 的结果和被除数的符号(正负号)相同。即 $a % $b 的结果和 $a 的符号相同。
var_dump(5%3);//int 2
var_dump(5%-3);//int 2
var_dump(5.5%3);//int 2
var_dump(-5%3.3);//int -2
var_dump(-5%-3);//int -2
【2】递增/递减运算符
类似与c语言,php可以支持前/后递增/递减的运算符。注意:递增递减不影响布尔值,递减null值没有效果,递增null的结果是1。
$a = 1;
echo $a;//1
echo $a++;//1 先输出$a=1 然后$a=$a+1 即$a=2
echo $a--;//2 先输出$a=2 然后$a=$a-1,即$a=1
echo ++$a;//2 先运算$a=$a+1,即$a=2 然后输出
echo --$a;//1 先运算$a=$a-1, 即$a=1 然后输出1
echo $a;//1 最后还是1
$bool=true;
var_dump($bool++,$bool--,--$bool,++$bool);//还是true
$bool=false;
var_dump($bool++,$bool--,--$bool,++$bool);//还是false
$null = NULL;
var_dump($null++,$null--,++$null,--$null);//null 1 1 0
//刚开始$null直接输出null ,然后进行++后 $null=1
//然后直接输出$null=1,然后进行--后,$null=0
//再然后先进行$null=$null+1即$null=1,然后输出
//最后先进行$null=$null-1 即$null=0,然后输出
【3】赋值运算符
基本的赋值运算符是“=”。一开始可能会以为它是“等于”,其实不是的。例如$a=$b,它实际上意味着把右边表达式的值赋给左边的运算数。赋值运算符和算术运算符组合在一起,变成复合运算符(+=,-=,*=,/=,%=,.=),例如$a+=$b,实际上就是$a=$a+$b。
另外赋值运算符是将原变量的值拷贝的新的变量中,也就是传值赋值,两者在赋值之后,互不影响。但是有个例外,就是php中new一个对象object的赋值默认使用的是引用赋值。
php支持引用赋值,使用$a=&$b这样的语法,意味着两个变量指向同一个数据,同一块内存地址,一个发生改变,两者会同时改变,也可以理解起别名。
#传值赋值
$a = 9;//赋值,$a等于9
$b = $a;//把$a的传值赋值给$b,$b等于9
$b += $a;//相当于把$a+$b的值18 再赋给$b
$b .= $a;//$b = $b.$a 把$b的值和$a的值用.连接符结合在一起成字符串了
var_dump($b,$a);//string '189' int 9
//由于是传值赋值,而$a并没有发生改变
#引用传值
$c = 100;
$d = &$c;//引用传值
$d = 0;//两者都改变
var_dump($c,$d);//int 0 int 0
【4】字符串运算符
php中的字符串使用连接符(.)来进行的,或者是(.=),可以将两个字符串拼接到一起。
$a = 'Hello! ';
$b = $a.' Tacks!';
echo $b;//Hello! Tacks!
$a = 'Hello! ';
$a .= 'World ';
echo $a;//Hello! World
【5】比较运算符
比较运算符,也叫做关系运算符或者条件运算符。一般返回值是布尔值,但是php7新增的太空运算符和null运算符 以及三元运算符 除外。
表示 | 名称 | 结果 |
---|---|---|
$a == $b | 等于 | TRUE,如果类型转换后 $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,如果 $a 严格小于 $b。 |
$a > $b | 大于 | TRUE,如果 $a 严格大于 $b。 |
$a <= $b | 小于等于 | TRUE,如果 $a 小于或者等于 $b。 |
$a >= $b | 大于等于 | TRUE,如果 $a 大于或者等于 $b。 |
(expr1) ? (expr2) : (expr3)* | 三元运算符 | expr1 求值为 TRUE 时的值为 expr2,在 expr1 求值为 FALSE 时的值为 expr3。php5.3之后可以简写expr1 ?: expr3 |
$a <=> $b | 太空船运算符 | PHP7开始提供(根据比较返回一个小于或等于或小于0的int值) |
$a ?? $b ?? $c | NULL 合并操作符 | PHP7开始提供。从左往右第一个存在且不为 NULL 的操作数。如果都没有定义且不为 NULL ,则返回 NULL 。 |
- 如果不是全等或者不全等这样强制类型相同的话,默认比较的时候操作符会将两个操作数自动转化成类型相同的,然后进行比较。字符串和数值进行比较,一般都转成数值比较。布尔值或者null 与其他类型比较都会转化成bool。而且true>false。
var_dump("1" == "01"); // 1 == 1 -> true
var_dump(10 == "1e1"); // 10 == 10 -> true
var_dump(100 == 1e2); // 100 == 100 -> true
var_dump(0 == "a"); // 0 == 0 -> true
var_dump("a" == "a");//"a" == "a" -> true
var_dump(true=='a')//true == true ->true
- 看看下面的代码运行结果
switch ("a") {
case 0:
echo "0";
break;
case "a": //不会到达这一步
echo "a";
break;
}
- 三元运算符(?:)
PHP中只有一个三元运算符,其功能类似与if...else...,但是三元运算符使用更佳简洁
$res = !empty($_GET['do'])?$_GET['do']:'default';
echo $res;
//如果没有get传过来参数,那么默认是default,如果$_GET['do'],则去使用它。
【6】逻辑运算符
逻辑运算符通常用来判断一件事情是”成立“还是”不成立“。因此逻辑运算符只能操作布尔型数值,处理后的结果也是布尔类型。虽然说是操作布尔值,但是实际上更多是经过比较运算符后的布尔值,还有经常出现在if条件或者while循环等流程控制中。
表示 | 名称 | 结果 |
---|---|---|
$a and $b | And(逻辑与) | $a和$b都是true,结果才是true |
$a or $b | Or(逻辑或) | $a和$b有一个true,结果就是true |
$a xor $b | Xor(逻辑异或) | $a,$b有且仅有一个true,结果才是true |
!$a | Not(逻辑非) | $a是false,结果就是true |
$a&&$b | And(逻辑与) | $a和$b都是true,结果才是true,优先级高于and |
$a||$b | Or(逻辑或) | $a和$b有一个true,结果就是true,优先级高于or |
- 举个简单例子
//在实际开发中 用&& ||多一些
$username = 'tacks';
$password = '123456';
$power = 1;
if($username == '' || $password== ''){
echo 'they are no empty!';
}else if($username=='tacks' && $password=='123456' ){
if(!$power){
echo 'you not have permission!';
}else{
echo 'you are okay!';
}
}
- “短路效应”
$name = 'root';
$age = 0;
if(($name='tacks') || ($age=20)){
echo $name,' ',$age;//tacks 0
}
//由于if里面第一个小括号里面是赋值语句,结果为true,而后面的用||逻辑或,那么后面的表达式就会被忽略
$res = ($name=='tacks') && ($age=20);
var_dump($res,$age);//false 0
//由于表达式中用的&&逻辑与,那么必须两个都是true,可是左边的结果是false,所以后面的表达式就会被忽略
- 实例
//如果使用逻辑或or,前面的数据库连接不成功,则会执行die输出错误信息退出程序,如同||一样
$conn = mysqli_connect('localhost','root','') or die('连接数据库失败');
//如果使用逻辑或||,前面的文件打开不成功,则会执行die输出错误信息退出程序,如同or一样
$fd = fopen('test.txt','r')||die('文件打开失败');
【7】位运算符
任何信息在计算机中都是以二进制形式保存的,位运算符可以对整数中指定的位进行置位。如果左右两个参数都是字符串,则位运算符则操作字符的ASCII值;浮点数也会自动转化成整型再参加位运算。
位运算虽然可以用与对操作数中每个二进制位进行运算,可以完成一些底层的系统程序设计,但是在程序开发中很少用到这些。
注意:位运算时的数据类型为string/int,分析时要转化二进制形式进行,但是程序中书写以及输出结果时,还是string和int类型。
表示 | 名称 | 结果 |
---|---|---|
$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”)。 |
- <<和>>
$a = 2;
echo $a<<3;//相当于2乘以2的三次方
$b = 64;
echo $b>>3;//相当于64除以2的三次方
- &运算中 0&0=0,0&1=0,1&0=0,1&1=1,都是1按位与才为1
$a = 8;//8->1000
$b = 7;//7-> 111
echo $a&$b;//0000->0
- |运算中 0|0=0,0|1=1,1|0=1,1|1=1,只要有一位1按位或就是1
$a = 8;//8->1000
$b = 7;//7-> 111
echo $a|$b;//1111->15
- 位运算符中按位与&和按位或|作为逻辑判断时候不存在短路问题
$bool = false;
$num = 10;
$res = $bool & (++$num>10);//因为$bool已经是false所以结果一定是0,但是后面的仍然会执行
var_dump($res,$num);//int 0 int 11
$bool = true;
$num = 10;
$res = $bool | (++$num>10);//因为$bool已经是true所以结果一定是1,但是后面的仍然会执行
var_dump($res,$num);//int 1 int 11
- 实例
php的ini设定 error_reporting使用按位的值,提供关闭某个为的真实例子,要显示出来除了提示级别之外的所有错误可以使用E_ALL & ~E_NOTICE相当于E_ALL^E_NOTICE。
【8】执行运算符
PHP 支持一个执行运算符:反引号(``)。注意这不是单引号!PHP 将尝试将反引号中的内容作为 shell 命令来执行,并将其输出信息返回(即,可以赋给一个变量而不是简单地丢弃到标准输出)。其作用和shell_exec()函数差不多。
其中使用的命令是根据操作系统决定的,不同的系统下,命令有所不同。为了保证开发时候程序可以跨平台和系统安全,在开发时候尽量不用反引号去调用操作系统命令。
$res = `dir`;//window下的cmd命令
echo "<pre>$res</pre>";
【9】错误控制运算符
PHP 支持一个错误控制运算符:@ 当将其放置在一个 PHP 表达式之前,该表达式可能产生的任何错误信息都被忽略掉。仅仅对表达式起作用,例如变量,函数调用,常量,等等。不能把它放在函数或者类定义前面,也不能放在if或者foreach前面。
$fd = @file('no_file.text');//打开一个不存在的文件,会产生警告,可以用@屏蔽
var_dump($fd);//false
@$num = 10/0;//0不能做除数 用@忽略错误
var_dump($num);//false
【10】数组运算符
指的是两个数组进行运算,+运算符把右边的数组元素附加到左边数组后面,如果两个数组都有的键名,则只用左边的,右边的会被忽略。
表示 | 名称 | 结果 |
---|---|---|
$a + $b | 联合 | $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 |
$a = ['a'=>'appale','b'=>'banana'];
$b = ['a'=>'pear','b'=>'strawberry','c'=>'cherry'];
$c = $a + $b;
var_dump($c);//c数组的值['a'=>'appale','b'=>'banana','c'=>'cherry']
$d = $b + $a;
var_dump($d);//d数组的值['a'=>'pear','b'=>'strawberry','c'=>'cherry']
//数组中的单元如果具有相同的键名和值则比较时相等。
$a = ['one','two'];
$b = [1=>'two','0'=>'one'];
var_dump($a == $b); // bool(true)
var_dump($a === $b); // bool(false)
【11】类型运算符
-
instanceof用于确定一个 PHP 变量是否属于某一类class实例。
class People{}
class Animal{}
$obj = new People;
var_dump($obj instanceof People);//boolean true
var_dump($obj instanceof Animal);//boolean false
-
也可用来确定一个变量是不是继承自某一父类的子类的实例
class People{}
class Student extends People{}
$obj = new Student;
var_dump($obj instanceof Student);//boolean true
var_dump($obj instanceof People);//boolean true
-
检查一个对象是否不是某个类的实例,可以结合逻辑运算符逻辑非not(!)
class People{}
$obj = new People;
var_dump(!($obj instanceof Animal));//boolean true
-
还可以用来确定变量是否实现某个接口
interface Universe{}
class Earth implements Universe{}
$obj = new Earth;
var_dump($obj instanceof Earth);//boolean true
var_dump($obj instanceof Universe);//boolean true
运算符的优先级
所谓的优先级,就是先执行哪一个运算符,要是一个表达式中出现好多种运算符,该怎么执行?默认是从左向右看,根据每种运算符不同,执行循序不同。就如同小学的数学运算,加减乘除。另外我们可以通过小圆括号进行优先运算。详情可以看官网给出的优先级顺序https://secure.php.net/manual/zh/language.operators.precedence.php。实际上在自己写代码的时候最好加上小圆括号,可以提交代码的可读性。
$a = 3 * 3 % 5; // (3 * 3) % 5 = 4
$a = true ? 0 : true ? 1 : 2; // (true ? 0 : true) ? 1 : 2 = 2
$a = 1;
$b = 2;
$a = $b += 3; // $a = ($b += 3) -> $a = 5, $b = 5