在PHP中,如何访问";:“私人”;对象中的数组?
直到3.3beta1左右,在PHP中,如何访问";:“私人”;对象中的数组?,php,arrays,wordpress,object,data-structures,Php,Arrays,Wordpress,Object,Data Structures,直到3.3beta1左右,WP\u Admin\u Bar对象中的项目都可以使用这种语法访问,例如更改现有菜单项之一的CSS类: $wp_admin_bar->menu->{'wp-logo'}['meta']['class'] = 'new-class'; 运行print\r($wp\u admin\u bar)时,输出如下所示: WP_Admin_Bar Object ( [menu] => stdClass Object (
WP\u Admin\u Bar对象
中的项目都可以使用这种语法访问,例如更改现有菜单项之一的CSS类:
$wp_admin_bar->menu->{'wp-logo'}['meta']['class'] = 'new-class';
运行print\r($wp\u admin\u bar)
时,输出如下所示:
WP_Admin_Bar Object
(
[menu] => stdClass Object
(
[my-account] => Array
(
但是,在版本3.3beta2
左右,用于更改菜单项CSS类的上述语法不再有效,并且print\r($wp\u admin\u bar)
的输出显示了该对象的不同结构:
WP_Admin_Bar Object
(
[nodes:WP_Admin_Bar:private] => Array
(
[my-account] => stdClass Object
(
[id] => my-account
)
我意识到Wordpress可能不希望我以这种方式摆弄菜单,如果有更标准化的方法,我很乐意使用它,但据我所知,只有两个功能可用于修改管理栏,添加菜单项
和删除菜单项
,而且这些并没有提供灵活性来做一些事情,比如更改现有菜单项的属性
为了证实这一点,我查看了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;
因此,我的问题是,如果我有权访问全局$wp\u admin\u bar
对象,是否有办法访问节点内的对象:wp\u admin\u bar:private
?如果没有,是否有其他方法可以访问这些对象,例如创建一个扩展WP\u Admin\u Bar
类的新类,然后从那里访问对象
附言:我试图在不改变核心Wordpress文件的情况下克服这个挑战
链接到文件:如果我正确理解了你的问题,你会问你是否可以访问对象的私有变量,但我想你知道你不能,除非类中有它的方法,所以这可能是一个无关紧要的无用答案,但以防万一: 看看这个类的代码。它是否有任何方法来检索这些变量,如get_nodes()、get_root()等?如果没有,您有3种选择:重新编码类设置vars public,重新编码类并添加方法,或者重新编码类并设置受保护的变量,然后使用这些方法创建一个扩展父类的新类(我建议使用这个类,因为它对父类的影响较小)
无论如何,如果您不能重新编码该类并且它没有get方法,您将无法访问这些私有变量。将它们更改为受保护的成员变量并扩展该类 无论是谁写了一个有私人成员的班级,这个班级实际上都是“最终”的。这表明你应该始终将你的成员写为受保护的,除非有非常非常好的理由这样做
希望这有帮助…如果你不想接触核心文件,那么你必须使用
反射
:
$adminBar = new WP_Admin_Bar();
$reflector = new ReflectionObject($adminBar);
$nodes = $reflector->getProperty('nodes');
$nodes->setAccessible(true);
print_r($nodes->getValue($adminBar));
黑客的替代方案是将对象强制转换为数组,然后执行以下操作:
$adminbar = (array) new WP_Admin_Bar;
$nodes = $adminbar[chr(0) . 'WP_Admin_Bar' . chr(0) . 'nodes'];
print_r($nodes);
你说得对,我混淆了private和protected,edited。添加了一个指向该类文件的链接。我希望通过扩展它而不改变核心文件来克服这个问题。你的问题看起来很好。也许你可以在发布之前提交一份带有这个问题链接的bug报告。他们可能愿意更改它以满足您的需要。我认为这是最好的办法。谢谢我将尝试
反射
,看看这是否有效。不确定是否可以将其强制转换到数组中,因为我需要对象仍然可以被类使用,以便可以呈现它。谢谢你的详细回答:)这对我来说非常有效。被接受的答案不能回答问题!有时,如果不侵入另一方的代码,您就无法更改对象……对于黑客版本,密钥可能不同,并且可以通过dump找到,密钥是“\x00*\x00id”,事实上chr(0)等同于\x00,因此密钥是chr(0)。'*'.chr(0)。'id'