2011-09-24 75 views
0

我有一些代码用于从PHP构建HTML表。缺少PHP数组孙子

<?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($表),而正确地var_dumping的TR的元件,并不的var_dump孙子td元素 - 注意空数组[ “TD”] =>数组(0){}

待办事项你知道为什么会发生这种情况吗?

它是否与返回的$ tr元素是$ table ['tr']元素的副本而不是引用有关?在这种情况下,为什么添加tr到表中工作,向tr添加td时不行?

谢谢!

+0

我会在这一个上采取更面向对象的方法。 –

回答

3

问题就出在你的new_tr()函数:创建

function new_tr(&$table, $class) 
{ 
    $tr = array('class' => $class, 'td' => array()); 

    $table['tr'][] = $tr; 

    return $tr; 
} 

的方式$这里TR,意味着它是一个将被复制在必要时定期变量。它确实被添加到$ table中,因为这是一个参考。

PHP在写入时使用copy,因此当代码返回$ 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 = 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) { 
     } 
    } 
    } 
} 
+0

明智的答案。函数定义中的&符号是我不知道该怎么做的。这既解决了眼前的问题,也教会了我如何将其应用于其他情况。非常感谢! – HoboBen

0
$table['tr'][] = $tr; 

这条线将创建tr添加到数组,但要注意,一旦你回到$tr,它的生命是自己的生命。当您修改它时,该值不会在table中更新。