private static function encodeVariable($variable, int $objectDepth = 1, int $arrayDepth = 1, int $totalDepth = 1)
{
static $maxObjectDepth = 5;
static $maxArrayDepth = 5;
static $maxTotalDepth = 10;
static $stack = [];
if ($totalDepth > $maxTotalDepth) {
return sprintf('** Max Depth (%s) **', $maxTotalDepth);
}
if (is_resource($variable)) {
return sprintf('** %s **', (string) $variable);
} elseif (is_object($variable)) {
if ($objectDepth > $maxObjectDepth) {
return sprintf('** Max Object Depth (%s) **', $maxObjectDepth);
}
$class = get_class($variable);
// Check recursion
foreach ($stack as $item) {
if ($item === $variable) {
return sprintf('** Recursion (%s) **', $class);
}
}
array_push($stack, $variable);
// Add class name
$return = ['__className' => $class];
// Add properties
$reflectionClass = new \ReflectionClass($class);
foreach ($reflectionClass->getProperties() as $property) {
$name = $property->getName();
$rawName = $name;
if ($property->isStatic()) {
$name = 'static:' . $name;
}
if ($property->isPublic()) {
$name = 'public:' . $name;
} elseif ($property->isProtected()) {
$name = 'protected:' . $name;
$rawName = "" . '*' . "" . $rawName;
} elseif ($property->isPrivate()) {
$name = 'private:' . $name;
$rawName = "" . $class . "" . $rawName;
}
if (!$property->isPublic()) {
$property->setAccessible(true);
}
$return[$name] = self::encodeVariable($property->getValue($variable), $objectDepth + 1, 1, $totalDepth + 1);
}
// Add members that are not defined in the class but exist in the object
$members = (array) $variable;
foreach ($members as $rawName => $member) {
$name = $rawName;
if ("" === $name[0]) {
$parts = explode("", $name);
$name = $parts[2];
}
if (!$reflectionClass->hasProperty($name)) {
$name = 'undeclared:' . $name;
$return[$name] = self::encodeVariable($member, $objectDepth + 1, 1, $totalDepth + 1);
}
}
unset($members);
array_pop($stack);
return $return;
} elseif (is_array($variable)) {
if ($arrayDepth > $maxArrayDepth) {
return sprintf('** Max Array Depth (%s) **', $maxArrayDepth);
}
$return = [];
foreach ($variable as $k => $v) {
// Encoding the $GLOBALS PHP array causes an infinite loop as it contains a reference to itself
if ('GLOBALS' === $k && is_array($v) && array_key_exists('GLOBALS', $v)) {
$v['GLOBALS'] = '** Recursion (GLOBALS) **';
}
$return[$k] = self::encodeVariable($v, 1, $arrayDepth + 1, $totalDepth + 1);
}
return $return;
} else {
return $variable;
}
}