Я использую Ubuntu с PHP 7.
PHP 7.0.5-3+donate.sury.org~xenial+1 (cli) ( NTS ) Copyright (c) 1997-2016 The PHP Group Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies with Xdebug v2.4.0, Copyright (c) 2002-2016, by Derick Rethans
Когда я отлаживаю скрипт PHP, используя var_dump
чтобы показать некоторую переменную:
- Отправка «var_dump» в консоль FireBug
- Как экспортировать массив PHP, где каждая пара ключей и значений находится в отдельной строке?
- Почему var_dump показывает имя файла и номер строки?
- PHP Пустая строка длиной 32
- Как создать массив из вывода var_dump в PHP?
<?php var_dump('tmp string'); var_dump(true);
Ниже приведен его вывод:
/var/www/example.com/test.php:3:string 'tmp string' (length=10) /var/www/example.com/test.php:4:boolean true
Почему он всегда выводит путь к файлу раньше?
Я хочу, чтобы он выводился, как показано ниже:
- Почему var_dump возвращает большее значение, чем длина строки?
- Как я могу захватить результат var_dump в строку?
- Альтернативный var_dump для PHP, который позволяет ограничить глубину вложенных массивов
- сохранить var_dump в текстовый файл
- Неожиданное наблюдение: var_dump () массива помещает ссылки на элементы … с каких пор?
string 'tmp string' (length=10) boolean true
Related of «Когда я отлаживаю php с переменной var_dump, он всегда выводит путь к файлу в начале?»
ruphp.com
Зачем нужны print_r и var_dump?
print_r чаще всего используют для массивов и основной задачей является именно узнать, какие ключи (если это ассоциативный массив или с большим уровнем вложенности многомерный) и значения находятся в массиве. Записывается следующим образом:
Нам на экраны выдаст следующий результат:
Несмотря на свою простоту, данный массив сложно читается, а если бы его структура состояла из нескольких уровней, то найти нужную информацию было бы очень затруднительно. К счастью, в HTML есть тег, который поможет с этим справиться, это тег pre:
Как видно из кода, print_r записывается между тегами pre, и в результате видим следующую картину:
Особенность тега pre еще и в том, что он отображает все символы пробелов, если вы указываете много пробелов, они записываются как один:
«По умолчанию, любое количество пробелов идущих в коде подряд, на веб-странице показывается как один.»
То есть, такая запись:
Выдаст:
Для массивов считаю что print_r это инструмент номер один ?
Зачем нужен var_dump?
Для обычных переменный, которые содержат строки, числа и т.д. есть простые способы вывода — echo и print. Но иногда этого недостаточно, в PHP у каждого значения есть свой тип. Есть правда неприятная особенность, тип может меняться, и запись:
Выдаст следующее значение:
Хотя мы передали одно число и одну строку. var_dump позволяет узнать к какому типу данных относится значение:
int сокращение от integer — целое число. Записывается не сложнее чем print_r:
Тип данных это важная вещь, но лично я print_r`ом пользуюсь гораздо чаще.
print_r и var_dump в 1С-Битрикс
В битриксе есть файл, который выполняется при каждой загрузке страницы — init.php, и для того чтобы каждый раз не писать много кода, можно записать 2 простые функции:
После записи можно передавать переменную, и что самое главное, массив. Запись для вызова будет следующая:
При работе с языком программирования PHP, это базовые вещи, которые помогут сэкономить ваше время :).
forwww.com
Функция var_dump() и объекты
Что касается работы с объектами, то все свойства объекта (общедоступные, закрытые и защищенные) будут возвращены при выводе, если только объект не реализует метод __debugInfo()
(добавлен в PHP 5.6.0).
Магический метод __debugInfo()
срабатывает, когда объект вызывается функцией var_dump()
, то есть необходимо вывести список свойств объекта. Если этот метод не определен в объекте, тогда будут выведены все public
,
protected
и private
свойства объекта.
Давайте рассмотрим пример:
<!-- Для удобочитаемости результата добавляем тег <pre> --> <pre> <?php // создаём класс Ex class Ex { private $var; // конструктор класса задаёт значение приватному свойству $var public function __construct($val) { $this->var = $val; } // метод __debugInfo переопределяет значение свойства $var public function __debugInfo() { return [ '$varSquared' => $this->var ** 2, ]; } } // в функции var_dump() создаём объект класса Ex var_dump( new Ex(8) );
Мы видим, что var_dump
показывает нам наличиние в объекте свойства varSquared
, хотя это свойство определено в методе __debugInfo()
, как и его значение.
komotoz.ru
var_export
или serialize
— это то, что вы ищете. var_export
будет отображать синтаксис синтаксического var_export
PHP, и serialize
визуализацию, отличную от человека, но обратимую преобразование «array to string» …
Редактировать Хорошо, за вызов:
В принципе, я преобразовываю вывод в сериализованную строку (а затем неэтериализую ее). Я не утверждаю, что это идеально, но, похоже, он работает над некоторыми довольно сложными структурами, которые я пробовал …
function unvar_dump($str) { if (strpos($str, "n") === false) { //Add new lines: $regex = array( '#(\[.*?\]=>)#', '#(string\(|int\(|float\(|array\(|NULL|object\(|})#', ); $str = preg_replace($regex, "n\1", $str); $str = trim($str); } $regex = array( '#^\040*NULL\040*$#m', '#^\s*array\((.*?)\)\s*{\s*$#m', '#^\s*string\((.*?)\)\s*(.*?)$#m', '#^\s*int\((.*?)\)\s*$#m', '#^\s*bool\(true\)\s*$#m', '#^\s*bool\(false\)\s*$#m', '#^\s*float\((.*?)\)\s*$#m', '#^\s*[(\d+)\]\s*=>\s*$#m', '#\s*?\r?\n\s*#m', ); $replace = array( 'N', 'a:\1:{', 's:\1:\2', 'i:\1', 'b:1', 'b:0', 'd:\1', 'i:\1', ';' ); $serialized = preg_replace($regex, $replace, $str); $func = create_function( '$match', 'return "s:".strlen($match[1]).":\"".$match[1]."\"";' ); $serialized = preg_replace_callback( '#\s*\["(.*?)"\]\s*=>#', $func, $serialized ); $func = create_function( '$match', 'return "O:".strlen($match[1]).":\"".$match[1]."\":".$match[2].":{";' ); $serialized = preg_replace_callback( '#object\((.*?)\).*?\((\d+)\)\s*{\s*;#', $func, $serialized ); $serialized = preg_replace( array('#};#', '#{;#'), array('}', '{'), $serialized ); return unserialize($serialized); }
Я тестировал его на сложной структуре, такой как:
array(4) { ["foo"]=> string(8) "Foo"bar"" [0]=> int(4) [5]=> float(43.2) ["af"]=> array(3) { [0]=> string(3) "123" [1]=> object(stdClass)#2 (2) { ["bar"]=> string(4) "bart" ["foo"]=> array(1) { [0]=> string(2) "re" } } [2]=> NULL } }
code-examples.net
Задача
Необходимо проверить значения, хранимые в переменных. Это может быть вложенный массив или объект, поэтому нельзя просто распечатать его и пройтись по нему в цикле.
Решение
Для этого следует применять функцию print_r() или функцию var_dump():
$array = array(«name» => «frank», 12, array(3, 4));
print_r($array);
Array
(
[name] => frank
[0] => 12
[1] => Array
(
[0] => 3
[1] => 4
)
)
var_dump($array);
array(3) {
[«name»]=>
string(5) «frank»
[0]=>
int(12)
[1]=>
array(2) {
[0]=>
int(3)
[1]=>
int(4)
}
}
Обсуждение
Вывод функции print_r() короче и его легче читать. Однако вывод функции var_dump() содержит типы данных и длину каждой переменной.
Эти функции работают с переменными рекурсивно, поэтому если внутри переменной есть ссылки на саму себя, то в результате можно получить бесконечный цикл. Хотя обе функции сами умеют избегать бесконечного вывода значений переменных. Функция print_r() после перво-го вхождения переменной печатает слово *RECURSION* вместо дальнейшего вывода информации об этой переменной и продолжает итерацию для оставшихся данных, которые она должна вывести на печать. Если функция var_dump() встречает переменную более трех раз, она выдает фатальную ошибку и заканчивает выполнение сценария. Рассмотрим массивы $user_1 и $user_2, ссылающиеся друг на друга посредством элементов friend:
$user_1 = array(‘name’ => ‘Max Bialystock’,
‘username’ => ‘max’);
$user_2 = array(‘name’ => ‘Leo Bloom’,
‘username’ => ‘leo’);
// Макс и Лео – друзья
$user_2[‘friend’] = &$user_1;
$user_1[‘friend’] = &$user_2;
// у Макса и Лео есть работа
$user_1[‘job’] = ‘Swindler’;
$user_2[‘job’] = ‘Accountant’;
Вывод функции print_r($user_2):
Array
(
[name] => Leo Bloom
[username] => leo
[friend] => Array
(
[name] => Max Bialystock
[username] => max
[friend] => Array
(
[name] => Leo Bloom
[username] => leo
[friend] => Array
*RECURSION*
[job] => Accountant
)
[job] => Swindler
)
[job] => Accountant
)
Встретив ссылку на $user_1 второй раз, функция print_r() печатает слово *RECURSION* вместо обращения к массиву. Затем она продолжает свою работу, печатая оставшиеся элементы массивов $user_1 и $user_2.
Встретившись с рекурсией, функция var_dump() ведет себя по-другому:
array(4) {
[«name»]=>string(9) «Leo Bloom»
[«username»]=>
string(3) «leo»
[«friend»]=>
&array(4) {
[«name»]=>
string(14) «Max Bialystock»
[«username»]=>
string(3) «max»
[«friend»]=>
&array(4) {
[«name»]=>
string(9) «Leo Bloom»
[«username»]=>
string(3) «leo»
[«friend»]=>
&array(4) {
[«name»]=>
string(14) «Max Bialystock»
[«username»]=>
string(3) «max»
[«friend»]=>
&array(4) {
[«name»]=>
string(9) «Leo Bloom»
[«username»]=>
string(3) «leo»
[«friend»]=>
&array(4) {
[«name»]=>
string(14) «Max Bialystock»
[«username»]=>
string(3) «max»
[«friend»]=>
&array(4) {
[«name»]=>
string(9) «Leo Bloom»
[«username»]=>
string(3) «leo»
[«friend»]=>
&array(4) {
Fatal error: Nesting level too deep — recursive dependency? in
var-dump.php on line 15
Функция var_dump() останавливает рекурсию еще до четвертого появления ссылки на массив $user_1. Когда это происходит, она выдает фатальную ошибку и прекращает выдачу дампа переменных (или выполнение сценария).И хотя функции print_r() и var_dump() печатают свои результаты вместо того, чтобы их возвратить, они могут сохранить данные без их рас-
печатки, используя выходной буфер:
ob_start();
var_dump($user);
$dump = ob_get_contents();
ob_end_clean();
Таким образом, результаты функции var_dump($user) помещаются в переменную $dump..
oooportal.ru
Нет другого способа, кроме ручного разбора в зависимости от типа. Я не добавлял поддержку объектов, но он очень похож на массивы; вам просто нужно сделать магию отражения, чтобы заполнить не только публичные свойства и не вызвать конструктор.
EDIT: Добавлена поддержка объектов … Магия отражения …
function unserializeDump($str, &$i = 0) { $strtok = substr($str, $i); switch ($type = strtok($strtok, "(")) { // get type, before first parenthesis case "bool": return strtok(")") === "true"?(bool) $i += 10:!$i += 11; case "int": $int = (int)substr($str, $i + 4); $i += strlen($int) + 5; return $int; case "string": $i += 11 + ($len = (int)substr($str, $i + 7)) + strlen($len); return substr($str, $i - $len - 1, $len); case "float": return (float)($float = strtok(")")) + !$i += strlen($float) + 7; case "NULL": return NULL; case "array": $array = array(); $len = (int)substr($str, $i + 6); $i = strpos($str, "n", $i) - 1; for ($entries = 0; $entries < $len; $entries++) { $i = strpos($str, "n", $i); $indent = -1 - (int)$i + $i = strpos($str, "[", $i); // get key int/string if ($str[$i + 1] == '"') { // use longest possible sequence to avoid key and dump structure collisions $key = substr($str, $i + 2, - 2 - $i + $i = strpos($str, ""]=>n ", $i)); } else { $key = (int)substr($str, $i + 1); $i += strlen($key); } $i += $indent + 5; // jump line $array[$key] = unserializeDump($str, $i); } $i = strpos($str, "}", $i) + 1; return $array; case "object": $reflection = new ReflectionClass(strtok(")")); $object = $reflection->newInstanceWithoutConstructor(); $len = !strtok("(") + strtok(")"); $i = strpos($str, "n", $i) - 1; for ($entries = 0; $entries < $len; $entries++) { $i = strpos($str, "n", $i); $indent = -1 - (int)$i + $i = strpos($str, "[", $i); // use longest possible sequence to avoid key and dump structure collisions $key = substr($str, $i + 2, - 2 - $i + $i = min(strpos($str, ""]=>n ", $i)?:INF, strpos($str, "":protected]=>n ", $i)?:INF, $priv = strpos($str, "":"", $i)?:INF)); if ($priv == $i) { $ref = new ReflectionClass(substr($str, $i + 3, - 3 - $i + $i = strpos($str, "":private]=>n ", $i))); $i += $indent + 13; // jump line } else { $i += $indent + ($str[$i+1] == ":"?15:5); // jump line $ref = $reflection; } $prop = $ref->getProperty($key); $prop->setAccessible(true); $prop->setValue($object, unserializeDump($str, $i)); } $i = strpos($str, "}", $i) + 1; return $object; } throw new Exception("Type not recognized...: $type"); }
(Здесь много «магических» чисел при увеличении счетчика строк строки $i
, в основном просто длины строк ключевых слов и некоторых круглых скобок и т. Д.)
code.i-harness.com
I personally prefer a single standalone function called debug from github.com/hazardland/debug.php
It outputs html formatted dump for a complex objects/nested arrays with an expand/collapse buttons and gives ability to simply observe deep level data structures without depleting your brain resources or in a form of 4 space tab indented plain text which looks like this (but html mode is just a fully satisfying thing):
id : 13
name : "deposit"
class : "paypaldeposit"
title : "Deposit"
system (cashiersystem)
name : "paypal"
class : "paypalsystem"
title : "PayPal"
image : "cashier_system_image_paypal.png"
methods : null
balance : ""
affect : 1
min (cashieramount)
currency : "USD"
value : "1"
origin : null
max (cashieramount)
currency : "USD"
value : "100"
origin : null
currencys (array)
EUR : "EUR"
USD : "USD"
RUB : "RUB"
cashiers (array)
2 : "2"
tax (cashiertax)
items (array)
EUR (array)
0 (array)
from : 0
to : 20
value : 0.3
percent : 0
USD (array)
0 (array)
from : 0
to : 20
value : 0.3
percent : 0
RUB (array)
0 (array)
from : 0
to : 1500
value : 25
percent : 0
active : true
order : 13
php.net