深入解析PHP表达式:变量、常量与运算符的全面指南
PHP表达式是PHP程序中最重要的部分。 PHP表达式是指使用运算符号按照一定规则连接起来的相同数据类型或不同数据类型(如变量、常量、函数等)的数据。有意义的公式。本章以表达式为中心,详细讲解表达式中涉及的变量、常量和常用运算符,最后讨论表达式中数据类型之间的转换。

3.1 常数
PHP有时会使用常量在内存中存储数据,并使用常量名称通过名称来访问内存数据。常量是指在程序运行过程中保持不变的量。常量一旦定义,其值和数据类型将不再改变。 PHP常量分为自定义常量和预定义常量。
3.1.1 自定义常量
自定义常量必须在使用前定义。 PHP的define()函数专门用于定义自定义常量。 Define()函数的语法格式为:define(name, value[, boolean case_insensitive])。
函数功能:定义一个常量,名称为name,值为value。 case_insensitive参数的默认值为FALSE,表示常量名区分大小写(case-sensitive);如果case_insensitive参数值为TRUE,则表示常量名不区分大小写(不区分大小写)。
函数说明:常量名称name为字符串类型数据,常量值value必须为标量数据类型数据。
例如,程序define.php如下。
定义和使用常量时请注意以下几点。
(1) 常量必须使用define()函数定义,常量名前面不能有前缀“$”。
(2) 常量名称以字母或下划线开头,后跟任意数量的字母、数字或下划线。
(3) 常量名称可以是全大写、全小写或混合大小写,但一般约定是全大写。
(4)常量的作用范围是全局的,不存在使用范围的问题。常量可以在程序中的任何位置定义和使用。
(5) 常量一旦定义,其值在程序运行过程中就不能修改,也不能被破坏。例如,程序defineError.php如下。该程序的运行结果如图3-1所示。
由于程序defineError.php 尝试修改定义的常量DATABASE 的值,因此程序会生成一条Notice 消息。从程序的运行结果可以看出,PHP生成Notice信息后,不会影响程序的继续运行。
3.1.2 常量内存分配
内存中分配了一块空间专门用于存储常量:常量存储区。常量存储区是一个比较特殊的存储空间。位于该存储空间中的常量是全局的,在程序运行过程中不能被修改或破坏。程序define.php运行时的内存分配图如图3-2所示。
3.1.3 预定义常量
PHP预定义了很多常量,可以直接在程序中使用,无需使用define()函数。下面列出了一些常用的 PHP 预定义常量。
(1)FILE(FILE前后各有两个下划线):当前正在处理的脚本文件的名称,如果用在引用的文件中(include或require),那么它的值就是被引用的文件,而不是引用的文件它。
(2)LINE(LINE前后各有两个下划线):正在处理的脚本文件的当前行号。
(3) PHP_VERSION:当前PHP预处理器版本,如5.3.0。
(4) PHP_OS:PHP所在操作系统的类型,如Linux。
(5) TRUE:表示逻辑正确。 FALSE:表示逻辑假。 NULL:表示没有值或者值不确定。
(6)DIRECTORY_SEPARATOR:表示目录分隔符。在UNIX或Linux操作系统环境下该值为“/”,在Windows操作系统环境下该值为“\”。例如,程序preDefined.php如下。
3.2 变量
PHP更经常使用变量在内存中存储数据。变量是 PHP 表达式中最重要的组成部分。 PHP变量可以分为自定义变量和预定义变量。本章讨论的变量是自定义变量。
3.2.1 变量的基本概念
变量是用于临时存储数据的容器,数据可以是任何数据类型。变量通过变量名实现对内存数据的基于名称的访问。 PHP 中的变量名称遵循以下规则。
(1)变量名必须以美元符号($)开头,如$userName
(2) 变量名的第一个字符必须是字母或下划线(不能是数字)。变量名可以是字母、数字和下划线的组合,例如$user_name_1。
(3) PHP中的变量名区分大小写。这是一个非常重要的规则。这意味着 $userName 和 $UserName 是两个完全不同的变量。
与传统的高级语言不同,在PHP中,定义的变量的值可以通过重新赋值来修改,甚至可以修改变量的数据类型。例如,程序variable.php如下。
3.2.2 变量的内存分配
除了专门用于存储常量的常量存储区域外,还有一个用于存储变量的堆栈空间。栈是一种数据结构,是一种特殊的线性链表,只能在一端进行插入和删除。栈按照后进先出的原则存储数据。最先进入的数据被压入栈底,最后进入的数据在栈顶。栈底是固定的,栈顶是浮动的。插入元素的过程称为PUSH,删除元素的过程称为弹出(POP)。堆栈的逻辑结构如图3-3所示。程序variable.php运行时的内存分配图如图3-4所示。
(1) 当程序准备执行时,存储器处于初始状态。此时栈内存和内存中都没有数据。
(2) 当程序执行到语句“$userName = “张三”;”时,调用进程1。进程1结束后,变量$userName和对应的值“张三”会被添加到栈内存中,记忆。
(3) 当程序执行到语句“$userName = “李思”;”时,调用进程2。经过进程2,变量$userName对应的值“李思”就会被添加到内存中。
(4)此后,由于内存中的“张三”数据没有被其他变量名引用(指向),因此“张三”将被视为垃圾数据,并在该处被PHP垃圾收集机制回收。 “适当”时刻以节省内存开支。这个过程称为过程3。
(5) 当程序执行到“$sex = FALSE;”时语句中,称为进程4。进程4结束后,变量$sex和对应的值FALSE会被添加到栈内存和内存中。
(6) 当程序执行到语句“$sex = “male”;”时,调用进程5。进程5之后,变量$sex对应的值“male”将被添加到内存中。
(7)由于FALSE在内存中没有被其他变量名引用(指向),因此FALSE将被视为垃圾数据,并会在“适当”的时刻被PHP垃圾收集机制回收,以节省内存开支。该过程称为过程6。
(8) 程序variable.php中的所有代码执行完毕后,PHP垃圾回收机制首先回收位于栈顶的变量$sex。这个过程就是过程7。
(9) 最后,PHP垃圾回收机制回收位于栈底的变量$userName。这个进程就是进程8。进程8之后,内存又回到初始状态,准备运行其他PHP程序。
3.2.3 变量赋值方法
变量赋值是指将具体的数据赋值给变量,这是通过赋值运算符“=”来实现的。 PHP提供了两种赋值方式:按值赋值和按地址赋值。
1. 传值赋值
之前的所有程序都使用按值传递赋值方式为变量赋值,即将值的“副本”分配给变量。例如,程序byValue.php如下。程序运行过程中的内存分配图如图3-5所示。
图3-5的部分描述如下。
(1)当程序执行“$age2 = $age1;”时语句,称为进程2。进程2之后,变量$age2的变量值18没有添加到内存中。这是因为PHP为了提高内存使用效率,采用了“copy-on-write”的原则来给变量赋值。总之,除非发生写(或修改)操作,否则指向同一地址的变量值或对象不会被复制,这不仅节省了内存,还提高了代码的执行效率。
(2)当程序执行“$age2 = 20;”时语句,称为进程3。进程3之后,变量$age2的变量值20被添加到内存中。
2. 传递地址分配方法
按地址赋值就是将源变量的内存地址赋给一个新变量,即新变量引用源变量的值。更改新变量的值将影响源变量的值,反之亦然。按地址赋值意味着两个变量都指向同一个数据,并且没有任何数据的复制过程。 PHP 通过在源变量 ($oldVariable) 前附加“&”符号来实现基于地址的赋值。语法格式为:$newVariable = &$oldVariable。例如,程序byReference.php如下。程序运行过程中的内存分配图如图3-6所示。
图3-6的部分描述如下。
(1) 当程序执行到“$age2 = &$age1”时;语句中,称为进程2。进程2之后,变量$age2和变量$age1指向内存中同一个变量值18。
(2) 当程序执行到“$age2 = 20”时;语句中,称为进程3。进程3之后,变量$age2和变量$age1指向内存中同一个变量值20。
3.2.4 可变变量
PHP 提供了一种特殊类型的变量:可变变量。可变变量允许 PHP 程序动态更改变量的变量名。可变变量的工作原理是使用一个变量的“值”作为另一个变量的“名称”。例如,程序variableNameChanged.php如下。
3.3 与变量或常量状态相关的函数
PHP 数据作为变量或常量存储在内存中。 PHP提供了判断和修改变量或常量状态的函数。
3.3.1 数据类型查看功能
PHP 提供了用于查看变量或常量的数据类型的函数,包括 gettype() 和 var_dump() 函数。
1. gettype()函数
语法格式:string gettype (mixed var)
函数功能:gettype()函数需要一个变量名(带$符号)或一个常量名作为参数。该函数返回变量或常量的数据类型。这些数据类型包括:整数、双精度、字符串、数组、对象、未知类型(unknown type)数据类型)等。
2.var_dump()函数
语法格式:void var_dump(混合变量)
函数功能:var_dump()函数需要传递变量名(带$符号)或常量名作为参数。该函数可以获取变量或常量的数据类型以及相应的值,并输出该信息。
函数说明:void表示函数var_dump()函数没有返回值。调试程序时,常使用var_dump()函数查看变量或常量的值、数据类型等信息。例如,程序dataType.php如下。
3.3.2 检查常量或变量是否定义了函数 1. Defined() 函数
语法格式:bool Defined(字符串名称)
函数功能:检查常量是否由define()函数定义。函数参数是一个常量名(注意常量名必须用双引号或单引号括起来)。如果常量是由define()函数定义的,则该函数返回布尔值TRUE,否则返回FALSE。例如,程序define.php如下。该程序的运行结果如图3-7所示。从运行结果可以看出,如果一个常量(如STUDENT)不是通过define()函数定义的,则该常量的值为常量名字符串。
2.isset()函数
语法格式:bool isset(混合变量)
函数功能:检查变量var是否定义。函数参数是变量名(带$符号)。如果变量已经定义,函数返回布尔值TRUE,否则返回FALSE。例如,程序isset.php如下。该程序的运行结果如图3-8所示。
3.3.3 取消变量定义unset()函数
unset() 函数语法格式:void unset (mixed var)
函数功能:取消变量var的定义。该函数的参数是变量名(带$符号),函数没有返回值。例如,程序unset.php如下。程序运行结果如图3-9所示。程序运行过程中的内存分配图如图3-10所示。
图3-10部分解释:当程序执行“unset($age1);”语句时,调用进程4。使用unset()函数只是断开变量名和变量值的连接,而不会立即销毁变量。 PHP 垃圾收集机制会在“适当”的时刻回收该变量。
3.3.4 检查变量是否为“null”
PHP 提供了两个函数来检查变量是否为“空”:empty() 函数和 is_null() 函数。
1.empty()函数
语法格式:boolean empty(混合变量)
函数功能:用于检查变量var是否为“空”。函数参数var是变量名(带有$符号)。如果变量 var 为空,empty() 函数返回 TRUE,否则返回 FALSE。例如,程序empty.php如下。
2.is_null()函数
语法格式:boolean is_ null(mixed var)
函数功能:检查变量var是否为NULL,如果值为NULL则返回TRUE,否则返回FALSE。
函数说明:当使用is_null()函数判断变量是否为NULL时,可以将其视为isset()函数的反函数。以下三种情况下变量的值为NULL。
(1) 变量未定义。
(2) 变量的值被赋予NULL。
(3) 变量被unset()函数处理后。
例如,程序is_null.php如下。该程序的运行结果如图3-11所示。
3.3.5 数据类型检查函数
PHP 提供了检查变量或常量数据类型的函数(参见表 3-1)。这些函数的共同特点是需要向这些函数传递一个变量名(带有$符号)或者一个常量名(注意常量名必须是双字符)。引号或单引号)作为参数,如果检查符合要求,函数返回TRUE,否则返回FALSE。例如,程序typeChecked.php如下。
3.4 PHP 运算符
运算符是数据运算的符号,是表达式的另一个重要组成部分。根据运算符功能的不同,PHP运算符可分为算术运算符、赋值运算符、位运算符、比较运算符、错误控制运算符、执行运算符、自增/自减运算符、逻辑运算符、字符串连接运算符、条件运算符等。不同的运算符需要不同数量的操作数。根据运算符的操作数数量,运算符可分为一元运算符、双目运算符和三元运算符。
3.4.1 算术运算符
PHP算术运算符可以实现算术运算。 PHP 中的算术运算符如表 3-2 所示。例如,程序calculator.php如下。
3.4.2 自增/自减运算符
PHP 中的自增/自减运算符如表 3-3 所示。例如,程序increase.php如下。
3.4.3 赋值运算符
赋值运算符“=”将“=”右侧表达式的值赋给左侧变量。赋值运算符生成的表达式是赋值表达式,这个表达式的值就是“=”左边的变量值。例如,程序assign.php如下。
此外,PHP 还提供了适用于所有二进制算术和字符串运算符的“组求和运算符”:+=、-=、*=、/=、%=、.= 等。这允许您使用一个值(例如$y) 放在表达式中,并将表达式的结果赋给另一个值(例如 $x)(参见表 3-4)。例如,程序combination.php如下。
3.4.4 比较运算符
比较运算符用于比较两个表达式的值,比较的结果是一个布尔值(TRUE 或 FALSE)。如果表达式是数值,则根据数值的大小进行比较;如果表达式是字符串,则根据每个字符对应的 ASCII 值进行比较。表 3-5 显示了 PHP 中的比较运算符。例如,程序compare.php如下。
3.4.5 逻辑运算符
逻辑运算符对布尔数据进行运算并返回布尔结果。表 3-6 显示了 PHP 中的逻辑运算符。例如,程序logic1.php如下。
例如,程序logic2.php如下。
3.4.6 字符串连接运算符
字符串连接运算符只有一个点运算符“.”。使用“.”运算符将两个字符串连接成一个字符串。例如,程序string.php如下。
3.4.7 错误抑制运算符
当PHP表达式产生错误但您不希望在页面上显示错误消息时,可以使用错误抑制运算符“@”。通过在 PHP 表达式之前放置“@”运算符,将不会输出该表达式生成的任何错误消息。这样做有两个好处。
(1)安全性:避免错误信息暴露,造成系统漏洞。
(2)美观:避免浏览器页面出现错误信息,影响页面美观。
例如,程序errorControl.php如下。该程序的运行结果如图3-12所示。
注意:在程序errorControl.php中,“@print $age”;语句中的print不能用echo代替,否则会出现程序解析错误:“Parse error: parse error in C:\wamp\www\2\sample.php on line 7”。
当发生数据库连接、文件流打开、被0除等异常时,可以使用@符号来抑制函数或表达式错误消息。例如,程序errorControl2.php如下。
3.4.8 条件运算符
条件运算符的语法格式为:表达式1?表达式2:表达式3
由条件运算符组成的表达式称为条件表达式。条件表达式的执行过程为:如果表达式1的值为TRUE,则整个条件表达式的值为表达式2的值; if 表达式 1 的值为 FALSE,则整个条件表达式的值为表达式 3 的值。条件运算符中有 3 个操作数,因此条件运算符是三元运算符。例如,程序condition.php如下。
3.4.9 类型运算符
PHP 5提供了类型运算符instanceof,用于判断一个对象是否是某个类的对象。例如,程序instanceof.php如下。
3.4.10 执行运算符
执行操作符使用反引号(`)(注意这不是单引号!通常是键盘上ESC下的键)。执行运算符尝试将反引号中的字符串内容作为操作系统的系统命令(例如Linux shell命令或Windows DOS命令)执行,并返回系统命令的执行结果。例如,程序exec.php如下。
3.4.11 位运算符
位运算符主要用于对整数数据的运算。当表达式中包含位运算符时,运算时会先将各个整数数据转换为对应的二进制数,然后再进行位运算。 PHP提供的按位运算符如表3-7所示。例如,程序bit.php如下。
3.4.12 运算符优先级
复杂的表达式通常包含多个运算符。表达式求值时,各个运算符的优先级不同,各个运算符的执行顺序也不同。优先级高的运算符会先执行,优先级低的运算符会先执行。随后将执行该运算符。 PHP中各个运算符的优先级从高到低的顺序如表3-8所示。在实际编程过程中,使用括号“()”是避免优先级混乱的最有效方法。
3.5 数据类型转换
PHP 中的任何变量或常量都有“隐式”数据类型。数据类型由分配给变量或常量的值自动确定。同一表达式可以包含不同数据类型的常量和变量。这些常量或变量在计算前必须转换为相同数据类型的数据。 PHP类型转换包括自动类型转换和强制类型转换。
3.5.1 自动类型转换
自动类型转换是指在定义变量或常量时,不需要指定变量或常量的数据类型。 PHP预处理器根据具体的应用环境将变量或常量转换为合适的数据类型。例如,当字符串进行算术运算时,PHP预处理器会在执行算术运算之前将字符串转换为数字类型;当数值执行字符串连接操作时,PHP 预处理器会将数值转换为字符串类型。 ,然后进行字符串连接操作。自动类型转换的基本规则如下。
(1)布尔数据参与算术运算时,TRUE转换为整数1,FALSE转换为整数0;当NULL参与算术运算时,会转换为整数0。例如程序rules1.php如下。
(2) 当对浮点数和整数进行算术运算时,先将整数转换为浮点数再进行算术运算。例如,程序rules2.php如下。
注意:程序rules2.php在进行算术运算时,首先将TRUE转换为整数1,然后将整数1转换为浮点数1进行运算。
(3) 对于参与算术运算的字符串,只有以数字开头的字符串才会被识别为数字。当字符串的开头符合整数格式时,字符串将被转换为整数。例如,进行算术运算时,字符串“3rd Degree”将被转换为整数3;当字符串的开头符合浮点格式时(在字符串的开头可以包含“.”、“e”或“E”字符),该字符串将被转换为浮点数,如字符串将“3.5”、“-4.01”、“4.2e6”、“-4.1”进行算术运算时的度数分别转换为浮点数3.5、-4.01、4200000、-4.1。如果字符串不是以数字开头,则会被转换为整数0,例如在进行算术运算时,字符串“Catch 22”会被转换为整数0。例如程序rules3.php为接下来。
(4) 进行字符串连接操作时,整数和浮点数将被转换为字符串类型数据。例如,12和12.3转换为字符串,变成“12”和“12.3”。布尔值 TRUE 会被转换为字符串“1”,布尔值 FALSE 和 NULL 会被转换为空字符串“”,这就解释了为什么语句“echo TRUE;”打印到页面时为 1,而语句“echo FALSE;”作为空字符串打印到页面上。例如,程序rules4.php如下。
(5)进行逻辑运算时,空字符串“”、字符串“0”、整数0、浮点数0.0、NULL、空数组将转换为布尔类型FALSE,其他数据将转换为布尔类型TRUE(注字符串“0.0”将转换为布尔值 TRUE)。例如,程序rules5.php如下。
3.5.2 强制类型转换
强制转换允许程序员手动将变量的数据类型转换为指定的数据类型。 PHP 提供了以下 3 种类型转换方法。
(1) 在要类型转换的变量或常量前添加用括号括起来的目标数据类型。
(2) 使用类型转换函数intval()、floatval()、strval()。
(3) 使用通用类型转换函数settype()。
方法一 在变量前面加一个括号,并在括号内填写目标数据类型。
这些目标数据类型包括:int、bool、float、string、array、object等。例如程序manual1.php如下。
方法二:使用函数名以val结尾的函数
如intval()、floatval()、strval()函数,函数语法格式及功能如表3-9所示。例如,程序manual2.php如下。
方法3 使用settype()函数
语法格式:bool settype(混合var、字符串类型)
函数功能:设置变量var的数据类型为type数据类型。 type的值包括“bool”、“int”、“float”、“string”、“array”、“object”、“NULL”等字符串。如果执行成功该函数返回TRUE,否则返回FALSE。例如,程序manual3.php如下。