В PHP как я могу получить доступ к массиву ": private" в объекте? - PullRequest
13 голосов
/ 27 ноября 2011

До тех пор, пока около 3,3 бета1 элементов в 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 ]

11 голосов
/ 27 ноября 2011

Если вы не хотите трогать файлы ядра, вам нужно использовать 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);
6 голосов
/ 27 ноября 2011

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

Тот, кто написал урок с частными членами, фактически сделал урок "финальным". Это говорит о том, что вы всегда должны писать своим членам как защищенным, если только нет действительно ДЕЙСТВИТЕЛЬНО веской причины поступать иначе.

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

1 голос
/ 27 ноября 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...