MasterYodaの昼下がり

日々の備忘録的なアレ

usort、uasortの罠

phpのusort、uasort関数はユーザ定義の比較関数で配列の要素をソートできる便利な関数。

がしかし、この関数には思わぬ罠がある。

ユーザ定義関数の処理中で、下記3つの処理のいづれかが行われるとphp warningが発生する。

  • sort対象のデータをvar_dumpもしくはprint_r

  • debug_backtrace()を実行

  • Exceptionを投げる、もしくはExceptionのインスタンスを生成

発生するphp warningの内容は、

Array was modified by the user comparison function

という内容のもの。

set_error_handlerなんかでwarningを捕まえてエラーにしている環境の場合、 思わぬところで落ちたりする。

冒頭で罠と書いたが、この挙動はphpのバグらしい。

https://bugs.php.net/bug.php?id=50688

サンプルコード

<?php

$list = array(2,1);

function cmp($a, $b)
{
    if ($a === $b) {
        return 0;
    }

    $e = new Exception();

    return $a - $b;
}

usort($list,"cmp");
var_dump($list);

結果

PHP Warning:  usort(): Array was modified by the user comparison function in /tmp/test.php on line 16
array(2) {
  [0]=>
  int(1)
  [1]=>
  int(2)
}