3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

配列でなければ配列にする処理に[$value]は不要か?(array)キャストではダメなの?

Posted at

書ききったあとに調べると上質な記事見つけちゃうよね。
PHP array キャストのススメ - Qiita
上記の記事の劣化説明になります。
ので、本文は読まなくていいです。


変なコーディングルールに対して正しいと思うコードがあるけど確証が無いよ無いなら作るよシリーズ

前回 : PHPの配列の作成は初期化と代入のどちらが速いのか - Qiita

結論

[$value](array)$valueは完璧に一致ではない。

オブジェクトを考慮しなければ、nullの場合の違いから
(array)$value
を支持したい。
オブジェクトも考慮し、おそらく実装者が一番実現したかったことを推測すると、

$array = is_object($value) ? [$value] : (array) $value;

がベストだと思う。

環境

Docker PHP:7.0.8

経緯

「引数に配列で無いものも受け取るが、配列として処理する」場合、

function hoge($value) {
    if (is_array($value)) {
        $array = $value;
    } else {
        $array = [$value];
    }

    foreach ($array as $value) {
    //...とか
}

というコードが量産されていた。
昔からforeachnullチェックや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;
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?