Перейти к содержимому

Фото
- - - - -

PHP как сделать свой дамп объекта (аналог var_dump/print_r)


  • Вы не можете создать новую тему
  • Please log in to reply
4 ответов в этой теме

#1 Setor

Setor
  • Постоялец
  • 1 890 сообщений
  • Откуда:Эстония, Таллин

Отправлено 09 декабря 2007 - 17:55

Такой вопрос, как в PHP5 сделать дамп объекта, получить значения его private и protected свойств. print_r и var_dump возвращают всё в string, а мне надо этот результат вывести в немного ином формате, нужно исключить из дампа все связанные объекты, иначе получается или рекурсия или вываливается огромное дерево зависимых объектов. Перерыл документацию, ничего толком не нашёл. Есть мысль использовать Reflection API, но может есть что-то попроще, что я упустил? ;)

ЗЫ: не ожидаю получить ответа, но может есть тут мозголомы? ;)

О, на php.net нашёл пример, неделю назад запостили. Попробую заюзать...
  • 0

#2 Setor

Setor
  • Постоялец
  • 1 890 сообщений
  • Откуда:Эстония, Таллин

Отправлено 09 декабря 2007 - 18:07

http://ee.php.net/ma...int-r.php#78851

Пришлось немного поправить, в той ф-ции игнор не работал как надо с объектами. Может кому пригодится...

// Использование
u_print_r( $variable, array( 'ignoreObjName', 'ignoreName2' ) );

function u_print_r( $subject, $ignore = array(), $depth = 1, $refChain = array() )
{
	if ( $depth > 20 ) return;

	if ( is_object( $subject ) )
	{
		foreach ( $refChain as $refVal )
		{
			if ( $refVal === $subject )
			{
				echo "*RECURSION*\n";
				return;
			}
		}

		array_push( $refChain, $subject );

		echo get_class( $subject ) . " Object ( \n";

		$subject = (array) $subject;
		foreach ( $subject as $key => $val )
		{
			if ( is_array( $ignore ) && ! in_array( $key, $ignore, 1 ) )
			{
				echo str_repeat(" ", $depth * 4) . '[';

				if ( $key[0] == "\0" )
				{
					$keyParts = explode("\0", $key);

					echo $keyParts[2] . (($keyParts[1] == '*')  ? ':protected' : ':private');

					// Дополнительная проверка на игнорируемые объекты
					foreach ( $keyParts as $keyPart )
					{
							if ( in_array( $keyPart, $ignore ) )
							{
								echo '] => <b>IGNORE</b>' . "\n";
								continue 2;
							}
					}
				}
				else
				{
					echo $key;
				}

				echo '] => ';

				u_print_r( $val, $ignore, $depth + 1, $refChain );
			}
		}

		echo str_repeat( ' ', ( $depth - 1 ) * 4 ) . ")\n";
		array_pop( $refChain );
	}
	elseif ( is_array( $subject ) )
	{
		echo "Array ( \n";

		foreach ( $subject as $key => $val )
		{
			if ( is_array( $ignore ) && ! in_array( $key, $ignore, 1 ) )
			{
				echo str_repeat( ' ', $depth * 4 ) . '[' . $key . '] => ';
				u_print_r( $val, $ignore, $depth + 1, $refChain );
			}
		}

		echo str_repeat( ' ', ( $depth - 1 ) * 4 ) . ")\n";
	}
	else
	{
		echo $subject . "\n";
	}
}

Сообщение изменено: Setor (09 декабря 2007 - 18:30 )

  • 0

#3 alx4ever

alx4ever

    Absolut

  • Пользователь
  • 232 сообщений
  • Откуда:Tallinn, Estonia

Отправлено 13 декабря 2007 - 11:58

nu i hren setor.. zachem takoe mozgobuistvo??

vot etim vse prose:
function dump($var) {
	$link = '';
	$style_start = '<span style="color:#CCCCCC"><i>';
	$style_end = '</i></span>';
	if (!isset($var)) return "$style_start (null) $style_end";
	elseif ($var === false) return "$style_start <font color=red>false</font> $style_end";
	elseif ($var === true) return "<font color=green><b>true</b></font>";
	elseif (is_array($var) and !$var) return "$style_start (empty array) $style_end";
	elseif (is_string($var) and !strlen($var)) return "$style_start (empty string) $style_end";
	elseif (is_numeric($var) and !$var) return "$style_start (number null) $style_end";
	elseif (is_array($var)) {
		ob_start();
		echo '<table border="1" width="100%" cellspacing="0" align="left" cellpadding="2" bgcolor="#FFFFFF" bordercolor="#3399FF" style="border-collapse:collapse;">';
		foreach($var as $key => $value) {
			echo '<tr><td valign="top" align="left" style="padding:2px 4px 0px 4px;" nowrap width="1%"><b>'.htmlspecialchars($key).'</b></td><td valign="top" align="left">'.Smart($value).'</td></tr>';
		}
		echo "</table>";
		$var = ob_get_contents();
		ob_end_clean();
		return $var;		
	} elseif (is_object($var)) {
		ob_start();
		echo "<table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">";
		echo "<tr><td colspan=\"2\"><strong>".get_class($var)." class</strong></td></tr>";		
		foreach ($var as $key => $value) {
			echo "<tr><td valign=top><b>".@htmlspecialchars($key)."</b></td><td valign=top>".Smart($value)."</td></tr>";
		}		
		foreach (get_class_methods($var) as $value) {
			echo "<tr><td valign=top><b><i>".@htmlspecialchars($value)."()</i></b></td><td valign=top>{...}</td></tr>";
		}		
		echo "</table>";
		$var=ob_get_contents();
		ob_end_clean();
		return $var;
	} elseif (is_resource($var)) return sprintf("Resource: %s <br />\n", get_resource_type($var));
	else return $var;
}

  • 0

https://ajaxel.com - Лучший CMS 


#4 zedirtybastard

zedirtybastard
  • Пользователь
  • 499 сообщений

Отправлено 13 декабря 2007 - 13:41

alx4ever, у тебя уровни вложенности считать не умеет.
Но сетор конечно перверт :) и по-моему с массивами в обьекте работать не будет.
Поддерживаю вопрос: нах оно надо то?
  • 0

#5 Setor

Setor
  • Постоялец
  • 1 890 сообщений
  • Откуда:Эстония, Таллин

Отправлено 13 декабря 2007 - 18:18

alx4ever, молодец, уместился в один экран (на моём мониторе). Код, что я привёл был скопирован из примера на PHP.net я его только отформатировал и добавил пару строк. По размеру не больше твоего) Ну и главное - он намного технологичней твоего примера + приведённый мною код решил мою проблему.

zedirtybastard, объясняю зачем оно надо. Допустим, у нас есть объект какой-нить Registry (реестр объектов или контекст). И в одном из классов нашего приложения, мы этот реестр присваиваем свойству класса (чтобы удобно к нему обращаться из методов). А теперь представим, что мы сохраним объект, который работал с реестром в том же самом реестре и помимо него ещё с десяток других объектов. Делаем print_r() получаем дерево на 20 экранов с повторяющимися по 10 раз ветками, рекурсией и поверь, в этом дампе ты нифига не поймёшь) Что я хотел сделать: исключить при дампах некоторые свойства классов. Например, я блокирую этот реестр и у меня красивая картинка - дамп нужного мне объекта!

Вот пример дампа

[customer] => Customer Object 
( 
	[customerModel:private] => CustomerModel Object 
	( 
		[context:protected] => IGNORE
		[database:protected] => IGNORE
	)

	[cart:private] => Cart Object 
	( 
		[cartModel:protected] => CartModel Object 
		( 
			[context:protected] => IGNORE
			[database:protected] => IGNORE
		)

		[cartsInfo:protected] => Array 
		( 
			[carts_id] => 42267
			[customers_id] => 1
			[carts_creation_date] => 2007-11-16 10:28:08
			[carts_updated_date] => 2007-12-13 01:42:10
			[delivery_type] => 1
			[delivery_time] => 2
			[delivery_params] => 
		)

		[cartsId:protected] => 42267
	)

	[order:private] => Order Object 
	( 
		[orderModel:protected] => OrderModel Object 
		( 
			[context:protected] => IGNORE
			[database:protected] => IGNORE
		)

		[ordersId:protected] => 0
		[validated:protected] => 1
		[completed:protected] => 
		[ordersInfo:protected] => Array 
		( 
			[delivery_type] => 1
			[delivery_time] => 2
			[delivery_equals] => 1
			[orders_comment] => my comment
		)

		[billingInfo:protected] => Array 
		( 
			[address_type] => 1
			[customers_name] => Sergei Kuznetsov
			[customers_company] => 
			[customers_phone] => 12345
			[address] => Address
			[city] => Kohtla-Jarve
			[indeks] => 12345
		)

		[deliveryInfo:protected] => Array 
		( 
			[address_type] => 1
			[customers_name] => Sergei Kuznetsov
			[customers_company] => 
			[customers_phone] => 12345
			[address] => Address
			[city] => Kohtla-Jarve
			[indeks] => 12345
		)

	)

	[customersId:private] => 1
	[customersInfo:private] => Array 
	( 
		...
	)

	[cartsId:private] => 42267
)

  • 0