关于等于 与 全等的问题

去网上找了下资料
https://stackoverflow.com/questions/80646/...
但理解还不够,so我想问一下,这两个比较运算符

在什么场景下一定要区分开来使用,否则就会引发问题

thanks

php
Stay Hungry, Stay Foolish.
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
最佳答案

摘取 PHP 文档的几个说明

如果(使用弱类型)比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。
当用 === 或 !== 进行比较时则不进行类型转换,因为此时类型和数值都要比对。

== 和 === 的问题,这里有个栗子,感兴趣可以自行食用

在后台订单管理中,会有 通过订单状态筛选订单 的基本功能对吧?那如果在模型常量中有如下定义

<?php

class OrderModel {

  //  刚创建订单,还没支付的状态值
  const STATE_CREATED = 0;
  //  已经支付的状态值
  const STATE_PAYED = 1;

}

如果你的订单状态没有值为 0 的定义,或者使用英文字符串定义状态值,这做得很好,就不需要往下再看了。

然后,我们通过 $request->get('state') 的方式接收筛选条件 state 当前的值,并传入到模版中,以进行状态下拉选择框的渲染

// 这里使用原生的 PHP 来写,与 Laravel 的模版大同小异
// $state = $request->('state');

<select name="state">
  <option>订单状态选择</option>
  <option value="0" <?php if ($state == 0) echo "selected"; ?>>已创建,未付款</option>
  <option value="1" <?php if ($state == 1) echo "selected"; ?>>已付款</option>
</select>

/**
 * 在 option 元素的 value 属性值输出一行,比较好的做法是使用
 * <?php echo OrderModel::STATE_CREATED;  ?> 输出,这里
 * 为了简化代码就硬编码为 0,1 字符
 */ 

简单解释一下上面代码的渲染意图,在没有传入 $state 或者传入的值不是 0 或 1 的情况下,下拉框默认显示 订单状态选择,反之,传入的是 0,1 就对应显示选中的选项

实际运行后你会发现,上述代码即使在 $state 没有传入的情况下($request->get('state') 的默认值是 null),已创建,未付款 还是会显示为已选中的状态。这是为什么?

答案在 if ($state == 0)

由于这里使用了 ==,于是 null 和 0 比较视为相等,selected 字符串被渲染出来了。所以即使在未选择任何筛选条件的情况下,已创建,未付款 显示为已选中的状态,使用它的用户就会觉得怪异。

PHP 文档中有一个松散比较的结果二维表,从中可以找到 NULL == 0 结果为 TRUE

解决方案当然是 if ($state === 0)null 和整型的 0 在这种情况下不应该视为相等。

资料参考

[中文]PHP: 比较运算符
[中文]PHP: PHP 类型比较表 (请定位到 松散比较 == 节)

4年前 评论
讨论数量: 9
wangchunbo

== 比较值相等。 ===比较类型 值都相等。

4年前 评论

我建议,任何情况下都别使用 ==

4年前 评论
lochpure

==比较值,===比较值和类型

4年前 评论

摘取 PHP 文档的几个说明

如果(使用弱类型)比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。
当用 === 或 !== 进行比较时则不进行类型转换,因为此时类型和数值都要比对。

== 和 === 的问题,这里有个栗子,感兴趣可以自行食用

在后台订单管理中,会有 通过订单状态筛选订单 的基本功能对吧?那如果在模型常量中有如下定义

<?php

class OrderModel {

  //  刚创建订单,还没支付的状态值
  const STATE_CREATED = 0;
  //  已经支付的状态值
  const STATE_PAYED = 1;

}

如果你的订单状态没有值为 0 的定义,或者使用英文字符串定义状态值,这做得很好,就不需要往下再看了。

然后,我们通过 $request->get('state') 的方式接收筛选条件 state 当前的值,并传入到模版中,以进行状态下拉选择框的渲染

// 这里使用原生的 PHP 来写,与 Laravel 的模版大同小异
// $state = $request->('state');

<select name="state">
  <option>订单状态选择</option>
  <option value="0" <?php if ($state == 0) echo "selected"; ?>>已创建,未付款</option>
  <option value="1" <?php if ($state == 1) echo "selected"; ?>>已付款</option>
</select>

/**
 * 在 option 元素的 value 属性值输出一行,比较好的做法是使用
 * <?php echo OrderModel::STATE_CREATED;  ?> 输出,这里
 * 为了简化代码就硬编码为 0,1 字符
 */ 

简单解释一下上面代码的渲染意图,在没有传入 $state 或者传入的值不是 0 或 1 的情况下,下拉框默认显示 订单状态选择,反之,传入的是 0,1 就对应显示选中的选项

实际运行后你会发现,上述代码即使在 $state 没有传入的情况下($request->get('state') 的默认值是 null),已创建,未付款 还是会显示为已选中的状态。这是为什么?

答案在 if ($state == 0)

由于这里使用了 ==,于是 null 和 0 比较视为相等,selected 字符串被渲染出来了。所以即使在未选择任何筛选条件的情况下,已创建,未付款 显示为已选中的状态,使用它的用户就会觉得怪异。

PHP 文档中有一个松散比较的结果二维表,从中可以找到 NULL == 0 结果为 TRUE

解决方案当然是 if ($state === 0)null 和整型的 0 在这种情况下不应该视为相等。

资料参考

[中文]PHP: 比较运算符
[中文]PHP: PHP 类型比较表 (请定位到 松散比较 == 节)

4年前 评论

file

贴个相关性不大的但需要注意的地方😆

4年前 评论

比如判断是否为 false 的时候,此时实际值又 0

4年前 评论
wangchunbo

因为php弱类型,所以就这样啦

4年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!