66
77 < title > 参照渡し | PHP-TECHNIQUE | SOCKET-MANAGER Framework For PHP</ title >
88 < meta name ="description " content ="当フレームワークで使っているPHPの技術情報「参照渡し」についての説明です " />
9- < meta content ="PHP,参照渡し " name ="keywords ">
9+ < meta content ="PHP,参照渡し,websocket,minecraft,bedrock " name ="keywords ">
1010
1111 < script async src ="https://www.googletagmanager.com/gtag/js?id=G-LF9W695NNW "> </ script >
1212 < script >
@@ -115,35 +115,38 @@ <h2 class="subtitle">お決まりの書き方</h2>
115115}
116116 </ pre > < br />
117117
118- 上記のように関数呼び出しでリターン値以外のデータを取得したい時によく使われる方法だと思います 。< br />
118+ 上記のように関数呼び出しでリターン値以外のデータも取得したい時によく使われる方法だと思います 。< br />
119119 他にもクロージャーとのデータのやり取りをする場合にも使われる事がありますが、ここで注目すべきは< code > $test</ code > という引数の先頭に< code > &</ code > (アンパサンド)が付いているところです。< br /> < br />
120120
121- これはC言語でもよく使われる書き方で「アドレス渡し」と呼ばれています。< br />
122- PHPとC言語ではコンパイラの処理に違いがあるので、PHP側の処理では「参照渡し」と呼ぶ事にします。< br />
123- まずは「アドレス渡し」の考え方を理解しておいた方が早いと思いますので以下をご覧ください。< br />
121+ これはC言語でもよく使われる書き方で「アドレス渡し」と呼ばれていますが、PHPは昔からC言語を部分的にリスペクトしているような傾向があるので、これもその一つだと思っています。< br />
122+ PHPとC言語ではコンパイラの処理に違いがあるので、PHP側の処理では「参照渡し」と呼ぶ事にします。< br /> < br />
123+
124+ まずは「アドレス渡し」の考え方を理解しておいた方が分かり易いと思いますので以下をご覧ください。< br />
124125 </ div > < br />
125126
126127 < a id ="address "> </ a >
127128 < h2 class ="subtitle "> 「アドレス渡し」について</ h2 >
128129
129130 < div class ="text-block ">
130- 現実世界で例えるならば、仮に東京100番地という住所に両親と子供を合わせて3人家族の山田さんの家があったとすると、この「東京100番地」がメモリ上の配置を表していて、山田さんの家が変数の番地にあたります。< br />
131- そして山田さんの家では最初3人が住んでいましたが、そのうち子供が出稼ぎに行くようになって両親の2人暮らしになったり、子供が結婚して実家に帰ってくる時には孫が増えたりする事で人数が変化していく変数だと捉える事ができます。< br /> < br />
132-
133- これをメモリ上のイメージに例えると以下のようになります。< br />
131+ 現実世界で例えるならば、仮に東京100番地という住所に以下のイメージで山田さんの家が存在していたとします。< br /> < br />
134132
135133 < img src ="./img/php-pass-by-reference/memory.png " /> < br /> < br />
136134
137- ここでいう番地とはメモリ上の住所のようなもので、不変的であり、唯一無二のものですが山田さんの家(変数)の内容は常に変化します。< br />
138- つまり「アドレス渡し」というのはこの唯一無二の番地の部分を渡している事になるので、変数のコピーを渡しているわけではなく、変数が格納されているメモリ上の実体を常に指し示す事になります。< br /> < br />
135+ この「東京100番地」という場所がメモリ上の配置を表していて、不変的であり唯一無二のものです。(C言語ではメモリ上の配置を任意で決める事ができます)< br />
136+ そして山田さんの家では最初3人が住んでいましたが、そのうち子供が出稼ぎに行くようになって両親の2人暮らしになったり、子供が結婚して孫とともに実家に戻ってくるなりして人数が変化していく変数だと捉える事ができます。< br /> < br />
137+
138+ 「アドレス渡し」というのはこの唯一無二の番地の部分を渡している事になるので、変数のコピーではなく変数が格納されているメモリ上の実体を常に指し示す事になります。< br /> < br />
139+
140+ C言語ではこのアドレス(上記の例では100という値)をポインタ変数というものに代入してアドレスそのものを変数として扱う事ができますが、PHPではこのポインタ変数というものが存在しません。
141+ PHPマニュアルには以下のように書かれています。< br />
139142
140- C言語ではこのアドレスをポインタ変数というものに代入してアドレスそのものを変数として扱う事ができますが、PHPではこのポインタ変数というものが存在しません。PHPのマニュアルでもそう書かれています。< br />
141- そして以下のようにも書かれていますがUnixシステムの事をご存じでない方もおられると思いますので、同じ場所を指し示すラベルのようなものだと考えてもらった方が分かり易いかもしれません。< br />
142143 < blockquote >
143144 リファレンスは、Unix ファイルシステムの ハードリンクのようなものであると考えられます。
144145 </ blockquote >
145146
146- つまりPHPでは< code > &</ code > (アンパサンド)を使って変数の所在をラベルのようなもので管理しているのに対して、C言語では< code > &</ code > (アンパサンド)を使ってアドレス表記が可能で、ポインタ変数を使ってそのアドレス自身を管理する事ができます。< br />
147+ Unixシステムの事をご存じでない方もおられると思いますので、同じ場所を指し示すラベルのようなものだと考えてもらった方が分かり易いかもしれません。< br /> < br />
148+
149+ つまりPHPでは< code > &</ code > (アンパサンド)を使って変数の所在をラベルのようなもので管理しているのに対して、C言語では< code > &</ code > (アンパサンド)を使う事でアドレス表記が可能で、ポインタ変数を使ってそのアドレス自身を管理する事ができます。< br />
147150 </ div > < br />
148151
149152 < a id ="compare "> </ a >
@@ -174,6 +177,7 @@ <h2 class="subtitle">PHPとC言語との比較</h2>
174177 < dt > 1)$outside変数に初期値としてnullを代入</ dt >
175178 < dt > 2)$outside変数を「参照渡し」でtestFunction関数の引数へ渡す</ dt >
176179 < dt > 3)testFunction関数内で$outside変数に1がセットされる</ dt >
180+ < dd > 関数内では< code > $inside</ code > 変数が常に< code > $outside</ code > 変数(山田さんの家)の所在を示していてその< code > $outside</ code > 変数を参照したり代入したりできます。</ dd >
177181 < dt > 4)1の値が標準出力へ出力される</ dt >
178182 </ dl >
179183
@@ -197,31 +201,36 @@ <h2 class="subtitle">PHPとC言語との比較</h2>
197201}
198202 </ pre > < br />
199203 ※C言語で< code > char</ code > というのは1バイトのデータ型です。< br />
200- ※C言語で変数名の前に< code > *</ code > (アスタリスク)をつけて宣言するとポインタ変数になります。また、宣言以外の処理中にアスタリスクをつけて参照するとそのアドレスが指し示す先のメモリ内容を参照できます 。< br /> < br />
204+ ※C言語で変数名の前に< code > *</ code > (アスタリスク)をつけて宣言するとポインタ変数になります。また、宣言以外のところでアスタリスクをつけるとそのアドレスが指し示す先のメモリ内容を参照できます 。< br /> < br />
201205
202206 上記をフローで表すと以下のようになります。
203207 < dl >
204208 < dt > 1)outside変数に初期値としてnullを代入</ dt >
205209 < dt > 2)outside変数を「アドレス渡し」でtestFunction関数の引数へ渡す</ dt >
206210 < dt > 3)testFunction関数内でoutside変数に1がセットされる</ dt >
211+ < dd > 関数内では< code > inside</ code > 変数をポインタ変数として扱っています。そして< code > *</ code > (アスタリスク)を付ける事で< code > outside</ code > 変数(山田さんの家)の所在を示しているのでその< code > outside</ code > 変数を参照したり代入したりできます。</ dd >
207212 < dt > 4)1の値が標準出力へ出力される</ dt >
208- </ dl >
213+ </ dl > < br />
214+
215+ < div class ="menu-line "> </ div > < br />
209216
210217 以上のように、処理の流れはいずれも同じですが変数の扱い方が異なっています。< br /> < br />
211218
212219 PHPでの< code > $inside</ code > 変数は関数定義のところで< code > &</ code > (アンパサンド)を付けて渡されていますが、関数内で値を設定する時は特別な記述をしているわけでもなく、普通に1が代入されています。< br />
213220 これに対してC言語での< code > inside</ code > 変数は関数へ< code > outside</ code > 変数を渡す時に< code > &</ code > (アンパサンド)を付けて渡されていますが、関数内ではポインタ変数として処理されています。< br /> < br />
214221
215- つまり、C言語での「アドレス渡し」はポインタ変数として制御できるのでその変数をカウントアップ等で更新すればアドレスも変化しますし、< code > inside</ code > 変数以外のメモリ領域も自由に読み書きできます。< br />
216- PHPではラベルのようなもので管理しているのでこれができません。< br />
222+ 上記のサンプルソースでは変数の値が「$inside(PHP) = *inside(C言語)」となり同じ値になりますが、C言語で「*(++inside)」と書くとカウントアップされたアドレス(101番地)が指し示す先の変数(鈴木さんの家)を参照する事になるため内容が入れ替わります。< br /> < br />
223+
224+ つまり、C言語での「アドレス渡し」はポインタ変数として制御できるのでその変数をカウントアップ等で更新すればアドレスを変更する事も可能で、< code > inside</ code > 変数以外のメモリ領域も自由に読み書きできるようになります。< br />
225+ これに対してPHP上ではこのポインタ変数の代わりにラベルのようなもので管理されている関係で< code > testFunction</ code > 関数内では常に< code > $outside</ code > 変数を指し示す事になるので、ポインタ変数のように参照先を切り替える事ができません。< br />
217226 </ div > < br />
218227
219228 < a id ="example "> </ a >
220229 < h2 class ="subtitle "> 実装例</ h2 >
221230
222231 < div class ="text-block ">
223- それではsocket -managerフレームワーク上での実装を見てみます。< br />
224- 今回対象にしているソースは以下です 。< br />
232+ それでは < font > < a href =" ./minecraft-contents/stand.html " target =" _blank " > ▶スタンドの弓矢 </ a > </ font > のソースから抜粋したsocket -managerフレームワーク上での実装を見てみます。< br />
233+ 今回対象にしている部分は以下の内容です 。< br />
225234
226235 < span > マインクラフトの相対座標の計算処理(app/UnitParameter/ParameterForMinecraft.php内)</ span >
227236 < pre color-change ="php ">
@@ -241,7 +250,7 @@ <h2 class="subtitle">実装例</h2>
241250 </ pre > < br />
242251
243252 この< code > ParameterForMinecraft</ code > クラス内で実装している< code > getRelativeCoordinates</ code > というグローバルメソッドがこれに当たります。< br />
244- そしてこのメソッドを使っている箇所で以下のように実装しています 。< br />
253+ そしてこのメソッドの呼び出し側で以下のように実装しています 。< br />
245254
246255 < span > 座標計算メソッドの呼び出し側の処理(app/CommandUnits/CommandForMinecraft.php内)</ span >
247256 < pre color-change ="php ">
@@ -264,7 +273,7 @@ <h2 class="subtitle">実装例</h2>
264273 ここではあらかじめ< code > $x</ code > 、< code > $y</ code > 、< code > $z</ code > 変数に退避した座標を< code > getRelativeCoordinates</ code > メソッドに渡して座標計算しています。< br />
265274 XYZの座標の情報を配列等のオブジェクトとして戻り値で返す事もできますが、< code > getRelativeCoordinates</ code > メソッドを通した後も< code > getCommandDataForStandArrowSpawn</ code > メソッドをコールする時にXYZ座標の変数をそのまま使いたかったので「参照渡し」にしています。< br /> < br />
266275
267- ※ここで言う「ヨー角」というのはマインクラフトワールド内での水平面の全方位を角度で表したものです。< br />
276+ ※ここで言う「ヨー角」というのはマインクラフトワールド内での水平面の全方位を角度で表したものです。(真北が0度、真南が180度になります) < br />
268277 </ div > < br />
269278
270279 < a id ="last "> </ a >
0 commit comments