質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

1933閲覧

for と foreachのつきまして

pegy

総合スコア243

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2017/10/23 00:45

以下のように多次元配列の中で、末端の配列の先頭を削除して詰めるコードを
書いているのですが、下記の1も2も等価であり同じように処理ができると考えていたのですが
2については、何も処理されません。2で意図した処理がされないことについて、ご質問させてください。

宜しくお願い申し上げます。

PHP

1/1 2$hoge=[[1,2,3],[4,5,6]]; 3 4for ($i=0; $i <count($hoge) ; $i++) { 5array_splice($hoge[$i],0,1); 6} 7print_r($hoge); 8/*結果 9Array 10( 11 [0] => Array 12 ( 13 [0] => 2 14 [1] => 3 15 ) 16 17 [1] => Array 18 ( 19 [0] => 5 20 [1] => 6 21 ) 22 23) 24*/ 25 26 27 28 29/2 30foreach ($hoge as $key) { 31 array_splice($key,0,1); 32} 33print_r($hoge); 34/*結果 35Array 36( 37 [0] => Array 38 ( 39 [0] => 1 40 [1] => 2 41 [2] => 3 42 ) 43 44 [1] => Array 45 ( 46 [0] => 4 47 [1] => 5 48 [2] => 6 49 ) 50 51) 52*/

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

forの方では$hogeを直接処理していますが、foreachの方では$keyに対して処理しているからですね
$keyをリファレンスで処理すれば同じ処理になります。

PHP

1foreach ($hoge as &$key) { 2 array_splice($key,0,1); 3} 4/* 追記 5リファレンスは使用後削除すること 6*/ 7unset($key);

投稿2017/10/23 00:56

編集2017/10/23 03:23
yambejp

総合スコア114829

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pegy

2017/10/23 00:59

コメント有難うございます。 なるほど、破壊的関数を使用する場合には、置き換わった変数ではなく直接(この場合にはリファレンス変数)変数を処理することに留意する必要があるのですね。 勉強になりました!
miyabi-sun

2017/10/23 02:55 編集

http://php.net/manual/ja/control-structures.foreach.php > unset($value); // 最後の要素への参照を解除します 補足です。 これは慣習なのですがリファレンスのforeachを使用した場合、 公式サイトでも上記のような行を用いて紹介しているように、foreachを抜けた直後で変数に対してunsetを付けましょう。 今回yambejpさんは`foreach ($hoge as &$key) {`と宣言していますが、 foreachを抜けた後も`&$key`の参照は残っているので、 次の行で`unset($key)`としましょう。
yambejp

2017/10/23 02:48

miyabi-sunさん、フォローありがとうございます まさにおっしゃる通りだとおもいます 変数の使い回しをする可能性がある限りリファレンスしたものは 使わなくなった時点で削除すべきでした
miyabi-sun

2017/10/23 02:57

強い言い方になっていたので修正しました。 回答のコアな部分としては不要と思いつつ、 バグを埋め込まない形ということで補足としてコメントとしてぶら下げてます。
yambejp

2017/10/23 03:04

miyabi-sunさん ちなみに foreach ($hoge as &$key) { array_splice($key,0,1); unset($key); } と foreach ($hoge as &$key) { array_splice($key,0,1); } unset($key); は、どちらがいいと思います?
miyabi-sun

2017/10/23 03:13

前者は初見ですね。今まで後者でやってました。 基本的には後者持ちですが、前者はこの辺が主張にできそうでどっちも良さそうですね。 ・副作用を`{}`の中に記述出来るので、外のブロックスコープが汚れない ・foreachに修正入って`&$key`が外に出ていかなくなってもエラーを回避できそう
yambejp

2017/10/23 03:21

なるほど。 私も後者で十分だと思いますが、使い回しという言う意味では 前者を推奨する方もいるのかなと思いまして・・ 問題なさそうなので、回答に追記しておきます
pegy

2017/10/23 03:35

miyabi-sun様 yambejp様 参照への解除につきまして、ご追記有難うございます。 公式も確認いたしました。宜しくお願い申し上げます。
miyabi-sun

2017/10/23 03:38

> yamabejpさん 対応ありがとうございます!
guest

0

プログラム中に回答を書いてみましたが、これで分かりますでしょうか?

PHP

1<?php 2//Case1 3$hoge =[[1,2,3],[4,5,6]]; 4 5for ($i=0; $i <count($hoge) ; $i++) { 6array_splice($hoge[$i],0,1); 7} 8print_r($hoge); 9 10//再度、値を設定する 11$hoge =[[1,2,3],[4,5,6]]; 12//Case2 13foreach ($hoge as $key) { 14 //$keyの内容はここで[2,3]または2回目のループ時には[5,6]となっていますが 15 //$hogeの内容は変更されていません 16 //array_splice($key,0,1); 17 18 //こうやって別の変数に値を入れてあげると結果が等しくなります。 19 array_splice($key,0,1); 20 $fuga[] = $key; 21} 22//$fugaを出力 23print_r($fuga); 24//$hogeは何も変わらず 25print_r($hoge);

投稿2017/10/23 00:53

motuo

総合スコア3027

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pegy

2017/10/23 01:16

コメント有難うございます。 yambejp様のように変数を参照にするか、仰るよう異なる変数に格納するかどちらもできそうですね。 加えて、非破壊的に取扱いたい場合には、敢えてforeachでこのようにやる方法もあるかなと気づきました。 深謝します!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問