0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

株式会社シンプルウェイAdvent Calendar 2023

Day 24

【Laravel】ヘルパー関数data_getの第二引数がnullの場合の挙動

Last updated at Posted at 2023-12-23

はじめに

Laravelで提供されているヘルパー関数data_getの第二引数がnullだった場合の挙動が意図しないものだったので、結果と実際どのような処理が行われているかを理解するために記事をまとめます。

実証環境

PHP 7.4
Laravel 6.2

引数による結果の違い

第二引数によって、以下ような結果になります。

$characters = [
    'player' => ['cuphead', 'mugman'],
    'boss' => ['The Root Pack', 'Goopy Le Grande', 'Ribby and Croaks']
];
dump(data_get($characters, 'player', '第二引数のキーなし'));
// array:2 [▼
//   0 => "cuphead"
//   1 => "mugman"
// ]
dump(data_get($characters, 'mob', '第二引数のキーなし'));
// "第二引数のキーなし"
dump(data_get($characters, null, '第二引数のキーなし'));
// array:2 [▼
//   "player" => array:2 [▼
//     0 => "cuphead"
//     1 => "mugman"
//   ]
//   "boss" => array:3 [▼
//     0 => "The Root Pack"
//     1 => "Goopy Le Grande"
//     2 => "Ribby and Croaks"
//   ]
// ]

1回目のdumpは第一引数に指定した配列やオブジェクトに第二引数のキーが存在するため、その中身を返しています。2回目については、キーが存在しないため、第三引数の値を返しています。
注目するのは3回目のdumpで、第二引数をnullにしたところ配列すべてが返ってきました。デフォルトを設定していますがこちらが返ってくることはありませんでした。

実際の処理

ソースコードは以下のようになっています。

function data_get($target, $key, $default = null)
{
    if (is_null($key)) {
        return $target;
    }

    $key = is_array($key) ? $key : explode('.', $key);

    while (! is_null($segment = array_shift($key))) {
        if ($segment === '*') {
            if ($target instanceof Collection) {
                $target = $target->all();
            } elseif (! is_array($target)) {
                return value($default);
            }

            $result = [];

            foreach ($target as $item) {
                $result[] = data_get($item, $key);
            }

            return in_array('*', $key) ? Arr::collapse($result) : $result;
        }

        if (Arr::accessible($target) && Arr::exists($target, $segment)) {
            $target = $target[$segment];
        } elseif (is_object($target) && isset($target->{$segment})) {
            $target = $target->{$segment};
        } else {
            return value($default);
        }
    }

    return $target;
}

処理の最初で、キーがnullなら第一引数をそのままreturnしていました。

終わりに

単純な処理ではありますが、意図しない挙動があった場合はリファレンスだけではなくてソースコードの確認をすべきだと思いました。

参考サイト

Laravel 6.x ヘルパ

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?