2011-09-24 62 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中更新。