为什么排序会失败?

8

我正在编写一个库例程,其中包括对嵌套数组进行一些相当复杂的排序。

从文档中我看到,所有的数组排序函数(包括使用内置比较器的函数)都可能在失败时返回false——但这种情况何时会出现呢?


这需要添加到文档中。有人已经为此提交了错误报告吗?https://bugs.php.net/ - colan
4个回答

10

如果你发送给函数的变量不是数组,那么它将失败
示例:

asort('Hello');//fails
asort(array(1,2,35,7,2,8,3));//true

4
应将此处理为异常而非返回类型。 - Raveline
5
或许这就是应该的方式,但事实并非如此。它确实像maniator所说的那样运作。 - Mark Baker
1
@Mark Baker和@Nils Werner:你们说得完全正确。这就是为什么a)我的评论只是一个评论,b)我使用了情态动词“应该”的原因。 - Raveline
2
有人能肯定地验证这是 sort() (等等)返回 FALSE 的 唯一 条件吗?否则,这个答案可能会误导人! - Doin
2
实际上这不是唯一的条件:例如,如果要排序的某些项本身就是数组,则会失败。请参见此处:http://stackoverflow.com/a/14707486/999120 - Doin
显示剩余5条评论

3

我也遇到了这个问题,并进行了一些研究,如果有其他条件,则排序返回false。查看代码后发现此排序函数。

PHP_FUNCTION(sort)
{
    zval *array;
    zend_long sort_type = PHP_SORT_REGULAR;
    compare_func_t cmp;

    ZEND_PARSE_PARAMETERS_START(1, 2)
        Z_PARAM_ARRAY_EX(array, 0, 1)
        Z_PARAM_OPTIONAL
        Z_PARAM_LONG(sort_type)
    ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);

    cmp = php_get_data_compare_func(sort_type, 0);

    if (zend_hash_sort(Z_ARRVAL_P(array), cmp, 1) == FAILURE) {
        RETURN_FALSE;
    }
    RETURN_TRUE;
}

在第一眼看上去,你会发现sort函数只在zend_hash_sort失败时返回false。zend_hash_sort是一个宏,实际上调用了zend_hash_sort_ex。这个函数非常稳健,在传递不可比较元素的数组的所有情况下都会返回成功,详见此处
这将我们带回到sort函数,该函数使用宏进行参数检查,并有三条规则。
  1. 该函数至少需要一个参数,最多两个参数。

  2. 第一个参数必须是一个数组

  3. 第二个参数(如果给出)必须是一个长整型

因此,如果违反这三个规则中的任何一个,sort函数只会返回false。
$a = false;
sort($a); // fails because of rule 2
$a = [];
sort($a, "test"); // failes because of rule 3
sort($a, 0, "test"); // failes because of rule 1

2
当提供的参数不是一个数组(或者甚至只是一个空数组)时。

-1

返回 false 的示例可能包括空数组、变量不是数组、可用内存不足、库调用失败、排序模块运行时失败、调用参数无效、磁盘包或驱动器未联机、排序算法或方法与开发地区或国家的规则不兼容。


3
抱歉,“开发者”,但是这个回答有很多地方都是明显错误的。 - symcbean
@开发者:如果你想有益地回答这个问题,你必须积极地确定PHP sort()函数实际上返回FALSE的“一般排序失败条件”类型。从被接受的答案来看,那只会是“变量不是数组”。如果出现其他情况,它们可能会导致运行时错误,而不是FALSE返回值。 - Doin
+1'd this. 在没有ISO规范说明的情况下,该函数可以因任何原因返回false。即使实现设计者觉得没有明显的原因也可以这样做。这听起来很荒谬,但是在任何地方都没有硬性保证。 - Luke A. Leber

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接