Как получить доступ к массиву данных, защищенным в ответ API [duplicate]

У меня был случай, когда я случайно начал разворачивать каталог файлов в корне. Он добавил файл .htaccess из моей папки с файлами, который блокирует все php

# If we know how to do it safely, disable the PHP engine entirely.
<IfModule mod_php5.c>
  php_flag engine off
</IfModule>

. Нижняя строка проверяет файл .htaccess на root.

33
задан Jan Turoň 3 January 2015 в 11:54
поделиться

6 ответов

Это то, на что предназначен «защищенный», поскольку главу Visibility объясняет:

Объявленные защищенные члены могут быть доступны только внутри самого класса и наследуются и родительских классов.

Если вам нужно получить доступ к свойству извне, выберите один из них:

  • Не объявляйте его защищенным, сделайте его общедоступным
  • Напишите пару функций для получения и установки значения (getters and setters)

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

class MyFields_Form_Element_Location extends Fields_Form_Element_Location{
}

... и добавьте там свой приемник / сеттер.

15
ответ дан Álvaro González 20 August 2018 в 14:21
поделиться
  • 1
    но что делать, если вы используете внешнюю библиотеку, и вы должны ее отлаживать и хотите печатать значения некоторых защищенных полей? – Kamil Kiełczewski 10 January 2017 в 10:09
  • 2
    @ KamilKiełczewski Извините, я не понимаю, в чем ваш смысл. Вы можете отлаживать любое время . Видимость - это концепция дизайна приложения. – Álvaro González 10 January 2017 в 10:23
  • 3
    дело в том, когда у вас очень большой объект (в моем случае это очередь laravel sqs), и вы должны удалять debug через ssh, и вы хотите видеть только выбранные (защищенные / закрытые) поля (не все поля объектов). – Kamil Kiełczewski 10 January 2017 в 11:46
  • 4
    @ KamilKiełczewski Но ... Вы пытаетесь комментировать что-то в своем ответе или задавать новый вопрос? – Álvaro González 10 January 2017 в 12:09
  • 5
    @ KamilKiełczewski Извините, но я просто не могу это получить. Если вы имеете в виду, что стандартные принципы ООП каким-то образом вмешиваются в отладку, я категорически не согласен, но, конечно, вы всегда можете найти сценарий, в котором спагетти легче справляться ;-) – Álvaro González 10 January 2017 в 12:21

Если вы не можете изменить исходный класс и расширить его, это тоже не вариант, вы можете использовать интерфейс ReflectionProperty.

Библиотека phptoolcase имеет удобный способ для этого:

$value = PtcHandyMan::getProperty( $your_object , ‘propertyName’);

Статическое свойство из одноэлементного класса:

$value = PtcHandyMan::getProperty( ‘myCLassName’ , ‘propertyName’);

Вы можете найти инструмент здесь: http://phptoolcase.com/guides/ptc-hm-guide.html

3
ответ дан Charlie 20 August 2018 в 14:21
поделиться

Вот простой пример (без проверки ошибок) использования ReflectionClass:

function accessProtected($obj, $prop) {
  $reflection = new ReflectionClass($obj);
  $property = $reflection->getProperty($prop);
  $property->setAccessible(true);
  return $property->getValue($obj);
}

Я знаю, что вы сказали, что ограничены 5.2, но это было 2 года назад 5.5 является самой старой поддерживаемой версией , и я надеюсь помочь людям с современными версиями.

62
ответ дан drewish 20 August 2018 в 14:21
поделиться
  • 1
    Это определенный хак, но в моем случае рамки, с которыми я работал, ограничивали мои движения. Это помогло и прекрасно использовать, пока вы знаете, что делаете, и почему - спасибо! :) – Stan Smulders 10 November 2015 в 10:01
  • 2
    Да, я нашел, что это действительно полезно в модульных тестах, где вы хотите проверить присвоение частной собственности, но не обязательно хотите сделать ее общедоступной. – drewish 5 October 2016 в 14:06
  • 3
    @drewish особенно, если вы должны отлаживать некоторую внешнюю библиотеку ... – Kamil Kiełczewski 10 January 2017 в 10:10
  • 4
    ReflectionClass доступен во всех версиях 5.x и не имеет библиотек, требований или конфигурации (доступных во всех сборках PHP). – Phil M 14 January 2017 в 01:06
  • 5
    Отражение - одна из тех вещей, где, если вы обнаружите, что используете ее, вы должны внимательно изучить, чтобы убедиться, что вам нужно. Тем не менее, есть время и место для всего. Во-вторых, я считаю, что это полезно в модульных тестах для обеспечения того, чтобы объект имел доступ к данным, которые ему нужны. В моем случае я использую очередность Laravel, издеваясь над тем, чтобы проверить не только то, что данное задание уволено, но и что ему были предоставлены правильные данные, хранящиеся в защищенном свойстве. Будучи асинхронным, это утверждение немного сложно сделать без этого. Спасибо @drewish. – Claymore 19 April 2018 в 14:29

Объект может быть типизирован в (ассоциативный) массив, а защищенные члены имеют ключи с префиксом chr(0).'*'.chr(0) (см. комментарий @ fardelian здесь ). Используя эту непризнанную функцию, вы можете написать «exposer»:

function getProtectedValue($obj,$name) {
  $array = (array)$obj;
  $prefix = chr(0).'*'.chr(0);
  return $array[$prefix.$name];
}

В качестве альтернативы вы можете проанализировать значение из строки serialized , где (кажется) защищенные члены имеют одинаковые (надеюсь, что php 5.2 не изменил его).

36
ответ дан Jan Turoň 20 August 2018 в 14:21
поделиться
  $propGetter = Closure::bind(  function($prop){return $this->$prop;}, $element['field_text']['#object'], $element['field_text']['#object'] );
  drupal_set_message('count='.count($propGetter('hostEntity')->field_captioned_carousel['und']));
-1
ответ дан stephen 20 August 2018 в 14:21
поделиться
  • 1
    Любые объяснения, пожалуйста? – Stephan Vierkant 8 March 2017 в 15:23
  • 2
    Ответы только на код очень мало для тех, кто пытается учиться. Teach a man to fish - хорошая аналогия здесь. – Regular Joe 9 March 2017 в 00:18

Если вы хотите возиться с классом, не добавляя геттеры и сеттеры ....

PHP 7 добавляет метод вызова ($ obj) (быстрее старого bindTo) на закрытие, позволяя вам вызвать так что переменная $this будет действовать так же, как и в классе - с полными разрешениями.

 //test class with restricted properties
 class test{
    protected $bar="protected bar";
    private $foo="private foo";
    public function printProperties(){
        echo $this->bar."::".$this->foo;   
     }
 }

$testInstance=new test();
//we can change or read the restricted properties by doing this...
$change=function(){
    $this->bar="I changed bar";
    $this->foo="I changed foo";
};
$change->call($testInstance);
$testInstance->printProperties();
//outputs I changed bar::I changed foo in php 7.0 
6
ответ дан user2782001 20 August 2018 в 14:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: