Viewing file: Exporter.php (8.76 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php /* * This file is part of the Exporter package. * * (c) Sebastian Bergmann <sebastian@phpunit.de> * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */
namespace SebastianBergmann\Exporter;
use SebastianBergmann\RecursionContext\Context;
/** * A nifty utility for visualizing PHP variables. * * <code> * <?php * use SebastianBergmann\Exporter\Exporter; * * $exporter = new Exporter; * print $exporter->export(new Exception); * </code> */ class Exporter { /** * Exports a value as a string * * The output of this method is similar to the output of print_r(), but * improved in various aspects: * * - NULL is rendered as "null" (instead of "") * - TRUE is rendered as "true" (instead of "1") * - FALSE is rendered as "false" (instead of "") * - Strings are always quoted with single quotes * - Carriage returns and newlines are normalized to \n * - Recursion and repeated rendering is treated properly * * @param mixed $value * @param int $indentation The indentation level of the 2nd+ line * @return string */ public function export($value, $indentation = 0) { return $this->recursiveExport($value, $indentation); }
/** * @param mixed $data * @param Context $context * @return string */ public function shortenedRecursiveExport(&$data, Context $context = null) { $result = array(); $exporter = new self();
if (!$context) { $context = new Context; }
$context->add($data);
foreach ($data as $key => $value) { if (is_array($value)) { if ($context->contains($data[$key]) !== false) { $result[] = '*RECURSION*'; }
else { $result[] = sprintf( 'array(%s)', $this->shortenedRecursiveExport($data[$key], $context) ); } }
else { $result[] = $exporter->shortenedExport($value); } }
return implode(', ', $result); }
/** * Exports a value into a single-line string * * The output of this method is similar to the output of * SebastianBergmann\Exporter\Exporter::export(). * * Newlines are replaced by the visible string '\n'. * Contents of arrays and objects (if any) are replaced by '...'. * * @param mixed $value * @return string * @see SebastianBergmann\Exporter\Exporter::export */ public function shortenedExport($value) { if (is_string($value)) { $string = $this->export($value);
if (function_exists('mb_strlen')) { if (mb_strlen($string) > 40) { $string = mb_substr($string, 0, 30) . '...' . mb_substr($string, -7); } } else { if (strlen($string) > 40) { $string = substr($string, 0, 30) . '...' . substr($string, -7); } }
return str_replace("\n", '\n', $string); }
if (is_object($value)) { return sprintf( '%s Object (%s)', get_class($value), count($this->toArray($value)) > 0 ? '...' : '' ); }
if (is_array($value)) { return sprintf( 'Array (%s)', count($value) > 0 ? '...' : '' ); }
return $this->export($value); }
/** * Converts an object to an array containing all of its private, protected * and public properties. * * @param mixed $value * @return array */ public function toArray($value) { if (!is_object($value)) { return (array) $value; }
$array = array();
foreach ((array) $value as $key => $val) { // properties are transformed to keys in the following way: // private $property => "\0Classname\0property" // protected $property => "\0*\0property" // public $property => "property" if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) { $key = $matches[1]; }
// See https://github.com/php/php-src/commit/5721132 if ($key === "\0gcdata") { continue; }
$array[$key] = $val; }
// Some internal classes like SplObjectStorage don't work with the // above (fast) mechanism nor with reflection in Zend. // Format the output similarly to print_r() in this case if ($value instanceof \SplObjectStorage) { // However, the fast method does work in HHVM, and exposes the // internal implementation. Hide it again. if (property_exists('\SplObjectStorage', '__storage')) { unset($array['__storage']); } elseif (property_exists('\SplObjectStorage', 'storage')) { unset($array['storage']); }
if (property_exists('\SplObjectStorage', '__key')) { unset($array['__key']); }
foreach ($value as $key => $val) { $array[spl_object_hash($val)] = array( 'obj' => $val, 'inf' => $value->getInfo(), ); } }
return $array; }
/** * Recursive implementation of export * * @param mixed $value The value to export * @param int $indentation The indentation level of the 2nd+ line * @param \SebastianBergmann\RecursionContext\Context $processed Previously processed objects * @return string * @see SebastianBergmann\Exporter\Exporter::export */ protected function recursiveExport(&$value, $indentation, $processed = null) { if ($value === null) { return 'null'; }
if ($value === true) { return 'true'; }
if ($value === false) { return 'false'; }
if (is_float($value) && floatval(intval($value)) === $value) { return "$value.0"; }
if (is_resource($value)) { return sprintf( 'resource(%d) of type (%s)', $value, get_resource_type($value) ); }
if (is_string($value)) { // Match for most non printable chars somewhat taking multibyte chars into account if (preg_match('/[^\x09-\x0d\x1b\x20-\xff]/', $value)) { return 'Binary String: 0x' . bin2hex($value); }
return "'" . str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) . "'"; }
$whitespace = str_repeat(' ', 4 * $indentation);
if (!$processed) { $processed = new Context; }
if (is_array($value)) { if (($key = $processed->contains($value)) !== false) { return 'Array &' . $key; }
$key = $processed->add($value); $values = '';
if (count($value) > 0) { foreach ($value as $k => $v) { $values .= sprintf( '%s %s => %s' . "\n", $whitespace, $this->recursiveExport($k, $indentation), $this->recursiveExport($value[$k], $indentation + 1, $processed) ); }
$values = "\n" . $values . $whitespace; }
return sprintf('Array &%s (%s)', $key, $values); }
if (is_object($value)) { $class = get_class($value);
if ($hash = $processed->contains($value)) { return sprintf('%s Object &%s', $class, $hash); }
$hash = $processed->add($value); $values = ''; $array = $this->toArray($value);
if (count($array) > 0) { foreach ($array as $k => $v) { $values .= sprintf( '%s %s => %s' . "\n", $whitespace, $this->recursiveExport($k, $indentation), $this->recursiveExport($v, $indentation + 1, $processed) ); }
$values = "\n" . $values . $whitespace; }
return sprintf('%s Object &%s (%s)', $class, $hash, $values); }
return var_export($value, true); } }
|