diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 51bfa9c..933b4dc 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -42,6 +42,7 @@ Yii Framework 2 Change Log - Enh #3154: Added validation error display for `GridView` filters (ivan-kolmychek) - Enh #3222: Added `useTablePrefix` option to the model generator for Gii (horizons2) - Enh #3230: Added `yii\filters\AccessControl::user` to support access control with different actors (qiangxue) +- Enh #3232: Added `export()` and `exportAsString()` methods to `yii\helpers\BaseVarDumper` (klimov-paul) - Enh #3252: Added support for case insensitive matching using ILIKE to PostgreSQL QueryBuilder (cebe) - Enh #3298: Supported configuring `View::theme` using a class name (netyum, qiangxue) - Enh #3328: `BaseMailer` generates better text body from html body (armab) diff --git a/framework/helpers/BaseVarDumper.php b/framework/helpers/BaseVarDumper.php index 24d5462..2f29924 100644 --- a/framework/helpers/BaseVarDumper.php +++ b/framework/helpers/BaseVarDumper.php @@ -7,6 +7,8 @@ namespace yii\helpers; +use yii\base\Arrayable; + /** * BaseVarDumper provides concrete implementation for [[VarDumper]]. * @@ -123,4 +125,56 @@ class BaseVarDumper break; } } + + /** + * Returns a parsable string representation of a variable. + * This method achieves the similar functionality as var_export + * but is more robust when handling arrays and objects. + * @param mixed $var variable to be exported. + * @return string parsable string representation of a variable. + */ + public static function export($var) + { + self::$_output = ''; + self::exportInternal($var, 0); + return self::$_output; + } + + /** + * @param mixed $var variable to be exported + * @param integer $level depth level + */ + private static function exportInternal($var, $level) + { + switch (gettype($var)) { + case 'NULL': + self::$_output .= 'null'; + break; + case 'array': + if (empty($var)) { + self::$_output .= '[]'; + } else { + $keys = array_keys($var); + $outputKeys = ($keys !== range(0, sizeof($var) - 1)); + $spaces = str_repeat(' ', $level * 4); + self::$_output .= '['; + foreach ($keys as $key) { + self::$_output .= "\n" . $spaces . ' '; + if ($outputKeys) { + self::exportInternal($key, 0); + self::$_output .= ' => '; + } + self::exportInternal($var[$key], $level + 1); + self::$_output .= ','; + } + self::$_output .= "\n" . $spaces . ']'; + } + break; + case 'object': + self::$_output .= 'unserialize(' . var_export(serialize($var), true) . ')'; + break; + default: + self::$_output .= var_export($var, true); + } + } } diff --git a/tests/unit/framework/helpers/VarDumperTest.php b/tests/unit/framework/helpers/VarDumperTest.php index 7000ca7..52467db 100644 --- a/tests/unit/framework/helpers/VarDumperTest.php +++ b/tests/unit/framework/helpers/VarDumperTest.php @@ -1,6 +1,7 @@ <?php namespace yiiunit\framework\helpers; +use yii\data\ArrayDataProvider; use yii\helpers\VarDumper; use yiiunit\TestCase; @@ -17,4 +18,92 @@ class VarDumperTest extends TestCase $this->assertEquals("stdClass#1\n(\n)", ob_get_contents()); ob_end_clean(); } + + /** + * Data provider for [[testExport()]] + * @return array test data + */ + public function dataProviderExport() + { + // Regular : + + $data = [ + [ + 'test string', + var_export('test string', true) + ], + [ + 75, + var_export(75, true) + ], + [ + 7.5, + var_export(7.5, true) + ], + [ + null, + 'null' + ], + [ + true, + 'true' + ], + [ + false, + 'false' + ], + [ + [], + '[]' + ], + ]; + + // Arrays : + + $var = [ + 'key1' => 'value1', + 'key2' => 'value2', + ]; + $expectedResult = <<<RESULT +[ + 'key1' => 'value1', + 'key2' => 'value2', +] +RESULT; + $data[] = [$var, $expectedResult]; + + $var = [ + 'value1', + 'value2', + ]; + $expectedResult = <<<RESULT +[ + 'value1', + 'value2', +] +RESULT; + $data[] = [$var, $expectedResult]; + + // Objects : + + $var = new \StdClass(); + $var->testField = 'Test Value'; + $expectedResult = "unserialize('" . serialize($var) . "')"; + $data[] = [$var, $expectedResult]; + + return $data; + } + + /** + * @dataProvider dataProviderExport + * + * @param mixed $var + * @param string $expectedResult + */ + public function testExport($var, $expectedResult) + { + $exportResult = VarDumper::export($var); + $this->assertEquals($expectedResult, $exportResult); + $this->assertEquals($var, eval('return ' . $exportResult . ';')); + } }