В PHP, как я могу получить доступ к массиву ": private" в объекте?
До тех пор, пока около элемента 3.3beta1 в WP_Admin_Bar Object
не будут доступны с использованием этого типа синтаксиса, например, чтобы изменить класс 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
Измените их на защищенные переменные-члены и расширьте класс.
Тот, кто написал класс с частными членами, фактически сделал класс "окончательным". Который показывает, что вы должны всегда писать своих членов как защищенные, если нет действительно, ДЕЙСТВИТЕЛЬНО хорошей причины для этого.
Надеюсь, что это поможет...
Ответ 2
Если вы не хотите касаться основных файлов, вы должны использовать Reflection
:
$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);
Ответ 3
Если я правильно понял ваш вопрос, вы спрашиваете, можете ли вы получить доступ к закрытым переменным объекта, но я думаю, вы знаете, что не можете, если в нем нет метода, поэтому это может быть тривиальный не- полезный ответ, но на всякий случай:
Посмотрите на код класса. Имеет ли какой-либо метод для извлечения этих переменных, например get_nodes(), get_root() и т.д.? Если нет, у вас есть 3 альтернативы: перекодируйте класс, чтобы публиковать vars, перекодировать класс и добавлять методы, или перекодировать класс и устанавливать защищенные переменные, а затем создать новый класс, расширяющий родительский с этими методами (рекомендую этот, поскольку он оказывает меньшее влияние на родительский класс).
В любом случае, если вы не можете перекодировать класс и у него нет методов get, вы не сможете получить доступ к этим частным переменным.