1

正しい並べ替え順序を決定するときに多次元配列を参照するために、「グローバル」宣言を使用するユーザー定義の並べ替え関数があります。PHP 5.1.6 では正常に動作していましたが、5.3.3 では失敗します。

コードは PHP 警告をスローします。

PHP 警告: uksort(): ユーザー比較関数によって配列が変更されました

しかし、コードは間違いなく配列を変更しません。

このコードは問題を複製します。

$arr = array();

$arr['i1']['val1'] = 99;
$arr['i1']['val2'] = 100;

$arr['i2']['val1'] = 89;
$arr['i2']['val2'] = 101;


function cmp($a, $b)
{
    global $arr;

    if ($arr[$a]['val2'] > $arr[$b]['val2']) { return 1; }
    if ($arr[$a]['val2'] < $arr[$b]['val2']) { return -1; }
    return 0;
}

if (uksort($arr, 'cmp'))
{
    echo "success";
}
else
{
    echo "failure";
}
4

2 に答える 2

1

uksort実際のキーでソートしない場合は、 butusortまたはを使用しないでくださいuasort:

function cmp($a, $b) {
    return $a['val2'] - $b['val2'];
}

uasort($arr, 'cmp');
于 2013-08-29T09:47:48.413 に答える
0

問題を回避することが非常に一般的であるため、問題の原因は次のとおりです。

global $arr;

$arrそれを解決するには、その行を削除して に置き換え$GLOBALS['arr']ます。uksortこれにより、変更メッセージが削除され、現在操作されているものではなく、シンボルテーブルからグローバル変数にアクセスしています。

例:

<?php
$arr = array();

$arr['i1']['val1'] = 99;
$arr['i1']['val2'] = 100;

$arr['i2']['val1'] = 89;
$arr['i2']['val2'] = 101;


function cmp($a, $b)
{
    if ($GLOBALS['arr'][$a]['val2'] > $GLOBALS['arr'][$b]['val2']) { return 1; }
    if ($GLOBALS['arr'][$q]['val2'] < $GLOBALS['arr'][$b]['val2']) { return -1; }
    return 0;
}

if (uksort($arr, 'cmp'))
{
    echo "success\n";
}
else
{
    echo "failure\n";
}

print_r($arr);

5.3.23 - 5.5.3 の出力: (他のバージョンのクラッシュ/誤動作)

success
Array
(
    [i1] => Array
        (
            [val1] => 99
            [val2] => 100
        )

    [i2] => Array
        (
            [val1] => 89
            [val2] => 101
        )

)

アップ、おそらくそれが最近のバージョンで警告が表示される理由です: (デモ: http://3v4l.org/DkK3v )

ここに画像の説明を入力

于 2013-08-29T10:02:25.677 に答える