我有一些用于从PHP构建HTML表的代码。
<?php
function new_table($class)
{
$table = array('class' => $class, 'tr' => array());
return $table;
}
function new_tr(&$table, $class)
{
$tr = array('class' => $class, 'td' => array());
$table['tr'][] = $tr;
return $tr;
}
function new_td(&$tr, $class, $content)
{
$td = array('class' => $class, 'content' => $content);
$tr['td'][] = $td;
return $td;
}
?>
用法:
$table = new_table('admin whoami');
$tr = new_tr($table, 'head');
new_td($tr, 'field', 'Field');
new_td($tr, 'value', 'Value');
$tr = new_tr($table, 'body');
new_td($tr, 'field', 'Name');
new_td($tr, 'value', $my_name);
echo '--- tr ---'.chr(10);
var_dump($tr);
echo '--- table ---'.chr(10);
var_dump($table);
结果:
--- tr ---
array(2) {
["class"]=>
string(4) "body"
["td"]=>
array(2) {
[0]=>
array(2) {
["class"]=>
string(5) "field"
["content"]=>
string(4) "Name"
}
[1]=>
array(2) {
["class"]=>
string(5) "value"
["content"]=>
string(5) "user0"
}
}
}
--- table ---
array(2) {
["class"]=>
string(12) "admin whoami"
["tr"]=>
array(2) {
[0]=>
array(2) {
["class"]=>
string(4) "head"
["td"]=>
array(0) {
}
}
[1]=>
array(2) {
["class"]=>
string(4) "body"
["td"]=>
array(0) {
}
}
}
}
如果你注意到,var_dump($ tr)正确地转储了tr,包括子td元素。
然而,var_dump($ table)虽然正确地var_dumping tr元素,但并没有var_dump孙子td元素 - 注意空数组[“td”] =&gt; array(0){}
你知道为什么会这样吗?
它与返回的$ tr元素有关,是$ table ['tr']元素的副本而不是引用吗?在这种情况下,为什么在向tr添加td时,在表中添加tr不起作用?
谢谢!
答案 0 :(得分:3)
问题在于你的new_tr()函数:
function new_tr(&$table, $class)
{
$tr = array('class' => $class, 'td' => array());
$table['tr'][] = $tr;
return $tr;
}
这里创建$ tr的方式意味着它是一个常规变量,必要时会被复制。它确实被添加到$ table中,因为这是一个参考。
PHP使用copy on write,所以当代码返回$ tr时,你添加到$ table,而你返回的$ tr实际上仍然是同一个变量。
但是当你在new_td()中写入它时,PHP确定它需要复制,因为它不是对某些东西的引用。所以此时你的调用脚本中的$ tr和$ table数组中相应的$ tr实际上是两个独立的变量/值。所以new_td()得到了$ tr的副本,而不是你在new_tr()中创建的那个。
要解决此问题,您需要使new_tr函数实际创建对TR的引用,并返回它作为引用创建的TR:
// Return the created TR as a reference by adding the ampersand here.
function &new_tr(&$table, $class)
{
$tr = array('class' => $class, 'td' => array());
// The TR in $table needs to be a reference to the value we're returning
// because we want to modify this exact variable instead of some copy.
$table['tr'][] =& $tr;
return $tr;
}
现在当你运行它并且你的代码调用new_td($ tr)时,它实际上正在修改你添加到$ table的变量:
$table = new_table('admin whoami');
$tr =& new_tr($table, 'head');
new_td($tr, 'field', 'Field');
// EDIT: Note how you need to create a reference here aswell. This is to
// make $tr a reference to the return value of new_tr() instead of a value copy.
$tr =& new_tr($table, 'body');
echo '--- table ---'.chr(10);
var_dump($table);
结果:
--- table ---
array(2) {
["class"]=>
string(12) "admin whoami"
["tr"]=>
array(2) {
[0]=>
array(2) {
["class"]=>
string(4) "head"
["td"]=>
array(1) {
[0]=>
array(2) {
["class"]=>
string(5) "field"
["content"]=>
string(5) "Field"
}
}
}
[1]=>
&array(2) {
["class"]=>
string(4) "body"
["td"]=>
array(0) {
}
}
}
}
答案 1 :(得分:0)
$table['tr'][] = $tr;
此行会将创建的tr
添加到数组中,但请注意,一旦返回$tr
,它就会过着自己的生命。修改它时,不会在table
。