7、运算

目标:了解PHP中运算符的分类

提问:PHP中拿到了各种数据之后,是用来干什么的?

回答:运算

概念

运算符:是PHP中的一些特殊符号,系统会自动根据这些特殊符号,将数据进行相应的运算

PHP中运算符有很多种:

  • 赋值运算符:赋值操作
  • 算术运算符:算术计算
  • 错误抑制符:抑制报错
  • 比较运算符:数据对比
  • 合并运算符:真伪判定给出不同结果
  • 逻辑运算符:逻辑结果判定
  • 连接运算符:字符串连接
  • 三目运算符:真伪判定给出不同结果
  • 自操作运算符:简化操作

步骤

1、确定当前需要使用到的运算符号

2、根据运算符号的规则确定需要参与的表达式个数

3、将对应的表达式和符号按照正确的顺序排列好即可

示例

#PHP变量赋值本质
#1、赋值符号为=
#2、赋值符号确定=左边为一个变量名,右边为一个产生结果的表达式
#3、排列

#给变量$a赋值一个常数10
$a = 10;
$b = 1 + 1;

小结

1、运算符是系统提供的一类特殊符号,能够让系统对数据进行相关加工操作

2、PHP中运算符种类繁多,我们可以根据实际的需要进行选择

  • 赋值运算符:赋值操作
  • 算术运算符:算术计算
  • 错误抑制符:抑制报错
  • 比较运算符:数据对比
  • 合并运算符:真伪判定给出不同结果
  • 逻辑运算符:逻辑结果判定
  • 连接运算符:字符串连接
  • 三目运算符:真伪判定给出不同结果
  • 自操作运算符:简化操作
  • 位运算符:根据计算机最小单位 bit位 进行运算(不多讲)

3、运算符的运算规则

  • 确定要使用到的运算符(做什么运算)
  • 确定运算符需要的表达式数量和性质
  • 按照顺序将表达式和运算符排列好

7.1、赋值运算

目标:了解赋值运算符的作用,以及常用的几种赋值运算

概念

赋值运算:将运算符右边的结果赋值给左边的符号,通过访问左边的符号即可得到右侧的结果

  • PHP中使用 = 进行赋值
  • 赋值运算要求左边是能够存储数据的符号(变量、常量),右边是一个有结果的表达式(值、有结果的计算过程)

PHP中赋值运算符有以下几种:

  • =:普通赋值
  • +=|-=|*=|/=|%=:先将左边的符号与右边的表达式进行相应的操作(%是取余),然后赋值给左边
  • .=:先将左边的符号的结果与右边的结果进行字符串连接(.是字符串连接符),然后赋值给左边

示例

#普通赋值
$a = 10;
$b = 20;
$c = 'string';

#复合赋值
$a += 10;        #表示$a = $a + 10; 先将$a + 10,然后将结果赋值给$a
$c .= 'hello';    #表示$c = $c . 'hello'

注意

  • 复合赋值运算是将左侧与右侧的整体结果进行运算
$a = 10;
$a -= 100 - 90;

#以上右侧的结果是100 - 90 = 10,所以整体结果应该是$a = $a - (100 - 90) = 10
#错误理解: $a = $a - 100 - 90 = -180
  • 当复合赋值是/=或者%=的时候,右侧的结果不能为0
$a = 10;
$a /= 0;        #错误:等价于$a = $a / 0 = 10 / 0 = 无限大

小结

1、赋值运算的基本符号是 =,也是程序语言中最基本的运算符

2、赋值运算分为两类

  • 基本赋值:=,右侧结果赋值给左侧存储数据的符号
  • 复合赋值:+=|-=|*=|/=|%=|.=,先将左侧数据符号代表的数据与右侧==结果==进行相应运算后赋值给左侧符号

3、复合赋值运算时要注意 /=%= 运算时,右侧结果不能为0

7.2、算术运算

目标:了解算术运算符的作用,并掌握算术运算的运算规则

概念

算术运算:实现两个数据的算术运算

  • 普通算术运算,需要符号左右两边都是数值
  • +:加法运算,左右两边相加
  • -:减分运算,左边减去右边
  • *:乘法运算,左边乘以右边
  • /:除法运算,左边除以右边(右边不能为0)
  • %:取余运算(模运算),左边除以右边,保留整数部分结果(右边不能为0)
  • **:幂运算,PHP7后新增,底数的指数次相乘
  • *、/、%的优先级比+、-的要高
  • 相同优先级的情况下,从左往右开始运算

示例

#算术运算
$a = 10;
$b = 8;

#加减乘除取余基本运算
$c = $a + $b;        #$c = 10 + 8 = 18
$d = $a / $b;        #$d = 10 / 8 = 1.25
$e = $a % $b;        #$e = 10 % 8 = 1(1.25取整数部分)

#幂运算
$f = $a ** 2;         #$f = 10 * 10 = 100

#运算符优先级
$g = 10 + 10 / 10;     #$g = 10 + 1 = 11

注意

  • 除法运算 / 和取余运算 % 的右侧都不能为0
  • 如果有多个表达式参与复合运算,那么可以使用 () 来提升优先级
$f = (10 + 10) / 10;    #$f = 20 / 10 = 2

小结

1、算术运算是进行数学的算术操作

2、算术运算包含+、-、、/、%、*六种操作

3、运算符有优先级

  • *、/、%优先级比+、-要高
  • 相同级别的优先级,从左往右开始运算
  • 可以使用 () 来提升优先级

7.3、错误抑制

目标:了解错误抑制符的作用,灵活运用错误抑制符来实现可能出现的错误的抑制

提问:当进行算术运算的时候如果除数为0就错了,该怎么控制呢?

回答:数据判断或者暴力错误抑制

概念

错误抑制:在可能出现的错误的代码前使用错误抑制符,让错误不会报出来

  • 错误抑制只需要在可能出现的错误的表达式之前使用即可
  • 错误抑制符只有一个:@
  • 错误抑制符只针对就近的目标,如果是针对结果,需要使用()(优先级考虑)
  • 错误抑制符只能抑制简单错误(notice、warning)

示例

#正常处理
$r = 10 / 0;        #报错:除数为0

#错误抑制处理
$r = @10 / 0;        #报错:出错的位置是 10 / 0 这个过程 ,抑制的位置是10,无意义

#正确处理
$r = @(10 / 0);        #不报错:因为是过程出错

小结

1、错误抑制符是用来抑制可能出现的错误的

  • 抑制级别:notice、warning低级别错误

2、错误抑制符@应该用在出现错误的位置

  • 如果只是一个表达式错误:那么直接@
  • 如果错误是一个过程:那么需要先将过程使用()包起来,然后进行抑制

7.4、比较运算

目标:了解比较运算的意义和工作原理,掌握常用比较运算符的使用

提问:如何知道两个数据的大小呢?

回答:比较运算

概念

比较运算:比较两个数据的大小或者长度,然后得出比较结果

  • 用于两个表达式的比较,比较的结果通常是true或者false
  • > :左边大于右边返回true,否则返回false
  • <:左边小于右边返回true,否则返回false
  • >=:左边大于或者等于右边返回true,否则返回false
  • <=:左边小于或者等于右边返回true,否则返回false
  • <=>:左边大于右边返回1,等于右边返回0,小于右边返回-1
  • ==:左边等于右边返回true,否则返回false
  • !=:左边不等于右边返回true,相等返回false
  • ===:左边等于右边,且两边数据类型一致返回true,否则返回false
  • !==:左边不全等于右边返回true,否则返回false

示例

#定义数据
$a = 10;                  #数字10
$b = 5;
$c = '10';                #字符串10

#基本比较运算
$res = $a > $b;
var_dump($res);           #布尔true:10 > 5,成立

#全等运算
$res = ($a == $c);
var_dump($res);           #布尔true:10 与 '10'系统自动会转换成相同的格式比较,都是10,所以相等

$res = ($a === $c);
var_dump($res);            #布尔false:10与10值相同,但是10是数字,'10'是字符串,类型不同

#飞船运算
var_dump($a <=> $c);       #0:相等,10与10值相同,类型不同不影响

注意:在PHP中比较运算比较特殊,通常系统会自动将类型转换成相同的然后进行比较,所以大家在使用==和===比较的时候,如果自己不够明确可以参照PHP操作手册中的类型比较表:PHP操作手册->附录->PHP类型比较表。

类型比较

小结

1、比较运算就是比较两个数据的区别

2、飞船运算包含了大于、等于和小于三种运算

3、比较运算的结果普遍是true和false,飞船运算符的结果除外

4、比较运算通常在实际开发中用于判定数据的有效性

  • 数值有大小可比较
  • 字符串:比较对应的ASCII值

    • 大小写比较ASCII值
    • 如果是相同字符串,谁第一个不同的大谁赢

5、PHP在进行比较时,会自动将不同类型转换成同一类型进行比较,所以这块需要特别注意

  • 松散比较 == :只比较值即可
  • 严格比较 === :值和类型都比较

7.5、合并运算

目标:掌握合并运算的操作,以及合并运算符的实际运用

提问:用户提交数据时,我们怎么确定用户提交了数据呢?

回答:判定或者合并运算

概念

合并运算:合并运算是用于简单的数据存在性判定,不存在的时候给出一个设定值

  • 合并运算需要一个判定:目标
  • 合并运算需要一个设定值:目标不存在的时候的值
  • 合并运算符: $a ?? B

    • $a存在,整个表达式返回$a的值
    • $a不存在,整个表达式返回B值
  • 合并运算是保证代码的逻辑完整性:即总是有一个结果(不会不存在)

示例

#假设用户是通过POST方式提交数据
$gender = $_POST['gender'];

#上述代码如果用户没有提交gender,那么会报错,我们可以通过合并运算符给定目标值
$gender = $_POST['gender'] ?? '男';    #用户提交了取$_POST的值,没有提交取gender

小结

1、合并运算符是 ??

2、合并运算符是针对数据存在的判定

  • 存在结果:取原始结果
  • 不存在结果:使用替代结果

3、合并运算在进行一些数据获取时,如果数据不是那么重要的情况下使用(如果数据非常重要,那么就必须让用户提交,而不是给默认值)

7.6、连接运算

目标:了解连接运算的实际应用

概念

连接运算:专门为字符串连接操作设定的运算符

  • 连接运算需要两个数据的参与
  • 连接运算符只有一个: . 英文点
  • 连接运算是将两个字符串连接成一个字符串

    • 如果数据本身不是字符串,系统会自动转变成字符串

示例

$a = 'hello ';
$b = 'world';

echo $a . $b;        #将$a和$b连接起来,然后一次性输出:hello world

注意:在进行连接运算时,如果有其他运算,最好将其他运算使用 () 包起来(提升优先级)

# +、-和.优先级一样,所以是先左后右
echo 'hello' . 5 + 5;            #5,同时报错:先算的hello . 5,编程hello5,然后去+5

#正确处理
echo 'hello' . (5 + 5);            #hello10,不出错

小结

1、连接运算是针对字符串连接使用的

2、连接运算符使用 . 实现

3、连接运算会将符号两边的数据先转换成字符串后运算

4、连接运算与其他运算符一起使用时,要主要运算符的优先级带来的问题

7.7、三目运算

目标:了解三目运算的逻辑,掌握三目运算符的应用

概念

三目运算:即有三个表达式参与运算的运算,是一种简单的判定以及给出结果的运算

  • 三目运算:需要三个表达式参与运算
  • 三目运算: 表达式1 ? 表达式2 : 表达式3

    • 如果表达式1为真:返回表达式2的结果
    • 如果表达式1为假:返回表达式3的结果
  • 三目运算简化:表达式1 ?: 表达式3

    • 如果表达式1为真:返回表达式1的结果(等价于: 表达式1 ? 表达式1 : 表达式3)
    • 如果表达式1为假:返回表达式3的结果

示例

#年龄大于等于18岁,可以上网,否则不能上网
$age = 15;

$res = $age >= 18 ? '上网' : '不能上网';
echo $res;        #上网:因为$age >= 18结果为真

#用户提交数据:如果有就用,没有就给初始值
$res = $_GET['age'] ?: 18;            #等价于合并运算:$res = $_GET['age'] ?? 18

三目运算是可以多个嵌入到一起的(不建议),如果有这种情况要特别注意,最好使用() 将子三目运算包起来

#年龄小于18岁,未成年,大于18岁,小于30岁,青年,大于30,小于65,中年,大于65,老年
$age = 19;

#错误示例:自己看不懂,程序也看不懂
$res = $age >= 18 ? $age > 30 ? $age > 65 ? '老年' : '中年' : '青年' : '未成年';

#调整,每个子三目运算都进行包裹
$res = $age >= 18 ? ($age > 30 ? ($age > 65 ? '老年' : '中年') : '青年') : '未成年';

小结

1、三目运算标准需要三个表达式参与运算:表达式1 ? 表达式2 : 表达式3

  • 表达式1成立:得到表达式2的结果
  • 表达式1不成立:得到表达式3的结果

2、简化的三目运算与合并运算一样(合并运算在PHP7以后有的,就是为了简化三目运算)

  • 表达式1 ? : 表达式3 ==== 表达式1 ?? 表达式3(不完全等价:三目运算是判定表达式1的结果是否为真,而合并运算是判定表达式1是否存在)

3、三目运算理论上可以无限嵌套,但是要注意对子三目运算的包裹(不建议使用)

7.8、逻辑运算

目标:了解逻辑运算的概念,掌握逻辑运算符的原理及应用

概念

逻辑运算:是针普通运算的结果的二次运算

  • 逻辑运算一般需要1个或者2个表达式参与
  • &&:逻辑与运算(也作and),左右两边结果都为true返回true,否则返回false
  • ||:逻辑或运算(也作or),左右两边结果至少有一个true返回true,否则返回false
  • !:逻辑非运算,原来结果为true返回false,原来结果为false返回true
  • 逻辑运算(逻辑与和逻辑或)也称之为短路运算:即左边表达式如果已经能够确定结果,那么右边表达式就不再判定

    • 逻辑或:如果左边第一个表达式已经为真,第二个表达式就不会运算(结果为真)
    • 逻辑与:如果左边第一个表达式已经为假,第二个表达式就不会运算(结果为假)
  • 运算原理:将所有表达式的结果转换成布尔结果之后再进行运算

示例

#简单示例
$a = true;
$b = false;

#逻辑运算
var_dump($a || $b);            #true,因为$a为true,所以整个结果为true
var_dump($a && $b);            #false,因为$b为false,所以整个结果为false
var_dump(!$a);                #false,因为$a为true,取反得到false

#通常参与逻辑运算的同时会有其他运算参与
$age = $_POST['age'];

$res = $age < 18 || $age > 65;        
#先执行左侧的$age < 18比较运算
#后执行右侧的$age > 65比较运算
#两个比较结果进行 || 逻辑运算

#短路验证
$a = 100;
$a == 100 || $b = 10;    #案例:实际开发不要出现运算中赋值

/*
 1、比较左边:$a == 100,结果为true
 2、发现是逻辑或运算:结果已经出来:true
 3、忽略$b = 10运算
*/
var_dump($b);            #未定义的变量

小结

1、逻辑运算符有三种: && 逻辑与、|| 逻辑或、!逻辑非

  • && :两个表达式都为真结果才为真,其他为假
  • || :两个表达式都为假结果才为假,其他为真
  • ! :一个表达式,对本身布尔结果取反

2、 逻辑运算是对布尔结果进行比较

  • 本身就是布尔结果:直接运算
  • 本身非布尔结果:自动转换成布尔结果后再运算

3、逻辑运算通常与其他运算结合在一起运算

4、逻辑与和逻辑或也称之为短路运算

  • 逻辑与:第一个为假,第二个不运算(短路)
  • 逻辑或:第一个为真,第二个不运算(短路)
  • 在实际开发中,应该将大概率能判定整个结果的运算放前面

5、逻辑运算在实际开发的时候运用比较多,尤其是逻辑复杂的程序

7.9、自操作运算

目标:了解自操作运算的原理,掌握自操作运算的应用

概念

自操作运:针对一个变量的自我操作运算,能够让变量实现自我按规矩改变

  • 自操作运算只需要一个变量即可完成
  • 自操作运算分为两种

    • ++:变量自增,即自己加1,然后赋值给自己
    • --:变量自减,即自己减1,然后赋值给自己
  • 自操作符号分前置和后置:前后置的区别运用是在参与其他运算时体现

    • 前置自操作符:先运算自己、改变自己,然后把改变后的结果去参与其他运算
    • 后置自操作符:先把自己当前的值保留去参与其他运算,然后运算自己、改变自己
  • 自操作在变量都是变化1的时候,而且需要重复执行时用到

    • 年龄:每年自增1
    • 寿命:每年自减1

示例

简单自操作运算

#变量赋值:多个同时赋值
$a = $b = 10;    

$a++;        #等价于: $a = $a + 1
echo $a;    #11

++$b;        #等价于: $b = $b + 1
echo $b;    #11
#独立运算,前置与后置没有区别

前后置区别(虚岁生日和实岁生日):参与其他运算

$a = $b = 0;        #刚出生

#虚岁生日
echo '我今年:',++$a,'岁';    #我今年1岁:前置先改变自己,后参与运算

#实岁生日
echo '我今年:',$b++,'岁';    #我今年0岁:后置先参与运算,后改变自己

#最终$a和$b都变成了1

小结

1、自操作包含 ++-- 都是一个变量参与的改变运算,每次都改变1

2、自操作运算包含前置运算和后置运算

  • 前置自操作:先改变自己、后参与运算
  • 后置自操作:先参与运算、后改变自己
  • 条件:前后置的区别需要运算本身还要参与到其他运算

    • 输出
    • 算术运算
    • 连接运算

3、自操作运算是有规律的自增1或者自减1,实际在循环时会经常用到(循环条件的变更)

7.10、运算符优先级

目标:了解运算符的优先级,懂得使用()来提升复杂运算的优先级别

概念

运算符优先级:多种运算符结合一起运算时,系统会根据不同的优先级进行优先运算,从而导致运算结果不可预知

运算符优先级

图中,从上到下依次优先级降低(部分运算符没讲,略过)

示例

在不确定表达式中优先级顺序的时候,使用()来保证对应的运算不会被其他优先级高的所拆分

$a = 10 + 5 * 2 / 10 % 3;    #11,因后续运算符都比+号高
$a = (10 + 5) * 2 / 10 % 3;    #0

小结

1、运算符优先级是系统提供的一种结合模式,优先级高的先结合,级别低的后结合

2、为了保障目标运算不被其他优先级高的影响,可以通过()来实现包裹

Last modification:February 11th, 2020 at 07:12 pm