如果您正在寻找更具可读性(主观上)的 var_dump,我前段时间写过类似的东西,也许它会对您有用:)
我想打印每个对象,就好像它是一个数组一样。代码的质量不是最好的,但是当我不能使用 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);
}
}