14
10

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 1 year has passed since last update.

【PHP】foreachで配列の最初と最後の処理を制御する

Last updated at Posted at 2020-03-12

目的

php foreach 最初と最後」「php foreach 最後」「php foreach last」などで検索すると、少し微妙な例ばかり出てきたので書いてみました。
なるべくベストパターンを載せるように努めていますが、何かあれば編集リクエストもしくはコメントを送っていただけると助かります。

PHP 7.3以上の場合

実装


$array = ['a', 'b', 'c', 'a']; // 0始まりでない配列や連想配列でもOK
foreach ($array as $index => $value) {
    if ($index === array_key_first($array)) {
        // 最初(始端処理)
        echo 'おはよう!', '<br>';
    }

    echo $value, '<br>';

    if ($index === array_key_last($array)) {
        // 最後(終端処理)
        echo 'おやすみ。', '<br>';
    }
}

結果


おはよう!
a
b
c
a
おやすみ。

PHP 7.3未満の場合

公式にPolyfillが載っているため、それに従いましょう。
(array_key_lastの方はUser Contributed Noteですが)

PHP: array_key_first
https://www.php.net/manual/ja/function.array-key-first.php#refsect1-function.array-key-first-notes

PHP: array_key_last
https://www.php.net/manual/ja/function.array-key-last.php#123016

実装


// 関数定義
if (!function_exists('array_key_first')) {
    function array_key_first(array $arr) {
        foreach($arr as $key => $unused) {
            return $key;
        }
        return NULL;
    }
}
if (!function_exists("array_key_last")) {
    function array_key_last(array $arr) {
        if (empty($arr)) {
            return NULL;
        }

        return array_keys($arr)[count($arr) - 1];
    }
}

// メイン処理
$array = ['a', 'b', 'c', 'a']; // 0始まりでない配列や連想配列でもOK
foreach ($array as $index => $value) {
    if ($index === array_key_first($array)) {
        // 最初(始端処理)
        echo 'おはよう!', '<br>';
    }

    echo $value, '<br>';

    if ($index === array_key_last($array)) {
        // 最後(終端処理)
        echo 'おやすみ。', '<br>';
    }
}

結果


おはよう!
a
b
c
a
おやすみ。

アンチパターン集

reset, endを使うパターン

バグるので絶対に使ってはいけません。
reset()は配列の最初の要素を返すため、要素に重複があると複数回実行されてしまいます。
end()も同様です。

実装


$array = ['a', 'b', 'c', 'a'];
foreach ($array as $value) {
    if ($value === reset($array)) {
        // 最初(始端処理)
        echo 'おはよう!', '<br>';
    }

    echo $value, '<br>';

    if ($value === end($array)) {
        // 最後(終端処理)
        echo 'おやすみ。', '<br>';
    }
}

結果


おはよう!
a
おやすみ。
b
c
おはよう!
a
おやすみ。

現在のインデックスをインクリメントするパターン

最後の判定だけ行うやつです。
インクリメントが冗長だしトレースがだるいのでおすすめしません。

実装


$array = ['a', 'b', 'c', 'a'];
$i = 0;
foreach ($array as $value) {

    echo $value, '<br>';
    $i++;

    if ($i === count($array)) {
        // 最後(終端処理)
        echo 'おやすみ。', '<br>';
    }
}

結果


a
b
c
a
おやすみ。

動作環境

  • PHP 7.4.1
14
10
6

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
14
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?