В 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

3 ответов


измените их на защищенные переменные-члены и расширьте класс.

тот, кто написал класс с частными членами, эффективно сделал класс "окончательным". Это показывает, что вы всегда должны писать о своих членах как о защищенных, если нет действительно, действительно веской причины поступить иначе.

надеюсь, это поможет...


Если вы не хотите, чтобы коснуться основных файлов, то вы должны использовать 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);

Если я правильно понимаю ваш вопрос, вы спрашиваете, можете ли вы получить доступ к частным переменным объекта, но я думаю, вы знаете, что не можете, если в классе нет метода для него, поэтому это может быть тривиальный бесполезный ответ, но на всякий случай:

посмотрите на код класса. Имеет ли он какой-либо метод для извлечения этих переменных, таких как get_nodes(),get_root () и т. д.? Если нет, у вас есть 3 альтернативы: перекодируйте класс, установите vars public, перекодируйте класс и добавьте методы или перекодируйте класс и установите защищенные переменные, затем создайте новый класс, расширяющий Родительский с помощью этих методов (я рекомендую этот, так как он меньше влияет на родительский класс).

в любом случае, если вы не можете перекодировать класс, и у него нет методов get, вы не сможете получить доступ к этим частным переменным.