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

时间:2021-08-19 08:19:21

Up until around 3.3beta1 items in the WP_Admin_Bar Object could be accessed using this type of syntax, for example to change the CSS class of one of the existing menu items:

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

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

When running print_r($wp_admin_bar) the output looked something like this:

运行print_r($ wp_admin_bar)时,输出看起来像这样:

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

However, around version 3.3beta2 the above syntax for changing a menu item's CSS class no longer works, and the output from print_r($wp_admin_bar) reveals a different structure for that object:

但是,在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

                )

I realize that Wordpress may not want me fiddling with the menus this way, and if there was a more standardized way to do this I would love to use it, but as far as I know there are only two functions that are available to modify the admin bar, add_menu_item and remove_menu_item, and these do not give the flexibility to do things like changing the attributes of existing menu items.

我意识到Wordpress可能不希望我以这种方式摆弄菜单,如果有更标准化的方法来做这件事,我很乐意使用它,但据我所知,只有两个功能可用于修改管理栏,add_menu_item和remove_menu_item,这些都不能灵活地执行更改现有菜单项的属性等操作。

To confirm, I looked at wp-includes/class-wp-admin-bar.php it is clear that Wordpress has changed the way they define the variables.

为了确认,我查看了wp-includes / class-wp-admin-bar.php很明显,Wordpress已经改变了他们定义变量的方式。

Old Class

老班

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

New Class

新课程

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

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

So my question is if I have access to the global $wp_admin_bar object, is there I way I can access the objects inside nodes:WP_Admin_Bar:private? And if not, is there another way to get to these objects, such as creating a new class that extends the WP_Admin_Bar class and then accessing the objects from there?

所以我的问题是,如果我有权访问全局$ wp_admin_bar对象,我是否可以访问节点内的对象:WP_Admin_Bar:private?如果没有,是否有另一种方法来获取这些对象,例如创建一个扩展WP_Admin_Bar类的新类,然后从那里访问对象?

ps: I'm trying to overcome this challenge without changing the core Wordpress files...

ps:我试图在不改变核心Wordpress文件的情况下克服这一挑战......

Link to the file: http://phpxref.ftwr.co.uk/wordpress/nav.html?wp-includes/class-wp-admin-bar.php.source.html

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

3 个解决方案

#1


6  

Change them to protected member variables and extend the class.

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

Whoever wrote the class with private members effectively made the class "final". Which goes to show that you should always write your members as protected, unless there's a really, REALLY good reason to do otherwise.

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

Hope that helps...

希望有帮助......

#2


11  

If you dont want to touch the core files, then you have to use Reflection:

如果你不想触摸核心文件,那么你必须使用Reflection:

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

The hackish alternative would be casting the object to array and then doing:

hackish替代方案是将对象转换为数组,然后执行:

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

#3


1  

If I understand correctly your question, you're asking if you can access an object's private variables, but I guess you know you can't unless there's a method for it in the class, so this may be a trivial non-useful answer, but just in case:

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

Look at the class' code. Does it have any method to retrieve those variables, like get_nodes(),get_root(), etc? If not you have 3 alternatives: recode the class set the vars public, recode the class and add the methods, or recode the class and set the variables protected, then create a new class extending the parent one with those methods (I recomend this one, since it has less impact on the parent class).

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

Anyway if you can't recode the class and it has no get methods you won't be able to access those private variables.

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

#1


6  

Change them to protected member variables and extend the class.

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

Whoever wrote the class with private members effectively made the class "final". Which goes to show that you should always write your members as protected, unless there's a really, REALLY good reason to do otherwise.

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

Hope that helps...

希望有帮助......

#2


11  

If you dont want to touch the core files, then you have to use Reflection:

如果你不想触摸核心文件,那么你必须使用Reflection:

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

The hackish alternative would be casting the object to array and then doing:

hackish替代方案是将对象转换为数组,然后执行:

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

#3


1  

If I understand correctly your question, you're asking if you can access an object's private variables, but I guess you know you can't unless there's a method for it in the class, so this may be a trivial non-useful answer, but just in case:

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

Look at the class' code. Does it have any method to retrieve those variables, like get_nodes(),get_root(), etc? If not you have 3 alternatives: recode the class set the vars public, recode the class and add the methods, or recode the class and set the variables protected, then create a new class extending the parent one with those methods (I recomend this one, since it has less impact on the parent class).

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

Anyway if you can't recode the class and it has no get methods you won't be able to access those private variables.

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