PHPで連想配列に値を入れ、以下のようにforeachで回すと、$dataに代入された順に

「hoge1 hoge2 hoge3」と出力されますが、この順番は将来に渡って保証されているものなのでしょうか?

perlの場合保証されていない、ということを聞いたので気になりました。
保証されている場合、参考資料などありましたら教えて下さい。

また、この代入の順番を期待するようなやり方は、通常の配列($data[0]など)を
使ってやるのがセオリーなのでしょうか。よろしくお願いします。

$data = array('hoge1'=>'1','hoge2'=>'2','hoge3'=>'3');

foreach ($data as $key => $value) {
  echo $key." ";
}

■結果
hoge1 hoge2 hoge3

回答の条件
  • 1人2回まで
  • 登録:2009/07/26 11:57:00
  • 終了:2009/08/02 12:00:02

回答(5件)

id:pahoo No.1

pahoo回答回数5960ベストアンサー獲得回数6332009/07/26 12:20:46

ポイント20pt

保証されません。

たまたま、ご利用の環境で保証されているように見えても、他の環境(とくにPHPのバージョンやOSが異なる場合)で動作させたときの保証はありません。


ご質問にあるように配列のキーを整数にしたとしても、foreach で回す場合にはキー順になるかどうかは保証されません。

事前にソートするか、for 文で回すのが無難です。

id:xxmasaxx

回答有り難うございます。うーむ保証されないのですか。

参考にさせて頂きます。

2009/07/26 20:31:52
id:b-wind No.2

b-wind回答回数3344ベストアンサー獲得回数4402009/07/26 12:24:41

ポイント20pt

この順番は将来に渡って保証されているものなのでしょうか?

保証される。


PHP: ������ - Manual

PHP の連想配列はいわゆる連想配列と内部的に大きく違う。

キーの順序は保証され、配列と連想配列に内部的には区別がない。配列は数字のみをキーとした連想配列に過ぎないからだ。

配列と連想配列の混合データすら作成可能だ。

このような構造は他の言語ではほとんど見られない。

良いか悪いは分からないが、そのようなデータ構造になっている。

実際にそれぞれの時点でどのような内部表現になっているかは var_dump 関数を用いると分かるようになっている。

PHP: var_dump - Manual


perlの場合は連想配列はシンプルにキーから値を取り出すことのみを保証しているだけなので、

キーの順序は保証されない。

もちろん実装として保証する物が存在する可能性はあるが、少なくとも Perl 言語の仕様ではない。

id:xxmasaxx

リンク先拝見しました。

明示的に順番は保証されているという記述は見つかりませんでしたが、

PHPでは配列と連想配列は一緒なんですね。なるほど。参考にさせて頂きます。

回答有り難うございました。

2009/07/26 20:41:36
id:yofukaci No.3

yofukaci回答回数306ベストアンサー獲得回数102009/07/26 18:34:10

ポイント20pt

PHP言語で規定されてない限り、保証はされません。

また、現状のバージョンでも保証はされません。

id:xxmasaxx

ネットで検索してみると、サイトによっては順番どうりになる、ならないと分かれるようで、正直分からなくなりました。。

ともあれ回答有り難うございました。参考にさせて頂きます。

2009/07/26 20:43:43
id:ymlab No.4

ymlab回答回数506ベストアンサー獲得回数332009/07/27 00:10:21

ポイント20pt

http://www.itl.dm.u-tokai.ac.jp/~hiroshi/education/sprg/txt/sp06...

5.7章 配列の順次処理

によると、

for と違って処理順は意識されないが,内部順序に基づいて処理される.

と書いてあるので、連想配列であるなしに関わらず意識はされないようです。

私もそういうときは、面倒だと思いつつ、

連想配列をおforeachで回して配列に入れ直してソートしています。

asortを使った方が速いかも知れませんが・・・。

http://php.benscom.com/manual/ja/function.asort.php

id:xxmasaxx

「内部順序」が具体的にどういう仕組みなのか、ちょっと気になりました。

ソートしなければならないとなると、ちょっと面倒っぽいですね。。回答有り難うございます。

2009/07/28 14:16:55
id:takano32 No.5

takano32回答回数58ベストアンサー獲得回数52009/07/27 11:03:18

ポイント20pt

保証されません。

内部のデータ構造について言及されてい方もいらっしゃるようですが、そのデータ構造自体が変化しないことが保証されていません。内部の構造は隠蔽されていると考え変更の対象となることも多いでしょう。

foreach という言葉の定義から外れることはないと思いますので、それぞれの要素について処理を施すという用途にのみ用いたほうがよいでしょう。

# 極論では foreach という構文についても将来的にこの構文が残ると確実に保証されることはありません。

id:xxmasaxx

そもそもPHP自体バージョンが上がると色々変わるので、

それらを念頭に入れて開発したほうがよさげですね。

回答有り難うございました。

2009/07/28 17:10:16
  • id:b-wind
    ふむ。回答者によって微妙に質問の解釈が違うのはおもしろいね。

    自分の主張はあくまで内部表現どおりに処理されるという物だ。間違ってもキー順に処理されるなどとは言っていない。
    質問文が、「代入順」となっているのでそれに即した回答をしたつもり。
    また、内部表現に期待するのは危険という指摘があるのはもっともだが現在の所その変更のされ方は明示されている
      http://jp.php.net/manual/ja/language.types.array.php
    また、内部表現を前提とした配列(連想配列)のソート関数も数多い。これらはすべて内部表現を変更するためのみに存在する。
      http://jp.php.net/manual/ja/array.sorting.php
    なにが「保証されない」としているかは回答者によって違うので一概には言えないが、これらの実装が
    それぞれマニュアル中に処理結果が明示されている点について、一つご意見を伺いたいな。

    これだけ変わった言語も珍しいとは思うが実装としてはこうなっている。
    ちなみに、PHPの「言語仕様」とやらは自分は見たことが無いのだが、存在するのかな?
    存在するのであれば自分も是非見てみたいので教えて欲しい。


    まぁこれだけの構造、いきなり仕様変更されることは考えにくいがPHPに限っては結構前科があるからなぁ。
    この点に限っては PHP 言語を選択した際のリスクとしてとらえるしか無さそう。

この質問への反応(ブックマークコメント)

トラックバック

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません