凡是运算,必有返回值即运算结果
算术运算符
算术运算符:用于执行两个变量或值的算术运算。
运算符 | 描述 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 获取余数(取余、取模) |
- | 取反 |
取模运算符的用法
- 判断两个数是否可以整除
- 取模运算时,结果正负只和被除数有关,上边是被除数
- 使用 % 方式,来换行显示数据
// 需求 每两个数据换行
$arr = array(1,2,3,4,5,6);
for ($i=0;$i<count($arr);$i++){
echo $arr[$i];
if (($i+1) % 2 == 0){
echo '<br>';
}
}
字符串使用算术运算符
- 字符串怎么能用算术运算符呢? 所以先进行类型转换,如果不能转则为0
- 涉及到自动类型转换的知识点,详见数据类型转换
// 算数运算符,根据上下文先将$a转为float,即$a=12.3,然后运算
$a = "12.3hello99";
$a = $a + 3;
var_dump($a); // float 15.3
自增/自减运算符
注意++a与a++的区别
$a = 1;
echo ++$a; // 2 $a先加1,然后返回$a
$b = 10;
echo $b++; // 10 先返回$b,然后$b加1
$b = 5;
$a = $b++; // $a=$b; $b++; 先返回$b,然后$b自增1
var_dump($a,$b); // a=5 b=6
$b = 5;
$a = ++$b; // $b++; $a=$b; $b先自增1.然后返回$b
var_dump($a,$b); // a=6 b=6
字符串的++运算 (了解)
- 字符串的++运算,会对ascii码进行加1,输出仍未字符串,注意和算数运算符区分
- 字符变量只能递增,不能递减,并且只支持纯字母 (a-z 和 A-Z),递增/递减其他字符变量则无效,原字符串没有变化
$i = 'a' ;
echo ++ $i; // 'b'
$i = 'abc';
echo ++ $i; // 'abd'
布尔型的++运算
- 递增运算对布尔型无效
- 算数运算对布尔型是有效的,先将其转换为0或1
$n = false;
$n++;
var_dump($n); // boolean false
赋值运算符
可以将符号右侧的值赋值给符号左侧的变量
// = += -= *= /= .= %=
$a = 2; // 直接赋值
$b = 5;
$b += $a; // 等价于 $b = $b + $a
$b /= $a;
$b %= $a;
注意:区分传值赋值和引用赋值
比较运算符
比较运算符的返回值结果为布尔型值
$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 |
float 运算后再比较会出现浮点数不精确的问题
- 浮点数直接比较,不含运算没问题
- 如果浮点数运算后比较,就可能出问题
var_dump((0.3-0.2) == 0.1); // boolean false
var_dump((0.8-0.3) == 0.5); // boolean true
/*
10进制 ------- 2进制
0.5 ------------- 0.1
0.8 ------------- 0.1100...
出现以上两种不同结果的原因是,浮点数不精确,某些小数在10进制下,是有限的,转成2进制是无限循环
因此损失一些精度,导致浮点数计算和数学上结果不一致
银行一般存整数,精确到分,来解决此问题
*/
== 和 === 的说明
- == 仅判断值,=== 类型和值都判断
- 用 == 或 != 进行比较时,如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值,并且比较按照数值来进行比较
- 用 === 或 !== 进行比较时不进行类型转换,因为此时类型和数值都要比对
$a = 1;
$b = '1xxx'; // == 比较时 类型转换 $b=1
var_dump($a == $b); // boolean true
var_dump($a === $b); // boolean false
$a = 0;
$b = 'xxx'; // == 比较时 类型转换 $b=0
var_dump($a == $b); // boolean true
var_dump($a === $b); // boolean false
逻辑运算符
逻辑运算符的结果为布尔型值,原值类型不变
逻辑运算符有四个:
&&
与(且):两个都为真,结果才为真||
或:只要有一个是真,结果就是真!
非:对一个布尔值进行取反xor
异或:仅有一个为为真,结果才为真and
与:优先级比&&
和=
低,尽量别用or
或:优先级比||
和=
低,尽量别用
a和b不仅可以是变量,也可以是表达式
$a = true;
$b = 'xxx';
function test(){
return true;
}
var_dump(0+0 and $b); // boolean false $b 仍等于 'xxx';
var_dump(!0.0); // boolean true
var_dump(0+1 xor 1-1); // boolean true 异或 只有一个为真才为真
var_dump(!$a); // boolean false
var_dump(!2); // 先进行数据类型转换 boolean false
var_dump(!test()); // boolean false
逻辑运算的短路特性
- 与操作时,如果前面的逻辑值为false,则后面就不再执行
- 或操作时,如何前面的逻辑值为true,则后面就不再执行
$a = 0;
$b = 1;
if ($a and ($b=10) ){ // $a已经是false就不需要判断$b了 &b被短路,没机会执行
}else {
echo $b, "<br>"; // 1
}
$a = 1;
$b = 0;
if ($a or ($b=10) ) { // &b被短路, 没机会执行
echo $b, "<br>"; // 0
}
逻辑运算短路测试
// 分析: $a++>1类似 $b=$a++,先用$a与1比较,然后$a自增,与运算,前面为false,后面被短路
$a = 1; $b = 10;
if ($a++>1 and $b++>10){
echo 'ok';
}
echo 'a='.$a.'b='.$b; // a=2 b=10
逻辑运算的优先级问题
- 造成不同结果的原因是
||
和or
的优先级不同 - 遇到优先级问题就加括号解决,因为小括号的优先级更高
- 以后优先使用
||
和&&
// 优先级排序: || = or
$a = false || true; // boolean true
$b = false or true; // boolean false
var_dump($a,$b);
// 优先级排序: && = and
$c = true && false; // boolean false
$d = true and false;// boolean true
var_dump($c,$d);
利用短路写的优秀代码
if (!defined("PI")){
define("PI", 3.14);
}
defined("PI") || define("PI",3.14);
echo PI; // 3.14
$a = -10;
$a < 5 && $a=5;
echo $a; // 5
三元运算符
语法:
条件表达式 ? 语句1 : 语句2;
执行的流程:
条件运算符在执行时,首先对条件表达式进行求值:
-
如果该值为true,则执行语句1,并返回执行结果
-
如果该值为false,则执行语句2,并返回执行结果
代码示例:
a b不仅可以是变量,也可以是表达式,函数的调用
// 表达式 (expr1) ? (expr2) : (expr3) 在 expr1 求值为 TRUE 时的值为 expr2,在 expr1 求值为 FALSE 时的值为 expr3
$a = 1;
$b = 2;
$c = 3;
function test($n,$m){
return $n + $m;
}
// 两个数的最大值
$res = $a>$b? $a:$b;
// 三个数的最大值
$res = ($a>$b? $a:$b)>$c? ($a>$b? $a:$b):$c;
三元运算符的经典使用,判断获取的表单数据是否满足条件
- empty 是
""
,"0"
,"0.0"
… 都是 empty - isset 是设置过这个值,并且不为null
- 根据实际情况选择使用,可以用 is_set() && 判断数据合法性,这样更安全
// Example usage for: Ternary Operator
$action = (empty( $_POST [ 'action' ])) ? 'default' : $_POST [ 'action' ];
// The above is identical to this if/else statement
if (empty( $_POST [ 'action' ])) {
$action = 'default' ;
} else {
$action = $_POST [ 'action' ];
}
复杂的三元运算符就加括号
// 乍看起来下面的输出是 'true'
echo ( true ? 'true' : false ? 't' : 'f' );
// 然而,上面语句的实际输出是't',因为三元运算符是从左往右计算的
// 下面是与上面等价的语句,但更清晰
echo (( true ? 'true' : 'false' ) ? 't' : 'f' );
字符串运算符
使用 .
拼接字符串
$a = "Hello " ;
$b = $a . "World!" ; // now $b contains "Hello World!"
$a = "Hello " ;
$a .= "World!" ; // now $a contains "Hello World!"
数字到字符串的自动转换
$a = 123;
$a = $a."hello";
var_dump($a); // string '123hello'
数组运算符
数组运算符的结果为布尔型值
$a + $b | 联合 | $a 和 $b 的联合 |
---|---|---|
$a == $b | 相等 | 如果 $a 和 $b 具有相同的键/值对则为 TRUE |
$a === $b | 全等 | 如果 $a 和 $b 具有相同的键/值对并且顺序和类型都相同则为 TRUE |
$a != $b | 不等 | 如果 $a 不等于 $b 则为 TRUE |
$a !== $b | 不全等 | 如果 $a 不全等于 $b 则为 TRUE |
细节讨论
- +运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的被忽略
- 用 == 或 != 进行比较时,会先进行自动数据类型转换
- 用 === 或 !== 进行比较时不进行类型转换,因为此时类型和数值都要比对
// + 运算符把右边的数组元素附加到左边的数组后面,两个数组中都有的键名,则只用左边数组中的,右边的被忽略
// 注意和 array_merge函数 的区别
$arr1 = array(1, 2, 'age'=>'18');
$arr2 = array(3, 4, 'age'=>'88');
$arr3 = $arr1 + $arr2;
var_dump($arr3); // Array ([0] =>1 [1] =>2 [age] =>18)
print_r($arr3);
// 用 == 或 != 进行比较时,会先进行自动数据类型转换
// 用 === 或 !== 进行比较时不进行类型转换,因为此时类型和数值都要比对
$arr1 = array(1, 2, 3);
$arr2 = array(true, '2', 3);
var_dump($arr1 == $arr2); // boolean true
var_dump($arr1 === $arr2); // boolean false
类型运算符
instanceof 用于判断一个对象是否属于某个类的实例
class A{}
$a = new A();
var_dump($a instanceof A); // boolean true
instanceof 也可用来判断一个对象是不是继承自某个父类的子类的实例
class A{}
class B extends A{}
$b = new B();
var_dump($b instanceof A); // boolean true
var_dump($b instanceof B); // boolean true
instanceof也可用于确定一个变量是不是实现了某个接口的对象的实例
interface A{}
interface B{}
class Dog implements A,B{}
$d = new Dog();
var_dump($d instanceof A); // boolean true
var_dump($d instanceof B); // boolean true
var_dump($d instanceof Dog); // boolean true
执行运算符
将cmd控制台的查询出的数据输出到浏览器页面
header('Content-type: text/html;charset=gbk');
// 执行运算符
echo '<pre>';
echo `netstat -anb`;
echo `ipconfig`;
错误控制运算符
- @ 当将其放置在一个PHP表达式之前,该表达式可能产生的任何错误信息都被忽略掉
- @ 运算符只对表达式有效
- 如果能从某处得到值,就能在它前面加上 @ 运算符,例如,可以把它放在变量,函数调用,常量,等等之前
- 不能把它放在函数或类的定义之前,也不能用于条件结构例如 if 和 foreach 等
- “@”错误控制运算符前缀甚至使导致脚本终止的严重错误的错误报告也失效。这意味着如果在某个不存在或者敲错了字母的函数调用前用了“@”来抑制错误信息,那脚本会没有任何迹象显示原因而死在那里
// @ 一般会配合die使用,即忽略了非致命错误,又可以提示致命错误
$con = @mysql_connect('localhost','root','') or die(mysql_error());
if ($con){
echo 'ok';
}else{
echo 'error';
}
位运算
- 位运算是针对字节上的位来进行运算
- 把位的0/1当成假/真,针对每个位上的逻辑运算,就是位运算
10进制 2进制
5 0000 0101
12 0000 1100
echo 5 & 12; // 0100——>4 【and / &&是逻辑与运算符 &是位运算符 有一个假就为假】
echo 5 | 12; // 1101——>13【or / ||是逻辑或运算符 |是位运算符 有一个真就为真】
echo 5 ^ 12; // 1001——>9 【xor是逻辑异或运算符 ^是位运算符 两个不同才为真】
echo ~5; // 1111 1010——>-6 【1变成0, 0变成1】