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);
?>
ちゃんと参照となっているようです。
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("サイバー田中", "俺の行き先?あの太陽にでも聞いてくれ");
// arrayの要素をコピーにしてみる。
$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 |
コメント