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

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

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

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

Q&A

解決済

2回答

2361閲覧

レファレンス代入しているとき、セッターする意味はあるでしょうか?

re97

総合スコア208

PHP

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

0グッド

1クリップ

投稿2016/03/22 11:24

編集2016/03/23 10:04

下記コードで、_bプロパティの値を格納している箇所を探しています
・これはリファレンス代入なので、$cの値が変更されれば、_bプロパティの値も変更される、ということでしょうか?
・もうそうなら、_aメソッドはセッターでも何でもないということでしょうか?
・privateメソッドの意味はない?

private function _a( ) {
$c =& $this->_b;

_bプロパティの値をセットしているところを探すには、 $c も追いかけなくてはいけない?


前提条件を一部間違えていたため、修正します
・引数は渡していました

private function _a( $hoge=null ) {
$c =& $this->_b[$this->getVal('id') . $this->getVal('name')];

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

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

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

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

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

guest

回答2

0

ベストアンサー

・これはリファレンス代入なので、$cの値が変更されれば、_bプロパティの値も変更される、ということでしょうか?

まずこの代入を行うと,$this->_bが使用している値を$cも使用するようになります.この後は,$cが変更されれば$this->_bは変更されますし,$this->_bが変更されれば$cも変更されます.unsetでリファレンスを解除することをどこかで行わない限り,この2つの変数名は互いにエイリアスのような扱いになります.が,$cの寿命はこのメソッドの内部だけなので,その外部で$cという変数を追う必要はありません.

・もうそうなら、_aメソッドはセッターでも何でもないということでしょうか?

そもそも引数が何もない時点でセッターの定義から外れています.

・privateメソッドの意味はない?

publicかprivateかは無関係です.

備考

「参照型」と「参照渡し」は全く別の概念なので注意してください.PHPにおいてはオブジェクトやリソースが参照型で,それ以外は値型に相当します.参照渡しは型に関わらず&をつけて代入されているかがすべてを決定します.

これを踏まえて,PHPコミッタの人が書いた以下の記事を読んでみると動きがよくわかると思います.「参照型」についてはあまり触れられていませんが,「参照渡し」については完全に網羅されています.

上記内容をもとに今回述べたことを正確に書くと

PHP5

シンボル$this->_bに対応するzval構造体へのポインタを,シンボル$cからも対応付けます.そして,zval構造体の参照カウントを1増加させます.更にzval構造体の参照フラグを有効にし,この後の操作でzval構造体が内包する値に変更があっても,コピーオンライトが走らないようにします.

なお,ポインタ参照は「zval構造体」と「zvalue_value共用体が指す数値以外の値」で2回発生しています.

シンボルテーブル -> zval.value.lval = 整数
シンボルテーブル -> zval.value.str.val -> 文字列

PHP7

シンボル$this->bと既存のzval構造体の間に,zend_reference構造体を内包する新しいzval構造体が入り込む形になります.その上で,シンボル$c$this->bと同様の新しいzval構造体に対応するようになります.これにより,この後の操作でzval構造体が内包するzend_reference構造体が内包するzval構造体が内包する値に関して変更があっても,コピーオンライトが走らないようにします.

なお,ポインタ参照は「zend_value共用体が指す数値以外の値」でしか発生しません.PHP7が速くなった理由はこれです.しかし今回のようにzend_reference構造体はポインタ参照の対象となってしまうのが難点です.

シンボルテーブル.zval.value.lval = 整数
シンボルテーブル.zval.value.str.val -> 文字列
シンボルテーブル.zval.value.ref -> val.value.lval = 整数

投稿2016/03/22 15:12

編集2016/03/22 15:55
mpyw

総合スコア5223

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

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

re97

2016/03/23 10:12

・回答ありがとうございました >$cの寿命はこのメソッドの内部だけなので,その外部で$cという変数を追う必要はありません ・この部分を知りたかったので、参考になりました ・ちなみに、リファレンス代入自体よく分かっていないため、提示いただいたリンクを確認している最中なのですが、「<値型>と<参照型>、<値渡し>と<参照渡し>について実行例を出す(PHP編)」で、call_user_func(function ()を使用しているのはなぜでしょうか? ・第1引数として無名関数(?)を渡しているだけで、第2引数以下を渡していないように見えるのですが ・試しに、最初の「値の値渡し」をcall_user_funcなしで試したら、同じ結果(1, 2)になりました ・4つまとめて書くため? それともスコープの関係か何かなのでしょうか?
mpyw

2016/03/23 10:19

4例のスコープを分離するために念のため分けているだけですね.呼び出し側にリファレンスのかかった変数は存在していないので,これは無くても結果に影響はないです.元ネタのC/C#などのコードがスコープ分離されていたのでそれに倣っただけです.これらの言語は { } で括るだけでそれがスコープになりますが,PHPはそうじゃないので…
re97

2016/03/24 08:53

・再度の回答ありがとうございました ・大変参考になりました
guest

0

・もうそうなら、_aメソッドはセッターでも何でもないということでしょうか?

参照以前にセットしたい値を引数を取っていない時点でセッターとは言いがたいのではないでしょうか。

・privateメソッドの意味はない?
_bプロパティの値をセットしているところを探すには、 $c も追いかけなくてはいけない?

見たところ $c はメソッド内のローカル変数ですが、global 宣言が質問にあたって省略されているだけでしょうか。
このメソッド内でのみ$c$this->_aという記述のショートカットとして利用可能にしたいだけという印象を受けます。
その場合はメソッドの外に登場する $c は別物なので追いかける必要はありません。

ところどころ推測で言っている部分が違ったらすみません。

投稿2016/03/22 15:42

tozjp

総合スコア790

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

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

re97

2016/03/23 10:06

・回答ありがとうございました ・確認してみましたが、global 宣言は付与されていませんでした >その場合はメソッドの外に登場する $c は別物なので追いかける必要はありません。 ・この点を知りたかったので、参考になりました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問