PHP 变动:PHP 8 版本下字符串与数值的弱比较

news/2025/3/28 8:20:31/

文章目录

  • 参考
  • 环境
  • 声明
  • 弱比较
      • 隐式类型转换
      • 字符串连接
      • 数学运算
      • 布尔判断
      • 相等运算符
  • 字符串与数值的弱比较
      • 字符串转化为数值的具体规则
      • 字符串与数值的弱比较
          • 一般情况
          • 科学计数法
            • 前缀 0E 与 0e
  • PHP8 在字符串与数值的弱比较方面做出的改动
      • 数值字符串
      • 优化

参考

项目描述
搜索引擎BingGoogle
AI 大模型文心一言通义千问讯飞星火认知大模型ChatGPT
PHP 手册PHP Manual
wsfgrdghPHP8中字符串与数字的比较更智能
PHP RFC 文档Saner string to number comparisons

环境

项目描述
PHP5.5.05.6.87.0.07.2.57.4.98.0.08.2.9

注:

本篇文章在除大板块 PHP8 在字符串与数值的弱比较方面做出的改动 外均不使用 8.x.x 版本的 PHP 解释器。

声明

本篇文章所介绍的 弱比较 适用于任何执行 非严格比较 的操作,包括但不限于 ==!=>>=in_array()array_search()。为使文章更为 精简,本文将专注于 == 的弱比较讲解。

弱比较

隐式类型转换

在 PHP 中,隐式类型转换(Implicit Type Conversion) 是指在某些操作中,PHP 会 自动 将数据 由一种数据类型转换为另一个数据类型,而 无需显式 地编写 类型转换 代码。

PHP 的隐式类型转换会按照一定规则(具体情况具体分析)对操作数进行转换,以使得相关操作 能够正常进行 下去。

字符串连接

在通过使用句点运算符 . 进行字符串连接操作时,PHP 将会尝试将其他数据类型 转换为字符串数据类型。对此,请参考如下示例:

<?php// 尝试将两个字符串进行拼接
var_dump('Hello ' . 'World');// 尝试将数值与字符串进行拼接
var_dump('1 + 1 = ' . 2);// 尝试将两个数值进行拼接
var_dump(1 . 1);

执行效果

string(11) "Hello World"
string(9) "1 + 1 = 2"
string(2) "11"

数学运算

在通过 数学运算符 进行数学运算时,PHP 将会尝试将其他数据类型的数据 转换为数值类型。对此,请参考如下示例:

<?php// 尝试对布尔值 true 与数值 1 进行减法运算
var_dump(true - 1);// 尝试对布尔值 true 与 false 进行加法运算
var_dump(true + false);// 尝试进行字符串之间的乘法运算
var_dump('2' * '150');// 字符串 100djdj 将被转换为 100
var_dump('100djdj' / 10);// 字符串 djdj100 将被转换为零
var_dump('djdj100' / 10);

执行效果

int(0)
int(1)
int(300)
int(10)
int(0)

布尔判断

在需要使用布尔值的位置,PHP 将尝试将非布尔值的数据 转换为布尔类型的数据。对此,请参考如下示例:

<?php// 尝试将空字符串转换为布尔值
if(''){print('Hello World' . "\n");
}// 尝试将字符串 Hello World 转换为布尔值
if('Hello World'){print('Hello China' . "\n");
}// 尝试将数值 999 转换为布尔值
if(999){print('久久久' . "\n");
}

执行效果

Hello China
久久久

相等运算符

在 PHP 中存在两种相等运算符,即弱类型相等运算符 == 和强类型相等运算符 ===,两者都可以用于判断两个操作数是否相等,但存在一些区别。

两者的 区别 在于,弱类型相等运算符 在对操作数进行比较之前,将 自动 进行类型转换以 使两者所属的数据类型相同。而 强类型相等运算符 在进行比较时,要求两个值的 类型 都必须 完全相同不进行类型转换。对此,请参考如下示例:

<?php// 在通过弱类型比较运算符对数值与字符串进
// 行比较时,PHP 优先将字符串转换为数值。// 由于两者转换为同一类型后,值相同,
// 故将返回 true。
var_dump('123' == 123);// 由于两者的数据类型及值均不相同,故
// 将返沪 false。
var_dump('123' === 123);

执行效果

bool(true)
bool(false)

字符串与数值的弱比较

字符串转化为数值的具体规则

在 PHP 的 隐式类型转换过程 中,字符串转化为数值的具体规则如下:

  1. 若字符串的 首个字符不为数字且不为空格等空白字符,则将该字符串转化为零。
  2. 若字符串的 首个字符不为数字但为空格等空白字符,则尝试读取其余字符,将遇到数字前的所有空白字符均转化为零,将遇到数字后的所有空白字符视为非数字字符;在遇到非数字字符时停止对字符串的读取并将已读取字符转化为数值
  3. 若字符串的 首个字符为数字,则尝试读取其余字符,在遇到非数字字符(除符合科学计数法格式的字符 e 或 E外)时停止对字符串的读取并将已读取字符转化为数值

举个栗子

目标字符串转化结果
Hello1230
1Hell2o31
0x8aHello1230
9.384Hello9.384
0008743738Hello9488743738
1.223e100122.3

注:

PHP 在执行字符串到数值的隐式类型转换过程,均 以十进制表示法 为依据。同上述例子一般,0x8aHello123 中的 0x8a 并不会被识别为十六进制数,由于十进制中不存在 x,故 PHP 在识别到字符 x 时就将立即停止读取并将读取到的字符串 0 转化为数值,故最终的转化结果为零。

字符串与数值的弱比较

一般情况

在 PHP 中,若字符串与数值进行弱比较,则 PHP 将 优先把字符串转换为数值 后再进行比较。对此,请观察如下示例:

<?phpvar_dump('Hello123' == 0);  # bool(true)
var_dump('1Hell2o3' == 1);  # bool(true)var_dump('0x8aHello123' == 0);  # bool(true)var_dump('9.384Hello' == 9.384);  # bool(true)var_dump('0363534Hello' == 0);  # bool(false)
var_dump('0008743738Hello948' == 8743738);  # bool(true)var_dump('   8996Hello ' == 8996);  # bool(true)
var_dump('   89 9 ' == 89090);  # bool(false)
var_dump('   89 9 ' == 89);  # bool(true)var_dump('' == 0);  # bool(true)

注:

空字符串 在字符串到数值的隐式类型转换过程中将被转化为

科学计数法

在 PHP 中,eE 均表示 科学计数法(Scientific Notation)。科学计数法由 基数指数 两部分组成,常用于 表示非常大或非常小的数值。

在科学计数法中,基数 通常 是一个浮点数,介于 110 之间,而指数是一个整数,表示要将基数乘以 10 的多少次方。基数与指数之间以字符 eE 进行分隔。

举个栗子

<?php// 3.78 * 10 ^ 3
var_dump(3.78e3);
var_dump('3.78e3' == 3780);// 3 * 10 ^ -1
var_dump(3E-1);
var_dump('3E-1' == 0.3);

执行效果

float(3780)
bool(true)
float(0.3)
bool(true)
前缀 0E 与 0e

零的任何指数次幂都为零,因此以 0E0e 为前缀的科学计数法表示的数值的结果都将为数值零。对此,请参考如下示例:

<?phpvar_dump(0e3280);
var_dump('0e30284083' == 0);
var_dump('0esjlfjsld' == 0);

执行效果

float(0)
bool(true)
bool(true)

PHP8 在字符串与数值的弱比较方面做出的改动

数值字符串

数值字符串 是指一个包含数字字符的字符串,数值字符串可以用于直接表示一个数值。

举个栗子

"123"
"-42"
"+384""3.14"
"-0.5"
"0.0000"
"00000000.0000""2.5e3"
"1.2e-2"
"+42.0E0""0004746"
"0305940"
"       484748      "
" 4847      "
"               3847"

注:

  1. 包含 代表其他进制(非十进制)数值的符号 的字符串不能被称为数值字符串(数学中通常不使用这些符号来标识其他进制的数值),如 0x1F0b10101 等字符串。在 PHP 中,八进制数值 通过 前导零 来表示,但在 数值字符串中,前导零将 被视为普通数字,不具备标识八进制数值的功能
  2. 如果存在将其他进制(非十进制)的字符串转化为数值的需求,可以考虑使用 intval() 等函数进行显式类型转化。
  3. 包含空格等空白字符的字符串 为什么也可以是数值字符串?你可以理解为 一眼望去是数值的就是数值字符串😔。

优化

PHP8 仍旧保留了隐式类型转换 这一特性,但在字符串与数值的弱比较方面做出了优化。在 字符串与数值的弱比较 过程中,PHP 将 依据字符串的不同 选择 将字符串转换为数值将数值转换为字符串 后再进行比较。具体规则如下:

  1. 若字符串 符合数值字符串的定义,则 PHP 尝试 将字符串转化为数值 后再进行比较。
  2. 若字符串 不符合数值字符串的定义,则 PHP 尝试 将数值转化为字符串 后再进行比较。

举个栗子

<?php# 数值 0x10 将首先转化为十进制数 16
# 后再转化为字符串与 '0x10' 进行比较。
var_dump('0x10' == 0x10);  # bool(false)
var_dump('16' == 0x10);  # bool(true)var_dump('' == 0);  # bool(false)
var_dump('0000.00000' == 0);  # bool(true)var_dump('989   ' == 989);  # bool(true)
var_dump('   989   ' == 989);  # bool(true)
var_dump('0000989' == 989);  # bool(true)var_dump('9847Hello' == 9847);  # bool(false)
var_dump('Hello' == 0);  # bool(false)

PHP8 的这一改动 提高了代码的可预测性降低了许多安全隐患发生的可能。在 PHP8 中,像这类的改动还有许多,也正是如此,PHP8 的开发一度被认为 混入了卓越的安全专家


http://www.ppmy.cn/news/1127192.html

相关文章

Qt-键盘消息的传递-键盘消息的获取-C++

文章目录 1.概述2.焦点3.强制获取键盘消息4.键盘常用组合方法5.总结 1.概述 QKeyEvent 类用来描述一个键盘事件。当键盘按键被按下或者被释放时&#xff0c;键盘事件便会被发送给拥有键盘输人焦点的部件。 QKeyEvent 的 key() 函数可以获取具体的按键&#xff0c;对于 Qt 中给…

知识分享 钡铼网关功能介绍:使用SSLTLS 加密,保证MQTT通信安全

背景 为了使不同的设备或系统能够相互通信&#xff0c;让旧有系统和新的系统可以集成&#xff0c;通信更加灵活和可靠。以及将数据从不同的来源收集并传输到不同的目的地&#xff0c;实现数据的集中管理和分发。 通信网关完美克服了这一难题&#xff0c;485或者网口的设备能通过…

mysql大数据量 分页查询优化

最近我老表问我一个面试问题&#xff0c;如果数据量很大&#xff0c;分页查询怎么优化。 个人觉得无非就是sql优化&#xff0c; 那无非就是走索引&#xff0c; 避免回表查询&#xff08;覆盖索引&#xff0c;也就是不要用select * &#xff0c;走主键索引&#xff0c;叶子节点有…

蓝桥杯2023年第十四届省赛真题-异或和之和--题解

目录 蓝桥杯2023年第十四届省赛真题-异或和之和 题目描述 输入格式 输出格式 样例输入 样例输出 【代码实现】 大家觉得写得可以的话&#xff0c;可以加入QQ群907575059. 蓝桥杯2023年第十四届省赛真题-异或和之和 时间限制: 3s 内存限制: 320MB 提交: 241 解决: 66 …

手机自动直播系统源码交付与代理加盟注意事项解析!

随着直播行业的不断发展&#xff0c;手机自动直播已经成为了人们生活中不可或缺的一部分。手机无人直播软件成了香饽饽&#xff0c;各类手机实景直播APP大批量涌现。因为创业和技术门槛低&#xff0c;市场需求高&#xff0c;所以成了最火热创业赛道。那么如果是不懂技术的人群&…

ubuntu18.04安装python3.10.13

下载python包: https://www.python.org/downloads/安装关联软件包: apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev执行sudo ./configure --enable-optimizations 此命令是为了在编译 Python 时启用性…

java中常见的函数式接口及简单示例

在Java中&#xff0c;有一些常见的函数式接口可以用于支持函数式编程和Lambda表达式的使用。以下是一些常见的函数式接口&#xff1a; Predicate&#xff1a;用于判断输入的值是否满足某个条件。它包含方法test&#xff0c;接收一个参数并返回一个布尔值。Function&#xff1a…

分享一款开源的QT的串口示波器

分享一款开源的QT的串口示波器&#xff0c;完全开源&#xff0c;支持串口、TCP、波形显示、通信协议。 Sailor Project功能说明 串口调试助手功能 支持传统的串口调试助手的基本收发功能&#xff0c;同时可以刷新大量的数据而不卡顿 支持保存接收的数据 支持最大200条可编辑…