Reputation: 5909
is it possible to override var_dump output for a custom class? I want something like this:
class MyClass{
public $foo;
public $bar;
//pseudo-code
public function __dump($foo, $bar)
{
return 'Foo:$foo, bar:$bar';
}
}
var_dump(array($instanceOfMyClass));
//it should output this:
array(1) {
[0] =>
class MyClass#1 (2) {
Foo:valueOfFoo, bar:valueOfBar
}
}
I know I can use some 3rd-party var_dump alternatives, but I want to customize behavior for var_dump in my library project.
Thanks.
Upvotes: 11
Views: 12082
Reputation: 1
Whenever I have a var_dump output, I just paste it in https://www.spaggetticode.com/text-manipulation/php-dump so that I can view it as JSON or PHP array code instead. Maybe useful?
For example, my var_dump
output was
array(1) {
["object"]=>
object(stdClass)#4 (4) {
["create"]=>
string(6) "sipper"
["faom"]=>
array(2) {
["roam"]=>
object(stdClass)#1 (3) {
["coam"]=>
string(4) "zoam"
["bob"]=>
string(3) "rob"
["fas"]=>
int(124)
}
["fas"]=>
bool(false)
}
["zom"]=>
object(stdClass)#2 (1) {
["hello"]=>
string(5) "world"
}
["vom"]=>
object(DateTime)#3 (3) {
["date"]=>
string(26) "2023-08-29 14:52:23.647869"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
}
}
and the tool converts it to
return [
"object" => (object)[
"create" => "sipper",
"faom" => [
"roam" => (object)[
"coam" => "zoam",
"bob" => "rob",
"fas" => 124,
],
"fas" => false,
],
"zom" => (object)[
"hello" => "world",
],
"vom" => new DateTime([
"date" => "2023-08-29 14:52:23.647869",
"timezone_type" => 3,
"timezone" => "UTC",
]),
],
];
Upvotes: 0
Reputation: 1
If You're looking for a more readable (subjectively) var_dump, I've written something like that some time ago, maybe it'll be of use to You :)
I wanted to print_r every object as if it was an array. The quality of the code is not the best, but it helped me when I couldn't use XDebug.
class XDump
{
private static array $object_hash = []; //workaround for cyclic dependencies
public static function dump($var, bool $withContent = true, ?int $maxDepth = null): void
{
$dumpVar = self::convertToArray($var, $withContent, $maxDepth);
print_r($dumpVar);
exit();
}
private static function convertToArray($var, bool $withContent, ?int $maxDepth)
{
self::$object_hash = [];
if (!$withContent) {
return self::getArrayStructure($var, $maxDepth);
}
return self::getArray($var, $maxDepth);
}
private static function getArray($obj, ?int $maxDepth, $mainKey = '', int $depth = 0)
{
$simpleReturn = self::getSimpleReturn($obj, $mainKey);
if (null !== $simpleReturn) {
return $simpleReturn;
}
$result = [];
$objectArray = (array)$obj;
foreach ($objectArray as $key => $item) {
if (!$maxDepth || $depth <= $maxDepth) {
$result[$key] = self::getArray($item, $maxDepth, $key, $depth + 1);
}
}
return self::shortenArray($result);
}
private static function getArrayStructure($obj, ?int $maxDepth, $mainKey = '', int $depth = 0)
{
$simpleReturn = self::getSimpleReturn($obj, $mainKey);
if (null !== $simpleReturn) {
return $simpleReturn;
}
$result = [];
$objectArray = (array)$obj;
foreach ($objectArray as $key => $item) {
if (self::hasChildren($item)) {
if (!$maxDepth || $depth <= $maxDepth) {
$result[$key] = self::getArrayStructure($item, $maxDepth, (string)$key, $depth + 1);
}
} else {
self::throwErrorIfNotPrintable($key, $mainKey);
$result['elements'][] = $key;
}
}
if (isset($result['elements'])) {
$elements = implode(' | ', $result['elements']);
if (1 === \count($result)) {
return $elements;
}
$result['elements'] = $elements;
}
return self::shortenArray($result);
}
private static function hasChildren($obj): bool
{
return \is_object($obj) || \is_array($obj);
}
private static function getHashIfAlreadyHashed($obj): ?string
{
$hash = self::getObjectHash($obj);
$existingHash = self::$object_hash[$hash] ?? null;
self::$object_hash[$hash] = $hash;
return $existingHash;
}
private static function throwErrorIfNotPrintable($obj, string $name = 'object'): void
{
if (!self::isPrintable($obj)) {
$type = \gettype($obj);
throw new ServerException("Value of {$name} with type {$type} is not handled!");
}
}
private static function isPrintable($obj): bool
{
return is_scalar($obj) || null === $obj;
}
private static function getSimpleReturn($obj, $mainKey)
{
if (\is_object($obj)) {
if (is_subclass_of($obj, \DateTimeInterface::class)) {
return TimeHelper::toDateTimeString($obj);
}
if (\Closure::class === \get_class($obj)) {
return 'Closure';
}
$existingHash = self::getHashIfAlreadyHashed($obj);
if (null !== $existingHash) {
return "Already hashed somewhere else as {$existingHash}!";
}
}
if (\is_string($obj)) {
$jsonData = json_decode($obj, true);
if ($jsonData) {
$jsonData['XDump_IS_JSON_STRING'] = true;
return $jsonData;
}
}
if (\is_resource($obj)) {
$type = get_resource_type($obj);
return "PHP resource with type: {$type} in {$mainKey}";
}
if (!self::hasChildren($obj)) {
self::throwErrorIfNotPrintable($obj);
return $obj;
}
return null;
}
private static function shortenArray(array $retArray): array
{
$shortenRet = [];
foreach ($retArray as $key => $item) {
$shortKey = self::shortenKey((string)$key);
$shortenRet[$shortKey] = $item;
}
return $shortenRet;
}
private static function shortenKey($key): string
{
try {
$parts = explode("\0", $key);
$shortKey = end($parts);
} catch (\Throwable $e) {
$shortKey = $key;
}
return $shortKey;
}
private static function getObjectHash($obj): string
{
return \get_class($obj).'|'.spl_object_hash($obj);
}
}
Upvotes: 0
Reputation: 10110
In PHP 5.6.0+, you can use the __debugInfo()
magic function to customize the output of var_dump()
.
array __debugInfo ( void )
This method is called by
var_dump()
when dumping an object to get the properties that should be shown. If the method isn't defined on an object, then all public, protected and private properties will be shown.This feature was added in PHP 5.6.0.
class MyDateTime{
public $year, $month, $day, $hour, $minute, $second;
public function __debugInfo() {
return array(
'date' => $this->year . "-" . $this->month . "-" . $this->day,
'time' => sprintf("%02d:%02d:%02d", $this->hour, $this->minute, $this->second),
);
}
}
$dt = new MyDateTime();
$dt->year = 2014; $dt->month = 9; $dt->day = 20;
$dt->hour = 16; $dt->minute = 2; $dt->second = 41;
var_dump($dt);
object(MyDateTime)#1 (2) {
["date"]=>
string(9) "2014-9-20"
["time"]=>
string(8) "16:02:41"
}
object(MyDateTime)#1 (6) {
["year"]=>
int(2014)
["month"]=>
int(9)
["day"]=>
int(20)
["hour"]=>
int(16)
["minute"]=>
int(2)
["second"]=>
int(41)
}
__debugInfo()
must return an array
. I got an error on PHP 5.6.0 for returning a string
:
Fatal error: __debuginfo() must return an array in /somepath/somefile.php on line 15
print_r()
too, although this doesn't seem documented anywhere.Upvotes: 17
Reputation: 2970
Don't make sense override var_dump result, you can just use toString() magic method
class MyClass{
public $foo;
public $bar;
public function test(){}
public function __toString()
{
$vars="Variables:";
foreach(get_class_vars(__CLASS__) as $name => $value) $vars.="<br> $name : {$this->{$name}}".gettype($this->{$name});
return __CLASS__.':<br>'.$vars.'<br>Methods:<br>'.implode('<br>',get_class_methods(__CLASS__));
}
}
$lol = new MyClass();
$lol->foo = 10;
$lol->bar = 'asd';
echo $lol;
Example HERE
Upvotes: 0
Reputation: 9302
You cant overwrite core PHP functions.
You could add the function __toString() in your object:
class myClass {
public function __toString(){
// custom var_dump() content here then output it
}
}
$myClass = new myClass();
echo $myClass;
Upvotes: 0
Reputation: 27295
For this you could use the ReflectionClass functions and build your own function to get the informations you need.
http://php.net/manual/de/reflectionclass.tostring.php
http://php.net/manual/en/book.reflection.php
Upvotes: 1