書ききったあとに調べると上質な記事見つけちゃうよね。
PHP array キャストのススメ - Qiita
上記の記事の劣化説明になります。
ので、本文は読まなくていいです。
変なコーディングルールに対して正しいと思うコードがあるけど確証が無いよ無いなら作るよシリーズ
前回 : PHPの配列の作成は初期化と代入のどちらが速いのか - Qiita
結論
[$value]
と(array)$value
は完璧に一致ではない。
オブジェクトを考慮しなければ、null
の場合の違いから
(array)$value
を支持したい。
オブジェクトも考慮し、おそらく実装者が一番実現したかったことを推測すると、
$array = is_object($value) ? [$value] : (array) $value;
がベストだと思う。
環境
経緯
「引数に配列で無いものも受け取るが、配列として処理する」場合、
function hoge($value) {
if (is_array($value)) {
$array = $value;
} else {
$array = [$value];
}
foreach ($array as $value) {
//...とか
}
というコードが量産されていた。
昔からforeach
のnull
チェックやarray
チェック省略に、
foreach( (array)
を信奉していた自分としてはどうも美しくない。
PHPのforeach文でnullチェックなしでエラー回避|リスティング広告の運用代行ならカルテットコミュニケーションズ
ここらでいっちょコード書いて投稿して、誤っていたら知識を更新しようと思います。
コード
<?php
function A($value) {
if (is_array($value)) {
$array = $value;
} else {
$array = [$value];
}
return $array;
}
function B($value) {
return (array)$value;
}
$values = [
0,
1,
'',
'test',
[],
['test'],
['test2' => 'test2'],
true,
false,
new stdClass,
fopen('php://stdin', 'r'),
];
foreach ($values as $value) {
if (A($value) !== B($value)) {
var_dump(A($value));
var_dump(B($value));
}
}
echo "end\n";
array(1) {
[0]=>
NULL
}
array(0) {
}
array(1) {
[0]=>
object(stdClass)#1 (0) {
}
}
array(0) {
}
end
オブジェクトやnull
自体がArray
に変換できる性質上、他のスカラー型などと異なり
配列に入れられたオブジェクト or null
と
配列に変換されたオブジェクト or null
の違いが生まれてしまいます。
後々foreach
で処理すると考えれば、
null
はキャストがありがたい。
オブジェクトはキャストが迷惑。
と言えるケースが多くなるんじゃないかと思います。
オブジェクトの配列を(foreach
で)処理したいが、オブジェクト一つだけをそのまま渡されても処理したい。
という場合は注意が必要かと思いました。
…もともとのコードは5行にもなるのが不格好なので、三項演算子を使えば
$array = is_array($value) ? $value : [$value];
でまあ中々いいんじゃないでしょうか?
さらに三項演算子ならスマートなままオブジェクト対応も出来そうです。
$array = is_object($value) ? [$value] : (array) $value;