Solarized
HOME > WEBプログラム覚書 > PHP4 func_get_args()とforeachと参照
PHP4 func_get_args()とforeachと参照
まだまだPHP4は現役ですね。
久しぶりにPHP4でコード書いてたら肝心なところがコピー扱いでハマりました。
テストコード
PHP
- <?php
- class Man
- {
- var $name;
- var $comment;
-
- function Man($name, $comment)
- {
- $this->name = $name;
- $this->comment = $comment;
- }
-
- function view()
- {
- printf("<h5>「%s」 - %s -</h5>", $this->comment, $this->name);
- }
- }
-
- class Mens
- {
- var $mens = array();
-
- function Mens()
- {
- foreach (func_get_args() as $man) {
- $this->mens[] =& $man;
- }
- }
-
- function view()
- {
- foreach ($this->mens as $man) {
- $man->view();
- }
- }
- }
-
- $man_1 = new Man("ハリ美jyun", "俺はもう既に本物のヒョウなのかもしれない");
- $man_2 = new Man("JMC パンサー", " 3秒だ。野郎を倒すのも女をオトすのもな");
- $man_3 = new Man("サイバー田中", "俺の行き先?あの太陽にでも聞いてくれ");
-
- $mens = new Mens($man_1, $man_2, $man_3);
- $mens->view();
-
- var_dump($man_1 === $mens->mens[0]);
- var_dump($man_2 === $mens->mens[1]);
- var_dump($man_3 === $mens->mens[2]);
- ?>
実行結果
「俺の行き先?あの太陽にでも聞いてくれ」 - サイバー田中 -
「俺の行き先?あの太陽にでも聞いてくれ」 - サイバー田中 -
「俺の行き先?あの太陽にでも聞いてくれ」 - サイバー田中 -
bool(false)
bool(false)
bool(true)
なんじゃいこりゃ!?
func_get_args()では参照渡しができない
上記ページに書かれているようにfunc_get_arg()は参照に対応していないので
array()でまとめて渡すようにします。
PHP
- <?php
- class Man
- {
- var $name;
- var $comment;
-
- function Man($name, $comment)
- {
- $this->name = $name;
- $this->comment = $comment;
- }
-
- function view()
- {
- printf("<h5>「%s」 - %s -</h5>", $this->comment, $this->name);
- }
- }
-
- class Mens
- {
- var $mens = array();
-
- function Mens(&$mens)
- {
- foreach ($mens as $man) {
- $this->mens[] =& $man;
- }
- }
-
- function view()
- {
- foreach ($this->mens as $man) {
- $man->view();
- }
- }
- }
-
- $man_1 = new Man("ハリ美jyun", "俺はもう既に本物のヒョウなのかもしれない");
- $man_2 = new Man("JMC パンサー", " 3秒だ。野郎を倒すのも女をオトすのもな");
- $man_3 = new Man("サイバー田中", "俺の行き先?あの太陽にでも聞いてくれ");
-
- $mens = new Mens($mens = array(&$man_1, &$man_2, &$man_3));
- $mens->view();
-
- var_dump($man_1 === $mens->mens[0]);
- var_dump($man_2 === $mens->mens[1]);
- var_dump($man_3 === $mens->mens[2]);
- ?>
「俺の行き先?あの太陽にでも聞いてくれ」 - サイバー田中 -
「俺の行き先?あの太陽にでも聞いてくれ」 - サイバー田中 -
「俺の行き先?あの太陽にでも聞いてくれ」 - サイバー田中 -
bool(false)
bool(false)
bool(true)
変化なし。というかそもそもなんで全部最後のオブジェクトになってるの??
なんかそっちが気になってきました。
foreach は参照ではなくコピー
上記ページでdisられてるようにforeachはコピーとなります。
残念ながらforで対応するしかないようです。
PHP
- <?php
- class Man
- {
- var $name;
- var $comment;
-
- function Man($name, $comment)
- {
- $this->name = $name;
- $this->comment = $comment;
- }
-
- function view()
- {
- printf("<h5>「%s」 - %s -</h5>", $this->comment, $this->name);
- }
- }
-
- class Mens
- {
- var $mens = array();
-
- function Mens(&$mens)
- {
- for ($i=0; $i<count($mens); $i++) {
- $this->mens[] =& $mens[$i];
- }
- }
-
- function view()
- {
- for ($i=0; $i<count($this->mens); $i++) {
- $this->mens[$i]->view();
- }
- }
- }
-
- $man_1 = new Man("ハリ美jyun", "俺はもう既に本物のヒョウなのかもしれない");
- $man_2 = new Man("JMC パンサー", " 3秒だ。野郎を倒すのも女をオトすのもな");
- $man_3 = new Man("サイバー田中", "俺の行き先?あの太陽にでも聞いてくれ");
-
- $mens = new Mens($mens = array(&$man_1, &$man_2, &$man_3));
- $mens->view();
-
- var_dump($man_1 === $mens->mens[0]);
- var_dump($man_2 === $mens->mens[1]);
- var_dump($man_3 === $mens->mens[2]);
- ?>
実行結果
「俺はもう既に本物のヒョウなのかもしれない」 - ハリ美jyun -
「 3秒だ。野郎を倒すのも女をオトすのもな」 - JMC パンサー -
「俺の行き先?あの太陽にでも聞いてくれ」 - サイバー田中 -
bool(true)
bool(true)
bool(true)
とりあえず期待通りの出力になりました。
ほんとに参照になってるか確認してみます。
上記コードに下記を追加
PHP
- <?php
- $man_1->name = "TEST";
- var_dump($mens->mens[0]->name);
- ?>
実行結果
string(4) "TEST"
ちゃんと参照となっているようです。
PHP4 におけるオブジェクトの比較
最初の例から === が不穏なtrue返してたんで調べてみたら
PHP4ではオブジェクトの比較は == も === も差がないとのこと。
PHP4では、とてもシンプルな作法でオブジェクトを比較できます。すなわち、 二つのオブジェクトは同じ属性と同じ値を持ち、
同じクラスのインスタンス である場合には等しいのです。二つのオブジェクトを比較演算子 (===)で比較した場合でも同様のルールとなります。
PHP: におけるオブジェクトの比較 - Manual
mens配列の要素をコピーにしてみます。
PHP
- <?php
- class Man
- {
- var $name;
- var $comment;
-
- function Man($name, $comment)
- {
- $this->name = $name;
- $this->comment = $comment;
- }
-
- function view()
- {
- printf("<h5>「%s」 - %s -</h5>", $this->comment, $this->name);
- }
- }
-
- class Mens
- {
- var $mens = array();
-
- function Mens(&$mens)
- {
- for ($i=0; $i<count($mens); $i++) {
- $this->mens[] =& $mens[$i];
- }
- }
-
- function view()
- {
- for ($i=0; $i<count($this->mens); $i++) {
- $this->mens[$i]->view();
- }
- }
- }
-
- $man_1 = new Man("ハリ美jyun", "俺はもう既に本物のヒョウなのかもしれない");
- $man_2 = new Man("JMC パンサー", " 3秒だ。野郎を倒すのも女をオトすのもな");
- $man_3 = new Man("サイバー田中", "俺の行き先?あの太陽にでも聞いてくれ");
-
-
- $mens = new Mens($mens = array($man_1, $man_2, $man_3));
- $mens->view();
-
- var_dump($man_1 === $mens->mens[0]);
- var_dump($man_2 === $mens->mens[1]);
- var_dump($man_3 === $mens->mens[2]);
-
- $man_1->name = "TEST";
- var_dump($mens->mens[0]->name);
-
- var_dump($man_1 === $mens->mens[0]);
- ?>
「俺はもう既に本物のヒョウなのかもしれない」 - ハリ美jyun -
「 3秒だ。野郎を倒すのも女をオトすのもな」 - JMC パンサー -
「俺の行き先?あの太陽にでも聞いてくれ」 - サイバー田中 -
bool(true)
bool(true)
bool(true)
string(13) "ハリ美jyun"
bool(false)
確かにコピーなのにtrueとなってますね・・・
うーんPHP4で同じオブジェクトか調べるにはどうしたらいいんでしょうか?
PHP5では改善されてます。
上記の2点はPHP5では改善されてます。最初のコードの =& を = にすれば問題なく動きます。やったね。
PHP
- <?php
- class Man
- {
- var $name;
- var $comment;
-
- function Man($name, $comment)
- {
- $this->name = $name;
- $this->comment = $comment;
- }
-
- function view()
- {
- printf("<h5>「%s」 - %s -</h5>", $this->comment, $this->name);
- }
- }
-
- class Mens
- {
- var $mens = array();
-
- function Mens()
- {
- foreach (func_get_args() as $man) {
- $this->mens[] = $man;
- }
- }
-
- function view()
- {
- foreach ($this->mens as $man) {
- $man->view();
-
- }
- }
- }
-
-
- $man_1 = new Man("ハリ美jyun", "俺はもう既に本物のヒョウなのかもしれない");
- $man_2 = new Man("JMC パンサー", " 3秒だ。野郎を倒すのも女をオトすのもな");
- $man_3 = new Man("サイバー田中", "俺の行き先?あの太陽にでも聞いてくれ");
-
- $mens = new Mens($man_1, $man_2, $man_3);
- $mens->view();
-
- var_dump($man_1 === $mens->mens[0]);
- var_dump($man_2 === $mens->mens[1]);
- var_dump($man_3 === $mens->mens[2]);
-
- $man_1->name = "TEST";
- var_dump($mens->mens[0]->name);
-
- var_dump($man_1 === $mens->mens[0]);
- ?>
実行結果
「俺はもう既に本物のヒョウなのかもしれない」 - ハリ美jyun -
「 3秒だ。野郎を倒すのも女をオトすのもな」 - JMC パンサー -
「俺の行き先?あの太陽にでも聞いてくれ」 - サイバー田中 -
bool(true)
bool(true)
bool(true)
string(4) "TEST"
bool(true)
| 投稿日 |
2009年7月28日 11:48 |
| カテゴリ |
PHP |
| タグ |
テストコード | 言語仕様 |
| トラックバック URL |
http://www.kantenna.com/cgi-bin/mt504/mt-tb.cgi/1179 |