iPhone/iPadのホーム画面コンテスト開催中!賞品は iTunes カード!

PHP 2008/04/25 03:11

PHP 配列を回すならforかforeachか

今日、社内で「PHPの配列をループで回すのにforを使うか、foreachを使うか」という話が面白かったので、メモ。

ここでいう配列はキーが数字で、0からの連番であることを想定してます。(キーが数字以外や連番で無い場合は、foreachを使います。)

例えば↓のようにDBテーブルからレコードを読み込んだ内容が入ってる場合、$listをループで回すならforとforeachのどちらを使うべきかという話です。

PHP:
  1. <?php
  2. $list = array();
  3. $list[] = array('id' => 1, 'name' => 'hoge');
  4. $list[] = array('id' => 2, 'name' => 'foo');
  5. $list[] = array('id' => 3, 'name' => 'bar');
  6. ?>

for文派

PHP:
  1. <?php
  2. for ($i = 0 ; $i <count($list); $i++) {
  3.   echo $list[$i]['id'] . PHP_EOL;
  4.   echo $list[$i]['name'] . PHP_EOL;
  5. }
  6. ?>

1. ループ内でデータが直感的に参照できる

$listが2次元配列になっているのが分かっているので、直感的にデータへ参照できる。

2. 誰でも知っている構文である

プログラムを知っていれば、誰でも分かる。(foreachに比べると)

3. 参照する変数が変わらない

まあ1.とほぼ同じですが、$listのデータを参照・操作したいので、$list変数へ参照した方が分かりやすい。

=> foreachだとループ内で参照する変数が変わるのが直感的で無い。

foreach派

PHP:
  1. <?php
  2. foreach ($list as $id => $rec) {
  3.   echo $id . PHP_EOL;
  4.   echo $rec['name'] . PHP_EOL;
  5. }
  6. ?>

1. 添え字が数字だろうが、何だろうが要素を順番に参照できる

(PHPでは全てもともと連想配列ですが)リストかハッシュかを意識する必要が無い。

さらに言うとIteratorをimplementしていれば、どのようなデータ構造でもforeachでループを回せる。

2. 参照すべき変数を限定できる

上の例でいうと、ループ内では$listを意識する必要はなく、$idもしくは$recさえ知っておけば要素へ参照できる。

またループ内では$listがどういう構造なのかも知る必要がない。

3. 要素の内容を表す変数名で参照できる

配列は$listだが、添え字を$id・要素を$recと、内容を表す変数が指定できるので、分かりやすい。

おまけ. 若干早い

以前取ったベンチでは、foreach()の方が早かった。ただ配列の要素数が数十程度では大した差にはならないのでそれほど神経質にならなくても良い。

PHPではforeachで

個人的には連想配列しか無いPHPでは、配列は単純にforeachで回すというルールで良いと思います。

私自身はforeach派なのですが、for文派の1や3のようにあくまで配列をイメージして各要素に参照したいというのを利点として挙げていたのが新鮮でした。(私は$list[$i]['name']と参照するのが冗長に感じていたので。)

forかforeachか、みなさんはどちらでしょう?

追記(2008/04/26):

皆さんコメントありがとうございます!確認した限りでは、全員foreach派で、for文派はいませんでした;-)。やはりPHPではforeachを使うのが一般的のようです。

以下、foreach派のコメントを。

  • rytich foreach派
  • @shimooka iteratorのように配列の要素数を意識しなくていいのが楽です>foreach
  • @lllnorikolll 私もforeachが多いです。
  • @junya バグの入る余地が少ないからforeachのほうが好み
  • @nazo 全要素に対して何かするならforeach、指定回数何かするならfor
  • @sonkm3 for よりは foreach の方が好きだな。インデックス用の変数ってうっかりしやすいから。。。
  • id:creazynet 今はほぼforeachだけですね。for→foreachを使う様になった時がjava脳→php脳に変わった瞬間だった気がします。
  • id:Kiske 普段はforeach、処理データ大きいときはwhile使ってる / while(list($key, $value) = each($array)){...}
  • id:heavenshell ほぼ foreach かなぁ。

関連エントリ



■Related Posts

12 Responses to “PHP 配列を回すならforかforeachか”

  1. on 25 4月 2008 at 12:45 1.xnights said …

    私はforeach派ですかね。
    ・無限ループがありえない
    この理由が大きいかと。

  2. on 25 4月 2008 at 18:15 2.0x20 said …

    foreachはうっかりarray以外がわたったらそこで落ちるんだよなー。
    とかいいつつforeachばっか使ってます。
    function is_arr(&$arr){$arr=(is_array($arr))?$arr:array();}
    なんてやったりして。

  3. on 26 4月 2008 at 19:56 3.shinbara said …

    xnightsさん:
    >・無限ループがありえない
    なるほど。これもありますね。

    0x20さん:
    確かにforeachでもforでも渡す値を
    チェックしておく事は必要ですね。

  4. on 09 9月 2008 at 17:55 4.Hajime said …

    forだとbreakが使えますよね。

  5. on 13 12月 2008 at 14:59 5.PHP屋 said …

    for ($i = 0 ; $i
    では、最後の行は処理されませんよ!

  6. on 03 1月 2009 at 01:25 6.tell-k said …

    forとforeachの例で実行結果が異なるようになっているのはわざとなんでしょうか?なんかすごい気になって。。。

  7. on 04 1月 2009 at 20:05 7.shinbara said …

    Hajimeさん:
    foreachでもbreakが使えますよー

    PHP屋さん:
    $listは0から始まっているので問題無いかと。

    tell-kさん:
    ここではforとforeachの構文での比較なので、実行結果にはあまり意味を持ちません。
    と言ってもそれほど大きなズレは無いと思うのですが、どの部分が気になりましたか?

  8. on 19 1月 2010 at 21:43 8.POSTで受け取ったデータの改行をとる(foreach,stripslashes,str_replace):PHP個人的メモ said …

    [...] http://www.1x1.jp/blog/2008/04/php_for_vs_foreach.html [...]

  9. on 10 2月 2010 at 15:19 9.tan_go238 said …

    だいぶ昔のPOSTですが誰も言及してないので。。
    forだと一回ループする度にcount()が走るから遅くなるのだと思います。

    $count = count($list);
    for ($i = 0 ; $i <$count; $i++){

    のようにすると若干速くなるかもしれませんね^^

  10. on 10 2月 2010 at 15:22 10.tan_go238 said …

    だいぶ昔のPOSTですが誰も言及してないので。。
    forだと一回ループする度にcount()が走るから遅くなるのだと思います。

    $count = count($list);
    for ($i = 0 ; $i <$count; $i++){

    のようにするとfor文でも若干速くなるかもしれませんね^^

  11. on 13 3月 2010 at 15:21 11.jada said …

    forの方がいい場合を考えてみました。
    DBテーブルからレコードを読み込んだ時点で$idがsortされていなくて、$idの順番に表示するような場合。
    (データベースならソートして読めばいいのですが、ソートしていないファイルを読んだ場合などでも)
    なんてのはどうでしょう。

  12. on 09 6月 2010 at 02:29 12.tell-k said …

    >tell-kさん:
    >ここではforとforeachの構文での比較なので、実行結果にはあまり意味を持ちません。
    >と言ってもそれほど大きなズレは無いと思うのですが、どの部分が気になりましたか?

    あぁすいません。ものすごく遅レスです。

    foreach版の

    echo $id . PHP_EOL;

    の部分は配列の添字なので echoされるのは「 0 1 2 」なのに対して、for版は

    echo $list[$i]['id'] . PHP_EOL;

    なのでechoされるのが「1 2 3」なのが気になっただけです。。。本題とは全く関係ないですm(_ _)m

Trackback This Post | Subscribe to the comments through RSS Feed

Leave a Reply