关于等于 与 全等的问题

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

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

thanks

php
Stay Hungry, Stay Foolish.
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
最佳答案

摘取 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年前 评论

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