Small refactor.

* Added state to PHP_Exporter\Exporter objects.
 * Cleaned up string construction so that it's more obvious what's being built.
This commit is contained in:
Jeff Welch 2013-02-06 18:19:05 -05:00
parent fba4ca1619
commit 5bd7ac6cfe
3 changed files with 111 additions and 83 deletions

View File

@ -16,34 +16,34 @@ Exporting simple types:
require_once __DIR__.'/../vendor/autoload.php';
$exporter = new PHP_Exporter\Exporter;
use PHP_Exporter\Exporter;
// 46
echo $exporter->export(46);
echo new Exporter(46);
// 4.0
echo $exporter->export(4.0);
echo new Exporter(4.0);
// 'hello, world!'
echo $exporter->export('hello, world!');
echo new Exporter('hello, world!');
// false
echo $exporter->export(false);
echo new Exporter(false);
// NAN
echo $exporter->export(acos(8));
echo new Exporter(acos(8));
// -INF
echo $exporter->export(log(0));
echo new Exporter(log(0));
// null
echo $exporter->export(null);
echo new Exporter(null);
// resource(13) of type (stream)
echo $exporter->export(fopen('php://stderr', 'w'));
echo new Exporter(fopen('php://stderr', 'w'));
// Binary String: 0x000102030405
echo $exporter->export(chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5));
echo new Exporter(chr(0) . chr(1) . chr(2) . chr(3) . chr(4) . chr(5));
```
Exporting complex types:
@ -53,7 +53,7 @@ Exporting complex types:
require_once __DIR__.'/../vendor/autoload.php';
$exporter = new PHP_Exporter\Exporter;
use PHP_Exporter\Exporter;
/*
Array &0 (
@ -69,7 +69,7 @@ Array &0 (
)
)
*/
echo $exporter->export(array(array(1,2,3), array("",0,FALSE)));
echo new Exporter(array(array(1,2,3), array("",0,FALSE)));
/*
Array &0 (
@ -80,7 +80,7 @@ Array &0 (
*/
$array = array();
$array['self'] = &$array;
echo $exporter->export($array);
echo new Exporter($array);
/*
stdClass Object &0000000003a66dcc0000000025e723e2 (
@ -89,7 +89,7 @@ stdClass Object &0000000003a66dcc0000000025e723e2 (
*/
$obj = new stdClass();
$obj->self = $obj;
echo $exporter->export($obj);
echo new Exporter($obj);
```
Compact exports:
@ -99,22 +99,26 @@ Compact exports:
require_once __DIR__.'/../vendor/autoload.php';
$exporter = new PHP_Exporter\Exporter;
use PHP_Exporter\Exporter;
// Array ()
echo $exporter->shortenedExport(array());
$exporter = new Exporter(array());
echo $exporter->shortenedExport();
// Array (...)
echo $exporter->shortenedExport(array(1,2,3,4,5));
$exporter = new Exporter(array(1,2,3,4,5));
echo $exporter->shortenedExport();
// stdClass Object ()
echo $exporter->shortenedExport(new stdClass);
$exporter = new Exporter(new stdClass);
echo $exporter->shortenedExport();
// Exception Object (...)
echo $exporter->shortenedExport(new Exception);
$exporter = new Exporter(new Exception);
echo $exporter->shortenedExport();
// this\nis\na\nsuper\nlong\nstring\nt...\nspace
echo $exporter->shortenedExport(
$exporter = new Exporter(
<<<LONG_STRING
this
is
@ -135,6 +139,7 @@ of
space
LONG_STRING
);
echo $exporter->shortenedExport();
```
## Requirements

View File

@ -54,6 +54,23 @@ namespace PHP_Exporter;
*/
class Exporter
{
/**
* The value to export
*
* @var mixed
*/
private $value;
/**
* Constructs a new exporter for a given value.
*
* @param mixed $value The value to export
*/
public function __construct($value)
{
$this->value = $value;
}
/**
* Exports a value into a string
*
@ -67,13 +84,23 @@ class Exporter
* - Carriage returns and newlines are normalized to \n
* - Recursion and repeated rendering is treated properly
*
* @param mixed $value The value to export
* @param integer $indentation The indentation level of the 2nd+ line
* @return string
*/
public function export($value, $indentation = 0)
public function export($indentation = 0)
{
return $this->recursiveExport($value, $indentation);
return $this->recursiveExport($this->value, $indentation);
}
/**
* Exports a value into a string.
*
* @return string
* @see PHP_Exporter\Exporter::export
*/
public function __toString()
{
return $this->export();
}
/**
@ -133,46 +160,55 @@ class Exporter
if (is_array($value)) {
if (($key = $processed->contains($value)) !== false) {
return "Array &$key";
return 'Array &' . $key;
}
$key = $processed->add($value);
if (count($value) > 0) {
$output = "Array &$key (\n";
$values = '';
if (count($value) > 0) {
foreach ($value as $k => $v) {
$ek = $this->export($k);
$output .= "$whitespace $ek => ".$this->recursiveExport($value[$k], $indentation + 1, $processed)."\n";
$values .= sprintf(
'%s %s => %s' . "\n",
$whitespace,
new Exporter($k),
$this->recursiveExport($value[$k], $indentation + 1, $processed)
);
}
return "$output$whitespace)";
} else {
return "Array &$key ()";
$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 "$class Object &$hash";
return sprintf('%s Object &%s', $class, $hash);
}
$hash = $processed->add($value);
$array = $this->toArray($value);
if (count($array) > 0) {
$output = "$class Object &$hash (\n";
$values = '';
$exporter = new Exporter($value);
$array = $exporter->toArray();
if (count($array) > 0) {
foreach ($array as $k => $v) {
$k = $this->export($k);
$output .= "$whitespace $k => ".$this->recursiveExport($v, $indentation + 1, $processed)."\n";
$values .= sprintf(
'%s %s => %s' . "\n",
$whitespace,
new Exporter($k),
$this->recursiveExport($v, $indentation + 1, $processed)
);
}
return "$output$whitespace)";
} else {
return "$class Object &$hash ()";
$values = "\n" . $values . $whitespace;
}
return sprintf('%s Object &%s (%s)', $class, $hash, $values);
}
return var_export($value, true);
@ -188,65 +224,54 @@ class Exporter
* Newlines are replaced by the visible string '\n'. Contents of arrays
* and objects (if any) are replaced by '...'.
*
* @param mixed $value The value to export
* @param integer $indentation The indentation level of the 2nd+ line
* @return string
* @see PHP_Exporter\Exporter::export
*/
public function shortenedExport($value)
public function shortenedExport()
{
if (is_string($value)) {
return $this->shortenedString($value);
if (is_string($this->value)) {
$string = $this->export();
if (strlen($string) > 40) {
$string = substr($string, 0, 30) . '...' . substr($string, -7);
}
return str_replace("\n", '\n', $string);
}
if(is_object($value)) {
if(is_object($this->value)) {
return sprintf(
"%s Object (%s)",
get_class($value),
count($this->toArray($value)) > 0 ? '...' : ''
'%s Object (%s)',
get_class($this->value),
count($this->toArray()) > 0 ? '...' : ''
);
}
if (is_array($value)) {
if (is_array($this->value)) {
return sprintf(
"Array (%s)",
count($value) > 0 ? '...' : ''
'Array (%s)',
count($this->value) > 0 ? '...' : ''
);
}
return $this->export($value);
}
/**
* Shortens a string and converts all new lines to '\n'
*
* @param string $string The string to shorten
* @param integer $max The maximum length for the string
* @return string
*/
public function shortenedString($string, $maxLength = 40)
{
$string = $this->export($string);
if (strlen($string) > $maxLength) {
$string = substr($string, 0, $maxLength - 10) . '...' . substr($string, -7);
}
return str_replace("\n", '\n', $string);
return $this->export();
}
/**
* Converts an object to an array containing all of its private, protected
* and public properties.
*
* @param object $object
* @return array
*/
public function toArray($object)
public function toArray()
{
if(!is_object($this->value)) {
return (array)$this->value;
}
$array = array();
foreach ((array)$object as $key => $value) {
foreach ((array)$this->value as $key => $value) {
// properties are transformed to keys in the following way:
// private $property => "\0Classname\0property"
@ -263,11 +288,11 @@ class Exporter
// Some internal classes like SplObjectStorage don't work with the
// above (fast) mechanism nor with reflection
// Format the output similarly to print_r() in this case
if ($object instanceof \SplObjectStorage) {
foreach ($object as $key => $value) {
if ($this->value instanceof \SplObjectStorage) {
foreach ($this->value as $key => $value) {
$array[spl_object_hash($value)] = array(
'obj' => $value,
'inf' => $object->getInfo(),
'inf' => $this->value->getInfo(),
);
}
}

View File

@ -250,8 +250,7 @@ EOF
*/
public function testExport($value, $expected)
{
$exporter = new Exporter;
$this->assertStringMatchesFormat($expected, self::trimnl($exporter->export($value)));
$this->assertStringMatchesFormat($expected, self::trimnl(new Exporter($value)));
}
public function shortenedExportProvider()
@ -284,8 +283,8 @@ EOF
*/
public function testShortenedExport($value, $expected)
{
$exporter = new Exporter;
$this->assertSame($expected, self::trimnl($exporter->shortenedExport($value)));
$exporter = new Exporter($value);
$this->assertSame($expected, self::trimnl($exporter->shortenedExport()));
}
public function provideNonBinaryMultibyteStrings()
@ -303,7 +302,6 @@ EOF
*/
public function testNonBinaryStringExport($value, $expectedLength)
{
$exporter = new Exporter;
$this->assertRegExp("~'.{{$expectedLength}}'\$~s", $exporter->export($value));
$this->assertRegExp("~'.{{$expectedLength}}'\$~s", (string)new Exporter($value));
}
}