2011-11-27 35 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