はじめに
array_multisortで引っかかったので備忘録として書きました
動作確認環境
OS | PHP version |
---|---|
Windows 10 | 7.2.11 |
確認データ
以下の配列データをranking列の値が低い順にソートします
weather | ranking |
---|---|
晴れ | 2 |
雨 | 3 |
曇り | 1 |
ソートしてみる
正しい使い方
まずは正しい使い方を記載します
<?php
// ソート対象
$sort_data = array();
array_push($sort_data, ['weather' => '晴れ', 'ranking' => 2]);
array_push($sort_data, ['weather' => '雨', 'ranking' => 3]);
array_push($sort_data, ['weather' => '曇り', 'ranking' => 1]);
// ソートするキーを設定
$target_keys = array();
foreach ($sort_data as $k => $v) $target_keys[$k] = $v['ranking'];
// ソート前のデータを出力
print_r("ソート前\n");
print_r($sort_data);
// 昇順ソート
array_multisort($target_keys, SORT_ASC, $sort_data, SORT_NUMERIC);
// ソート後のデータを出力
print_r("ソート後\n");
print_r($sort_data);
結果は以下となります
ソート前
Array
(
[0] => Array
(
[weather] => 晴れ
[ranking] => 2
)
[1] => Array
(
[weather] => 雨
[ranking] => 3
)
[2] => Array
(
[weather] => 曇り
[ranking] => 1
)
)
ソート後
Array
(
[0] => Array
(
[weather] => 曇り
[ranking] => 1
)
[1] => Array
(
[weather] => 晴れ
[ranking] => 2
)
[2] => Array
(
[weather] => 雨
[ranking] => 3
)
)
正しくソートされていますね
間違った使い方
間違った使い方です
<?php
// ソート対象
$sort_data = array();
array_push($sort_data, ['weather' => '晴れ', 'ranking' => 2]);
array_push($sort_data, ['weather' => '雨', 'ranking' => 3]);
array_push($sort_data, ['weather' => '曇り', 'ranking' => 1]);
// ソートするキーを設定
$target_keys = array();
foreach ($sort_data as $k => $v) $target_keys[$k] = $v->ranking;
// ソート前のデータを出力
print_r("ソート前\n");
print_r($sort_data);
// 昇順ソート
array_multisort($target_keys, SORT_ASC, $sort_data, SORT_NUMERIC);
// ソート後のデータを出力
print_r("ソート後\n");
print_r($sort_data);
結果は以下となります
ソート前
Array
(
[0] => Array
(
[weather] => 晴れ
[ranking] => 2
)
[1] => Array
(
[weather] => 雨
[ranking] => 3
)
[2] => Array
(
[weather] => 曇り
[ranking] => 1
)
)
ソート後
Array
(
[0] => Array
(
[weather] => 晴れ
[ranking] => 2
)
[1] => Array
(
[weather] => 雨
[ranking] => 3
)
[2] => Array
(
[weather] => 曇り
[ranking] => 1
)
)
ソートされませんね
原因
単純にキーの設定でアロー演算子を使っているのが原因
foreach ($sort_data as $k => $v) $target_keys[$k] = $v->ranking;
対象データは連想配列であるためアロー演算子ではとってこれない
実際に$target_keysの値を見てみると空が入っている
Array
(
[0] =>
[1] =>
[2] =>
)
アロー演算子でとってくる場合、対象データ以下のように変更する必要がある
<?php
// ソート対象
$sort_data = array();
$data1 = new \stdClass();
$data1->weather = '晴れ';
$data1->ranking = 2;
$data2 = new \stdClass();
$data2->weather = '雨';
$data2->ranking = 3;
$data3 = new \stdClass();
$data3->weather = '曇り';
$data3->ranking = 1;
array_push($sort_data, $data1);
array_push($sort_data, $data2);
array_push($sort_data, $data3);
// array_push($sort_data, ['weather' => '晴れ', 'ranking' => 2]);
// array_push($sort_data, ['weather' => '雨', 'ranking' => 3]);
// array_push($sort_data, ['weather' => '曇り', 'ranking' => 1]);
// ソートするキーを設定
$target_keys = array();
foreach ($sort_data as $k => $v) $target_keys[$k] = $v->ranking;
// ソート前のデータを出力
print_r("ソート前\n");
print_r($sort_data);
// 昇順ソート
array_multisort($target_keys, SORT_ASC, $sort_data, SORT_NUMERIC);
// ソート後のデータを出力
print_r("ソート後\n");
print_r($sort_data);
オブジェクトに入れたものならば大丈夫。当たり前ですね。
NOTICEエラーを出すようにしよう
初歩的なミスですが、NOTICEエラー非表示で開発していたためこのエラー出力されず30分画面とにらめっこしてました...
NOTICEエラーを出すと以下のようなエラーが出力されます
PHP Notice: Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11
Notice: Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11
PHP Notice: Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11
Notice: Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11
PHP Notice: Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11
Notice: Trying to get property 'ranking' of non-object in C:\Users\work\test\test.php on line 11
開発時はNOTICEエラーを出力するようにしよう...