Secura Vita

Category: Works > PHP » PHP:配列のループ処理で最後のみ処理を変える(foreach,while)
2016/02/08
Works

PHP:配列のループ処理で最後のみ処理を変える(foreach,while)

PHP:配列のループ処理で最後のみ処理を変える(foreach,while)

配列を修理してる際に最後のみ処理を変更したいってことよくありますよね。

最後のみクラスを変えたいというよな時です。

いろいろ方法あったりするんですが、それを検証しつつ紹介したいと思います。

ループについてはこちら↓

PHP:配列をfor・while・foreachを使ってループさせて取り出す(2016/02/05)

スポンサーリンク

カウント処理をする

一番無難でわかりやすいカウント処理です。

//foreach
$args = array( 1 , 2 , 3 , 4 , 5 );
$count = count( $args );
$i = 1;
foreach( $args as $val) {
    ++$i;
    if( $i > $count ) {
        echo '<li class="last">' . $val . '</li>';  
    } else {
        echo '<li>' . $val . '</li>';
    }
}
 
//while          
$args = array( 1 , 2 , 3 , 4 , 5 );
$count = count( $args );
$i = 1;
while( list( $key , $val ) = each( $args ) ) {
    ++$i;
    if( $i > $count ) {
        echo '<li class="last">' . $val . '</li>';  
    } else {
        echo '<li>' . $val . '</li>';
    }
}

結果はどちらもこうなります。

<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li class="last">5</li>

end()を使う

調べると結構出てくる方法です。

//foreach
$args = array( 1 , 2 , 3 , 4 , 5 );
$end = end( $args );
foreach( $args as $val ) {
    if( $val === $end ) {
        echo '<li class="last">' . $val . '</li>';  
    } else {
        echo '<li>' . $val . '</li>';
    }
}

//while
$args = array( 1 , 2 , 3 , 4 , 5 );
$end = end( $args );
reset( $args );
while( list( $key , $val ) = each( $args ) ) {
    if( $val === $end ) {
        echo '<li class="last">' . $val . '</li>'; 
    } else {
        echo '<li>' . $val . '</li>';    
    }
}

結果

<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li class="last">5</li>

end( $args )で配列の最後を取得し、現在の値と同じか調べる方法です。

each()を使う場合、reset()しないとおかしなことになりますのでご注意を!

注意事項

この方法には問題があって、最後の値と同じものが配列内にがあった場合不具合を起こします。

$args = array( 1 , 2 , 3 , 4 , 3 );

結果

<li>1</li>
<li>2</li>
<li class="last">3</li>
<li>4</li>
<li class="last">3</li>

値を比較してるわけですから当然ですよね。

current()を使う

whileで使える方法です。foreachではポインタの扱いが変わるみたいでうまくいきませんでした。

$args = array( 1 , 2 , 3 , 4 , 5 );
while( list( $key , $val ) = each( $args ) ) {
    if( current( $args ) === false ) {
        echo '<li class="last">' . $val . '</li>'; 
    } else {
        echo '<li>' . $val . '</li>';    
    }
} 

結果

<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li class="last">5</li>

each()はループを処理する際にはじめに配列から値を取り出しポインタを次に進めるという処理が行われるのでcurrent()には次の値が入っています。
のでcurrent()があるかどうか調べてます。

注意事項

条件分岐はかならず完全比較にしておいて下さい。

if( !current( $args ) ) {
if( empty( current( $args ) ) ) {

これでは不具合が起きます。

<li>1</li>
<li class="last">2</li>
<li></li>
<li>4</li>
<li class="last">1</li>

なぜなら最後のcurrent()には「bool(false)」が入り、「!」や「empty」でもtrueを返してしまうからです。

あと配列に0やnullではなく「false」がセットされてた場合は同様の不具合が起きるのでご注意を。

結局のところ

結局カウントで分岐させたほうが確実ってことですね。
どういうデータになるかわからない場合はカウント処理しといたほうが無難です。

カウント処理は配列の中身はまったく関係ないですし。

スポンサーリンク
おもしろかった・役に立った