在 PHP 中,如何访问对象中的 ":private" 数组?
Posted
技术标签:
【中文标题】在 PHP 中,如何访问对象中的 ":private" 数组?【英文标题】:In PHP how can I access a ":private" array in an object? 【发布时间】:2012-01-07 09:04:38 【问题描述】:直到 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_item
和 remove_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
【问题讨论】:
【参考方案1】:如果我正确理解了您的问题,您是在询问是否可以访问对象的私有变量,但我想您知道除非类中有针对它的方法,否则您不能,所以这可能是一个微不足道的非有用的答案,但以防万一:
查看班级的代码。是否有任何方法可以检索这些变量,例如 get_nodes()、get_root() 等?如果没有,你有 3 种选择:重新编码类设置 vars public,重新编码类并添加方法,或重新编码类并将变量设置为受保护,然后使用这些方法创建一个扩展父类的新类(我推荐这个,因为它对父类的影响较小)。
无论如何,如果您无法重新编码该类并且它没有 get 方法,您将无法访问这些私有变量。
【讨论】:
你说得对,我在这里将 private 与 protected 混淆了,已编辑。【参考方案2】:将它们更改为受保护的成员变量并扩展类。
使用私有成员编写课程的人有效地使课程“最终”。这表明您应该始终将您的成员写为受保护的,除非有非常非常好的理由不这样做。
希望对您有所帮助...
【讨论】:
添加了指向该类文件的链接。希望通过扩展它而不更改核心文件来克服这个问题。 您的问题看起来非常好。也许您可以在发布之前提交包含此问题链接的错误报告。他们可能愿意根据您的需要对其进行更改。 codex.wordpress.org/Reporting_Bugs 我认为这是最好的做法。谢谢。 core.trac.wordpress.org/ticket/19371【参考方案3】:如果你不想接触核心文件,那么你必须使用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);
【讨论】:
我会尝试Reflection
看看是否可行。不确定我是否可以将其转换为数组,因为我需要反对该类仍然可以使用它,以便可以渲染它。感谢您的详细回答:)
这对我很有用。接受的答案不回答问题!有时,如果不侵入另一方的代码,您就无法更改对象……
对于hackish版本,key可以不同,用dump找到,key是"\x00*\x00id",实际上chr(0)等价于\x00所以key是chr (0).'*'.chr(0).'id'以上是关于在 PHP 中,如何访问对象中的 ":private" 数组?的主要内容,如果未能解决你的问题,请参考以下文章