2011-11-27 32 views
12

直到在WP_Admin_Bar Object周圍3.3beta1項目可以使用這種類型的語法來訪問,例如更改CSS類的現有的菜單項中的一個:在PHP中,如何訪問對象中的「:private」數組?

$wp_admin_bar->menu->{'wp-logo'}['meta']['class'] = 'new-class'; 

當運行print_r($wp_admin_bar)輸出看起來是這樣這樣的:

WP_Admin_Bar Object 
(
    [menu] => stdClass Object 
     (
      [my-account] => Array 
       (

然而,圍繞3.3beta2爲不再更改菜單項的CSS類以上語法的工作原理,並從print_r($wp_admin_bar)輸出顯示不同的結構,其對象版本:

WP_Admin_Bar Object 
(
    [nodes:WP_Admin_Bar:private] => Array 
     (
      [my-account] => stdClass Object 
       (
        [id] => my-account 

       ) 

我認識到,WordPress的可能不希望我的菜單擺弄這樣的,如果有這樣做更規範的方式,我喜歡使用它,但據我所知,只有有兩個功能可用於修改管理欄add_menu_itemremove_menu_item,這些功能不能靈活地執行諸如更改現有菜單項的屬性等操作。

爲了確認,我查看了wp-includes/class-wp-admin-bar.php很明顯,Wordpress已經改變了他們定義變量的方式。

老班

class WP_Admin_Bar { 
    var $menu; 
    var $proto = 'http://'; 
    var $user; 

新類

class WP_Admin_Bar { 
    private $nodes = array(); 
    private $root = array(); 

    public $proto = 'http://'; 
    public $user; 

所以我的問題是,如果我有機會獲得global $wp_admin_bar對象,是有我的方式,我可以訪問內部nodes:WP_Admin_Bar:private的對象?如果不是,是否有另一種方法來獲得這些對象,例如創建一個新的類來擴展WP_Admin_Bar類,然後從那裏訪問對象?

PS:我試圖克服這一挑戰在不改變核心WordPress的文件...

鏈接到文件:http://phpxref.ftwr.co.uk/wordpress/nav.html?wp-includes/class-wp-admin-bar.php.source.html

回答

5

將它們更改爲受保護的成員變量並擴展該類。

無論誰寫私人成員的班級有效地使班級「最終」。這表明,你應該始終寫你的成員爲受保護的,除非有真正的理由否則。

希望可以幫助...

+0

添加了與該類文件的鏈接。希望通過擴展它而不是改變核心文件來克服這個問題。 – cwd

+0

你的問題看起來非常好。也許你可以在發佈之前提交一個帶有這個問題鏈接的錯誤報告。他們可能願意改變它以滿足您的需求。 http://codex.wordpress.org/Reporting_Bugs – Homer6

+0

我認爲這是最好的事情。謝謝。 http://core.trac.wordpress.org/ticket/19371 – cwd

1

如果我理解正確的話你的問題,你問,如果你可以訪問一個對象的私有變量,但我想你知道除非在課堂上有一種方法,否則你不知道,所以這可能是一個無用的答案,但以防萬一:

看看類'代碼。它是否有任何方法來檢索這些變量,如get_nodes(),get_root()等?如果沒有,你有3個選擇:重新編碼類設置變量公共,重新編碼類並添加方法,或重新編碼類和設置變量保護,然後創建一個新類擴展父類與這些方法(我推薦這一個,因爲它對父類的影響較小)。

無論如何,如果你不能重新編碼的類,它沒有get方法,你將無法訪問這些私有變量。

+0

你」我正在混淆私人與保護在這裏,編輯。 – NotGaeL

8

如果你不想觸及核心文件,那麼你必須使用Reflection

$adminBar = new WP_Admin_Bar(); 
$reflector = new ReflectionObject($adminBar); 
$nodes = $reflector->getProperty('nodes'); 
$nodes->setAccessible(true); 
print_r($nodes->getValue($adminBar)); 

的hackish的替代方法是鑄造的對象數組,然後做:

$adminbar = (array) new WP_Admin_Bar; 
$nodes = $adminbar[chr(0) . 'WP_Admin_Bar' . chr(0) . 'nodes']; 
print_r($nodes); 
+0

我會嘗試'反射',看看是否有效。不知道我是否可以將它轉換爲數組,因爲我需要反對仍然可以被類使用,以便它可以被渲染。感謝您的詳細解答:) – cwd

+0

這對我很好。接受的答案不回答這個問題!有時你不能在沒有侵入另一方的代碼的情況下更改對象... – squarecandy

+0

反射效果很好..以前從來不知道這一點 – Ankit