当前位置: 首页 > news >正文

PHP判断空值以及变量和数值作比较

文章目录

  • 环境
  • 总结
  • 判断空值
  • 其它
    • 判断数组的键是否存在
    • 判断变量是否存在
    • `??` 运算符
  • 变量和0比较

环境

  • PHP 8.2.12
  • Windows 11 专业版

总结

如果不想看详细内容,可以直接看总结:

  • 最常用、最推荐的方法是 isset() ,它是真正的判“空”:
    • 要么变量不存在
    • 要么变量的值是null
  • 如果把条件放宽,把0、false、空字符串、空数组也看做空值,那么可使用 empty() 方法来判别
  • isset() 的变体是 $x !== null ,但是对于不存在的变量,后者会报出warning Undefined variable ,因此不推荐
  • empty() 的变体是 $x ,但是对于不存在的变量,后者会报出warning Undefined variable ,因此不推荐
  • array_key_exists() 可以判断数组里是否存在某个键(值为null也算存在)
  • get_defined_vars() 结合 array_key_exists() ,可以精细判断某个变量是否存在(值为null也算存在)
  • $x ?? 123 相当于 isset($x) ? $x : 123 ,是后者的简写
  • 变量和数值作比较时,一定要确保变量存在,而且是数值类型的。注意如果用 is_numeric() ,会兼容一部分字符串
  • 反之,如果直接拿变量和数值作比较,则即使变量不存在,或者为null值,或者为非数值类型,也能比较(变量不存在时会报一个warning),但结果可能出乎意料,因此强烈不推荐

判断空值

PHP在判断空值时,大概有以下4种情况:

  1. 变量不存在,或已被 unset()
  2. 变量值为 null
  3. 变量值为 0''false 、空数组等值
  4. 正常有值的变量
变量不存在,或已被 unset()null0,空字符串,false,空数组其它值
isset($x)falsefalsetruetrue
!empty($x)falsefalsefalsetrue
$x !== nullfalse with warningfalsetruetrue
$xfalse with warningfalsefalsetrue

其它

判断数组的键是否存在

前面提到的方法,对于“变量不存在”和“变量存在且值为null”这两种情况,基本上是不区分的,因为绝大多数情况下,都没有必要区分。

不过对于数组,有时可能需要判断某个键是否存在,比如:

$arr1 = array('x'=>123, 'y'=>null);
$arr2 = array('x'=>123);

$arr1$arr2 多了一个键 y (虽然其值是null)。

如何判断这种情况呢?答案是用 array_key_exists()

  • array_key_exists('y', $arr1) :true
  • array_key_exists('y', $arr2) :false

判断变量是否存在

同理,回过头来,我们也可以分辨“变量不存在”和“变量存在且值为null”这两种情况。方法是先用 get_defined_vars() 获取所有变量(得到一个数组),然后通过 array_key_exists() 判断指定键是否存在:

$arr = get_defined_vars();if (array_key_exists("x", $arr)) { // falseecho "x is defined";
} else {echo "x is not defined";
}$x = null;$arr = get_defined_vars();if (array_key_exists("x", $arr)) { // trueecho "x is defined";
} else {echo "x is not defined";
}

?? 运算符

先看一个例子:

$x ?? 123

它的功能是:如果 $x 存在且不为null,则返回 $x ,否则返回 123

可见,该代码等价于以下的三目运算:

isset($x) ? $x : 123

可以把前者看做是后者的简写。

因为代码中会经常遇到取值时,需要先判断是否为空值的情况,可以用 if...else... 或者三目运算符,而 ?? 运算符简化了代码,更加一目了然。

跑个题:在SQL语言中,比如Db2和MySQL,有 coalesce() 函数,也实现了类似的功能,比如:

select coalesce(c1, 0) as c1 from t1

coalesce() 的功能是:如果第一个参数不是null则返回第一个参数,否则返回第二个参数。

变量和0比较

另一种常见的场景是,变量和0的比较,比如:

if ($teamid > 0)......

上面的写法不够严谨:

  • 变量可能并不存在
  • 变量可能是null值
  • 变量可能是非数值类型

显然,更严谨的做法是,先确定变量存在而且是数值,然后再和0作比较:

if (isset($x) && (is_int($x) || is_float($x)) && $x > 0)

或者:

if (isset($x) && is_numeric($x) && $x > 0)

前者比较严格,判断变量的类型是否为int或float,而后者较为宽松,对字符串也有一定的容忍。

对字符串的判别,比如:

  • is_numeric('123') :true,123
  • is_numeric('1e3') :true,1000
  • is_numeric(' 123 ') :true,123
  • is_numeric('0123') :true,123 (注:不能当作8进制,而是直接忽略前面的0)
  • is_numeric('0xFF') :false (注:不识别16进制,但在早期PHP版本中,可能是true)
  • is_numeric('123abc') :false (不识别数字和字母的混合体)

注意,即使 is_numeric() 测试结果是false,也可以强转为数值,比如:

  • (int) '0123' :123(不能当作8进制,而是直接忽略前面的0)
  • (int) '0xFF' :0 (不识别16进制)
  • (int) '123abc' :123
  • (int) 'xyz' :0

转换规则是,从字符串开头开始,找数字或合法的字符(比如 e ),一直到不符合要求为止,然后把可以转换的部分转换为数值。如果从一开头就不可转换,则转换结果为0。

关于字符串到数值的类型转换,可参见我另一篇文档: https://blog.csdn.net/duke_ding2/article/details/149110312

总之,如果不做判断,直接拿变量和0做对比,很可能会出现非期望的结果。以下面的代码为例:

if ($x > 0)
......
变量不存在,或已被 unset()null0空字符串‘xyz’false空数组其它值
$x > 0false with warningfalsefalsefalsetruefalsetrue视情况而定
$x < 0false with warningfalsefalsetruefalsefalsefalse视情况而定
$x == 0true with warningtruetruefalsefalsetruefalse视情况而定
$x != 0false with warningfalsefalsetruetruefalsetrue视情况而定
$x === 0false with warningfalsetruefalsefalsefalsefalse视情况而定
$x !== 0true with warningtruefalsetruetruetruetrue视情况而定

总结:把变量当作数值和0比较时:

  • 变量不存在:0,但在严格比较时,不是0。此外,会报一个warning
  • null:0,但在严格比较时,不是0
  • 0:0,严格比较时,也是0(废话)
  • 空字符串:一个小于0的数
  • false:0,但在严格比较时,不是0
  • 空数组:一个大于0的数
  • 其它值:视情况而定

可见,如果直接拿变量和0作比较,会产生很多意想不到的结果。因此,一定要确保变量非空且是数值类型,才能和数值做比较。

http://www.lryc.cn/news/613411.html

相关文章:

  • 关于Android studio调试功能使用
  • 【linux】vmware中ubuntu无法上网
  • 用 tcpdump 捕获网络数据包
  • Spring IoC 容器核心流程(面试必懂)
  • DevOps平台结合Gradle实现打包流水线
  • Linux中进程地址空间
  • 2025 年华数杯全国大学生数学建模竞赛C 题 可调控生物节律的 LED 光源研究--完整成品、思路、模型、代码、结果分享
  • GPT-5即将来袭,AI新时代要变天?
  • Redis实战(8) -- 分布式锁Redission底层机制
  • LVDS系列24:Xilinx Ultrascale系ISERDESE3原语(二)
  • 【数据结构——并查集】
  • 批量获取亚马逊商品SKU商品规格调用流程
  • 哈勃网络计划大规模升级卫星以创建全球蓝牙层
  • 哈希表——指针数组与单向链表的结合
  • [Oracle] FLOOR()函数
  • 2025最新国内服务器可用docker源仓库地址大全(2025年8月更新)
  • 上海一家机器人IPO核心零部件依赖外购, 募投计划频繁修改引疑
  • 【Linux基础知识系列】第八十八篇 - 使用du命令分析文件和目录大小
  • 如何解决用阿里云效流水线持续集成部署Nuxt静态应用时流程卡住,进行不下去的问题
  • 硬盘哨兵pe版本 v25.70.6 中文免费版
  • openGauss3.10企业版单机部署(openEuler20.03 SP3)
  • RP2040下的I2S Slave Out,PIO状态机(四)
  • HMC1119LP4METR ADI亚德诺 高频功率放大器 MMIC集成电路IC
  • 自动化测试篇--BUG篇
  • Android-Kotlin基础(Jetpack④-Room)
  • RepoCoder:仓库级代码补全的迭代检索生成框架解析与应用前沿
  • 前缀和
  • 网卡名eth1、em1 、eno1、ens1 的区别
  • C++ vector 扩容时到底发生了什么?
  • 纯本地AI知识库搭建:DeepSeek-R1+AnythingLLM全流程