在PHP中如何访问对象中的“:private”数组?

时间:2011-11-27 15:54:49

标签: php arrays wordpress object data-structures

使用这种类型的语法可以访问WP_Admin_Bar Object中的大约3.3beta1个项目,例如更改现有菜单项之一的CSS类:

$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

3 个答案:

答案 0 :(得分:11)

如果您不想触摸核心文件,则必须使用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);

答案 1 :(得分:6)

将它们更改为受保护的成员变量并扩展该类。

无论是谁与私人成员一起撰写课程,都会使课程“最终”。这表明你应该总是把你的成员写成受保护的,除非有一个真正的,非常好的理由不这样做。

希望有帮助...

答案 2 :(得分:1)

如果我理解你的问题,你会问你是否可以访问一个对象的私有变量,但我想你知道你不能,除非在课堂上有一个方法,所以这可能是一个微不足道的非有用的答案,但以防万一:

查看类的代码。是否有任何方法来检索这些变量,如get_nodes(),get_root()等?如果没有,你有3个选择:重新设置类set vars public,重新编写类并添加方法,或重新编码类并设置变量protected,然后创建一个新类,用这些方法扩展父类(我推荐这个方法) ,因为它对父类的影响较小。)

无论如何,如果你不能重新编写类并且它没有get方法,你将无法访问这些私有变量。