【问题标题】:PHP max() and min() weird behavior with different typesPHP max() 和 min() 具有不同类型的奇怪行为
【发布时间】:2016-08-22 06:09:16
【问题描述】:

过去两个小时我一直在为这种行为摸不着头脑:

echo 'max(1, "a", "2"   ) : '; var_dump( max( 1, 'a', '2' ) );
echo 'max(1, "2", "a"   ) : '; var_dump( max( 1, '2', 'a' ) );
echo 'max(   "a", "2", 1) : '; var_dump( max( 'a', '2', 1 ) );
echo 'max(   "2", "a", 1) : '; var_dump( max( '2', 'a', 1 ) );
echo "\n";
echo 'min(1, "a", "2"   ) : '; var_dump( min( 1, 'a', '2' ) );
echo 'min(1, "2", "a"   ) : '; var_dump( min( 1, '2', 'a' ) );
echo 'min(   "a", "2", 1) : '; var_dump( min( 'a', '2', 1 ) );
echo 'min(   "2", "a", 1) : '; var_dump( min( '2', 'a', 1 ) );

打印出来的:

max(1, "a", "2"   ) : string(1) "2"
max(1, "2", "a"   ) : string(1) "a"
max(   "a", "2", 1) : int(1)
max(   "2", "a", 1) : int(1)

min(1, "a", "2"   ) : string(1) "2"
min(1, "2", "a"   ) : string(1) "a"
min(   "a", "2", 1) : int(1)
min(   "2", "a", 1) : int(1)

当我期待时:

max(1, "a", "2"   ) : string(1) "2"
max(1, "2", "a"   ) : string(1) "2"
max(   "a", "2", 1) : string(1) "2"
max(   "2", "a", 1) : string(1) "2"

min(1, "a", "2"   ) : string(1) "a"
min(1, "2", "a"   ) : string(1) "a"
min(   "a", "2", 1) : string(1) "a"
min(   "2", "a", 1) : string(1) "a"

请注意,max()min() 函数的值始终相同,但顺序不同。

此外,根据文档,与整数比较时,不以数字字符开头的字符串被评估为整数0,但多个字符串值按字母数字进行比较。来源:

如何解释这个输出?

【问题讨论】:

    标签: php comparison


    【解决方案1】:

    min()max() 中的比较是按顺序进行的,这可以在源代码中看到:

    min() source code:

    //...
    min = &args[0];
    
    for (i = 1; i < argc; i++) {
        is_smaller_function(&result, &args[i], min);
        if (Z_TYPE(result) == IS_TRUE) {
            min = &args[i];
        }
    }
    //...
    

    max() source code:

    //...
    max = &args[0];
    
    for (i = 1; i < argc; i++) {
        is_smaller_or_equal_function(&result, &args[i], max);
        if (Z_TYPE(result) == IS_FALSE) {
            max = &args[i];
        }
    }
    //...
    

    因此您可以看到该函数遍历数组并检查下一个值是否小于/大于先前保存的最小/最大值。


    要了解如何获得这些结果,您还必须知道值的比较是在 PHP type juggling. 之后完成的

    让我们看两个例子来看看函数是如何工作的:

    示例 1

    max ( 1 , 'a' , '2' )
          │    │     │
          1 > 'a'    │
            │        │
            1    <  '2'
                 │
                 └ Result: '2'
    
    1. 比较1'a',数值上下文意味着'a'被转换为01大于0
      →int 1返回

    2. 比较1'2',数字字符串意味着'2'被转换为22大于1
      →字符串'2'返回

    • 结果:字符串 '2'

    示例 2

    max ( 1 , '2' , 'a' )
          │    │     │
          1 < '2'    │
            │        │
           '2'   <  'a'
                 │
                 └ Result: 'a'
    
    1. 比较1'2',数字字符串意味着'2'被转换为22大于1
      →字符串'2'返回

    2. 比较'2''a',两个字符串都表示字符串比较,'a'大于'2'只是和ASCII values比较。
      →返回字符串'a'

    • 结果:字符串'a'

    同样的规则适用于所有其他示例。

    【讨论】:

    • 这个答案有道理,我也放心了,但是哪里说比较是按顺序进行的呢? PHP 文档似乎缺少此信息。
    • @AndréAntunesdaCunha 您可以从一些示例中得出它是按顺序排列的,但实际上手册中并没有清楚地这样写。
    • @u_mulder 您不应该将源代码行链接到 master 分支,因为代码会不断发展,行不再准确。例如,链接到提交哈希。
    • 我的答案是过自己的生活o_O)))
    猜你喜欢
    • 2015-07-06
    • 2018-09-13
    • 2012-08-26
    • 2012-03-15
    • 2018-02-11
    • 2010-09-06
    • 2018-04-18
    • 2014-09-25
    相关资源
    最近更新 更多