【问题标题】:Type casting and Comparison with Loose Operator "=="类型转换和与松散运算符“==”的比较
【发布时间】:2011-07-13 14:20:26
【问题描述】:

我有一个令我非常困惑的问题。我之前注意到了这一点,但直到今天才注意到它。 我试图为整数字符串编写自己的检查。我知道is_numeric(),但这还不够,因为它不仅将float 视为数字,而且integersis_int() 对字符串数字不起作用。

我做了类似的事情


$var1 = 'string';
$var2 = '123'; 

var_dump( (int)$var1 == $var1);// boolean true 
var_dump((int)$var2 == $var2);// boolean true

 var_dump((int)$var1);//int 0
 var_dump($var1);//string 'string' (length=6)

正如预期的那样,第二个 var 转储输出 true,因为我希望通过 php 的松散比较,字符串和整数版本是相等的。

但是对于第一个,我不明白为什么会这样。我已经尝试投射到bool,但它仍然给了我相同的结果。

我已经尝试将 cast var 分配给一个新的 variablr 并比较两者,结果仍然相同

这是我做错了什么还是 php 错误?

***注意 我不是在这里比较类型。我实际上是想利用int 0 不等于string 'string' 的事实。

我以不同的方式编写了整数检查,因此我真的不需要替代方案。

***编辑 我做了一些额外的检查,结果发现0 == 'string' 也是正确的。这怎么可能?

***编辑 2 以下有多个正确答案。感谢所有回答的人。

【问题讨论】:

  • 如果你使用“==="会发生什么?
  • var_dump((int)$var1) 为我返回“int(0)”。
  • @Jim,我知道我应该添加它。那么它显然输出错误。但我并没有像我已经说过的那样比较类型。我正在尝试利用 == operator 的行为

标签: php casting comparison


【解决方案1】:

注意:这个答案是对a related question about the Twig template engine的回应,它被标记为重复,并重定向到这里。

由于上下文不同,此答案提供给 SO 社区的那些成员,他们可能会受益于与 专门相关的其他详细信息。

TL;DR:见这篇帖子How do the PHP equality (== double equals) and identity (=== triple equals) comparison operators differ?

问题

上下文

  • Twig 模板引擎(截至周五 2017-01-27T05:12:25 的最新版本)

场景

  • DeveloperYlohEnrohK 在 twig 表达式中使用比较运算符
  • DeveloperYlohEnrohK 在使用相等比较运算符时发现意外结果

问题

  • 为什么相等比较运算符 (==) 在 Twig 中会产生意外结果?
  • 为什么以下会产生不同的结果?

    {{ 转储(0 == 'somekey') }} ==> 真 {{ 转储(0|lower == 'somekey') }} ==> false

解决方案

陷阱

  • 在撰写本文时,Twig 模板引擎不像标准 PHP 那样支持 ===
  • Twig 确实有 === using same as 的替代品
  • 因此,PHP 和 Twig 对 well-known circumstance 的处理方式略有不同。

另见

【讨论】:

  • 感谢您的出色回答。
【解决方案2】:

这不是错误,这是一个功能。任何字符串都可以转换为整数,但the cast will return 0 if the string doesn't start with an integer value. 此外,在比较整数和字符串时,the string is casted to an integer and then the check is done against the two integers。由于该规则,几乎任何随机字符串都“等于”为零。 (要绕过这种行为,您应该使用strcmp,因为它通过将传递给字符串的任何内容强制转换为字符串来执行显式字符串比较。)

为了确保我处理的是整数,我会先使用is_numeric,然后将字符串转换为int,并验证字符串化的 int 是否对应于输入值。

if (is_numeric($value) && strcmp((int)$value, $value) == 0)
{
    // $value is an integer value represented as a string
}

【讨论】:

  • 如果$value 大于最大 int 大小,则 PHP 将使用最大 int 大小,然后是 strcmp((int)$value, $value) != 0。这可能被认为是与功能相关的特性或错误——任何使用上述内容的人都应该意识到这一点并做好适当的准备。
【解决方案3】:

根据php.nethttp://php.net/manual/en/language.operators.comparison.php

var_dump(0 == "a"); // 0 == 0 -> true

所以,我认为这是在处理类型,实际上将双方都转换为 int。然后比较字符串中每个索引的 ascii 值的总和或 ascii 值。

【讨论】:

  • 我没有。我正在用手机打字,这对我来说是很多打字。其次,这就是我的 vardump 输出。可能是因为 xdebug。
  • 对不起。以上不适合你。我知道这种行为很奇怪,但大多忘记了它的这一方面,但当我试图依赖它时忘记了这一方面。现在我手上有很多正确的答案。谢谢。
【解决方案4】:

首先在数学中'='被称为传递b/c(A=B and B=C => A=C)是有效的。

PHP 不是这种情况“==”!

(int)$var1 == $var1

在这种情况下,PHP 会将 'string' 强制转换为 0 - 这是一个约定。

然后 ==-operator 将隐式地将第二个操作数“字符串”也转换为整数 -> 以及 0。

这导致了事实。

【讨论】:

  • +1:提到传递性,我总是在抱怨 PHP 比较时提到这一点 :)
【解决方案5】:

你的帖子出错了,正确的输出是这样的:

bool(true)
bool(true)
int(0)
string(6) "string"

会发生什么:

  1. 因为您将变量转换为整数,然后将其与具有松散比较的整数进行比较==,PHP 将首先将字符串隐式转换为整数,更明确但 100% 等效的形式是:@ 987654323@
  2. 参见 1),这里同样适用
  3. 它应该打印int(0),因为它无法解析数字,而是返回0
  4. 打印 string(6) "string" - 符合预期

【讨论】:

  • 我没有。我正在用手机打字,这对我来说是很多打字。其次,这就是我的 vardump 输出。可能是因为 xdebug。
  • 不客气。好吧,也许你只是把它们弄混了,我敢肯定 xdebug 不会改变它;)
  • 很有趣,这就是我的浏览器窗口中显示的内容。正如我输入的那样。我只是交叉检查了
  • 我认为是 xdebug 做的。它看起来与我没有安装 xdebug 的旧笔记本电脑不同。数组转储看起来也很不错
  • @frostymarvelous 5 年后你又回来了?哇!
【解决方案6】:

如果你也想比较变量的类型,你应该使用===

【讨论】:

  • 我的理解是 OP 想要检查像 "555" == 555 这样的东西。
【解决方案7】:

这是一个更严格地测试 int 或整数字符串的函数。

function isIntegerNumeric($val) {
  return (
    is_int($val)
      || (
        !is_float($val)
          && is_numeric($val)
          && strpos($val, ".") === false
      )
  );
}

它相对较快,并且在不需要时避免进行任何字符串检查。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-09
    • 2010-12-16
    • 2021-11-07
    • 1970-01-01
    • 2014-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多