【问题标题】:Why PHP casts two numerical strings to numbers before [loosely] comparing them?为什么 PHP 在 [松散地] 比较它们之前将两个数字字符串转换为数字?
【发布时间】:2013-06-02 05:09:50
【问题描述】:

我浏览了几个类似的问题,但它们都只陈述事实:

If ... comparison involves numerical strings, then each string is converted to a number and the comparison performed numerically.

好的,我明白了。它解释了当'00001' == '1' 返回TRUE 时发生的什么

问题是:为什么 PHP 会这样做?
探测字符串是否为数字的原因是什么,如果是,则进行强制转换?为什么我们不能只比较两个字符串呢?

如果两个操作数具有不同的类型,我可以相当理解需要什么转换。但是,当两者都是字符串时,为什么它会“usual math”呢?

【问题讨论】:

  • 因为他们没有从 Perl 那里得到提示。 :P 像“== 比较数字,eq 比较词汇,=== 比较严格”这样说会容易得多。 (虽然如果我们有前两个,后者可能永远不需要使用。嗯,也许与对象。)

标签: php casting comparison string-comparison


【解决方案1】:

您可以比较两个字符串。

"00001" === "1"  // false

记住== 表示相等 === 表示相等

对于为什么会出现这种情况,我唯一的猜测是因为一开始 PHP 努力成为一种无类型语言,然后才走上成为松散类型语言的道路。

PHP 最初是允许在其中编写一些脚本的字符串处理器。由于网络上的所有输入本质上都是文本的,因此在处理数字时必须努力工作,因为文本输入要表现得理智。

对此我可能是错的,但我不相信显式转换数据类型的能力直到 PHP 4 引入了 *val 函数(如 intval)等。我认为转换符号,如(int) 在那之后出现了。

对于非比较操作,这很容易,因为它们都有一个与之关联的类型(+ - / * 都处理数字,而 . 处理字符串)所以在这些情况下应该如何转换的清晰路径是明显。

但是通过变量之间的相等性或等价性检查,唯一的方法是将所有看起来像数字的东西都视为数字,因为当时唯一可以通过外部获取它的方法是作为字符串否则就没有办法了。

【讨论】:

  • 我知道我会得到很多类似的答案。所以太直接了:)
  • @Orangepill - 但他的问题是Why?
  • @YourCommonSense 更好吗?
  • @Orangepill:我绝对认为是。比任何纯粹的技术答案都更好地涵盖了“为什么”。虽然它不是“松散类型”,但它是“动态类型”。
  • 非常、非常有用但经常被忽视的评论。谢谢!
【解决方案2】:

啊,终于明白了。我真是太愚蠢了。

比较不仅涉及"is equal",还涉及"less than""greater than"。而对于后两者,在比较之前转换数字操作数显然很重要,因为数字在 PHP 中通常表示为字符串,而 11 必须大于 9,即使两者都存储在字符串中。

所以,compare_function()同时进行所有比较,返回 1, 0, -1 以分别判断第一个操作数是更大、等于还是小于第二个 - 嗯,这很公平地解释了为什么被强制转换的操作数。

【讨论】:

    【解决方案3】:

    因为,PHP 为最终用户而非应用程序开发人员生产产品。 因此,当您生产如下产品时:

    if (isset($_POST['submit'])){
      if ($_POST['myinput'] == "1") echo 'Yes'; //or == 1
      else echo 'NO';
    }
    
        ?>
        <form name="myform" method="POST" action="">
        <input name="myinput">
        <input name="submit" type="submit">
        </form>
    

    如果用户输入10001,您希望在这两种情况下打印什么? YesNO?

    答案很明确。我们希望看到Yes。所以这是why PHP does so 如果出于某种罕见的原因,我们确实需要比较它们,那么我们应该将 == 更改为 ===

    【讨论】:

    • 支持添加是因为许多设计决策,尤其是 '1''00001'(int) 1(float) 1.0 之间的等效性是由于 HTTP 仅支持字符串。 PHP 试图在面向“仅字符串”的世界中简化开发人员的类型处理。
    猜你喜欢
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多