Как сделать PHP stdClass отражением

#php #reflection #stdclass

#php #отражение #стандартный класс

Вопрос:

У меня есть функция для регистрации переменных php в файл. Существует раздел, который обрабатывает объекты elseif(is_object($var))... , и он хорошо работает с любыми объектами приложения. НО это не работает, если переменная является объектами stdClass. Я не понимаю, в чем разница между другими объектами и объектом stdClass. Вот код функции:

 function varLog( $var, $log = 'info', $depth = 2, $round = 0)
{
    $logFile = __DIR__ . '/../log/' . $log . '.log';
    file_put_contents( $logFile, '(' . gettype( $var ) . ') ', FILE_APPEND );

    if( in_array( gettype($var), ['integer', 'double', 'string'] ) )
    {
        file_put_contents( $logFile, $var . PHP_EOL, FILE_APPEND );
    }
    elseif( in_array( gettype($var), ['boolean', 'NULL'] ) )
    {
        $var = is_null( $var ) ? 'NULL' : ($var ? 'TRUE' : 'FALSE');
        file_put_contents( $logFile, $var . PHP_EOL, FILE_APPEND );
    }
    elseif ( is_array( $var ) )
    {
        file_put_contents( $logFile, 'length ' . count($var) . PHP_EOL, FILE_APPEND );

        foreach ( $var as $key => $val )
        {
            file_put_contents( $logFile, str_repeat('    ', $round   1) . $key . ' => ', FILE_APPEND );
            if ( $round   1 <= $depth )
            {
                varLog( $val, $log, $depth, $round   1 );
            }
            else
            {
                file_put_contents( $logFile, '(' . gettype( $val ) . ')' . PHP_EOL, FILE_APPEND );
            }
        }
    }
    elseif ( is_object( $var ) )
    {
        file_put_contents( $logFile, get_class( $var ) . PHP_EOL, FILE_APPEND );
        $props = (new ReflectionClass( $var ))->getProperties();
        foreach ( $props as $prop )
        {
            $prop->setAccessible( true );
            $scoope = $prop->isPrivate() ? '(private)' : ($prop->isProtected() ? '(protected)' : '(public)');
            file_put_contents( $logFile, str_repeat('   ', $round   1) . $scoope . ' ' . $prop->name . ' => ', FILE_APPEND );
            if ( $round   1 <= $depth )
            {
                varLog( $prop->getValue( $var ), $log, $depth, $round   1 );
            }
            else
            {
                file_put_contents( $logFile, '(' . gettype( $prop->getValue( $var ) ) . ')' . PHP_EOL, FILE_APPEND );
            }
        }
    }
}
 

Кажется, строка

 $props = (new ReflectionClass( $var ))->getProperties();
 

не возвращает никаких реквизитов.

Комментарии:

1. Вы можете сделать get_object_vars($var); , если вам нужно, вместо того, чтобы использовать ReflectionClass для StdClass .

2. Я хотел бы знать, почему этот код не работает с stdClass. get_object_vars() возвращает только общедоступные свойства.

Ответ №1:

В PHP есть ReflectionClass и ReflectionObject. Вы можете использовать ReflectionObject для StdClass .

 $props = (new ReflectionObject(($var))->getProperties();
 

В противном случае вы можете использовать get_object_vars:

 $props = get_object_vars($var);
 

Разница между ними заключается в том, что ReflectionClass будут возвращены только исходные свойства класса.

Предположим, что у вас есть следующий класс:

 class Test {
    public $foo;
}
 

Затем вы создаете его экземпляр и присваиваете новое свойство:

 $instance = new Test;
$instance->bar = 'foo';
 

Затем, если вы извлекаете свойства класса с ReflectionClass :

 (new ReflectionClass($instance))->getProperties();
 

Он не возвращает bar свойство:

 [
    ReflectionProperty {#3059
         name: "foo",
         class: "Test",
        modifiers: "public",
    },
]
 

Следовательно, пустой массив при использовании ReflectionClass with StdClass . В то ReflectionObject время как вернет оба:

 (new ReflectionObject($instance))->getProperties();
 

Вывод:

 [
    ReflectionProperty {#3071
         name: "foo",
         class: "Test",
        modifiers: "public",
    },
    ReflectionProperty {#3073
         name: "bar",
         class: "Test",
        modifiers: "public",
    },
]
 

Источник: https://gist.github.com/wjaspers/9353164