From 265604b7a7aec3e8a58709bb4396a961e9e076f9 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Wed, 5 Nov 2014 11:55:06 -0500 Subject: [PATCH] [#4243] Tweaks to the new var-dumper component --- components/var_dumper/advanced.rst | 81 ++++++++++++++++++-------- components/var_dumper/introduction.rst | 39 +++++++++++-- 2 files changed, 91 insertions(+), 29 deletions(-) diff --git a/components/var_dumper/advanced.rst b/components/var_dumper/advanced.rst index 9b70c8fdfd4..6b6cbf4ebce 100644 --- a/components/var_dumper/advanced.rst +++ b/components/var_dumper/advanced.rst @@ -5,14 +5,30 @@ Advanced Usage of the VarDumper Component ========================================= -``dump()`` function is just a thin wrapper and a more convenient way to call +The ``dump()`` function is just a thin wrapper and a more convenient way to call :method:`VarDumper::dump() `. You can change the behavior of this function by calling -:method:`VarDumper::setHandler($callable) `: -calls to ``dump()`` will then be forwarded to ``$callable``. +:method:`VarDumper::setHandler($callable) `. +Calls to ``dump()`` will then be forwarded to ``$callable``. + +By adding a handler, you can customize the `Cloners`_, `Dumpers`_ and `Casters`_ +explained below. A simple implementation of a handler function might look +like this:: + + use Symfony\Component\VarDumper\VarDumper; + use Symfony\Component\VarDumper\Cloner\VarCloner; + use Symfony\Component\VarDumper\Dumper\CliDumper; + use Symfony\Component\VarDumper\Dumper\HtmlDumper; + + VarDumper::setHandler(function($var) { + $cloner = new VarCloner(); + $dumper = 'cli' === PHP_SAPI ? new CliDumper() : new HtmlDumper(); + + $dumper->dump($cloner->cloneVar($var)); + }); Cloners -~~~~~~~ +------- A cloner is used to create an intermediate representation of any PHP variable. Its output is a :class:`Symfony\\Component\\VarDumper\\Cloner\\Data` @@ -21,18 +37,24 @@ object that wraps this representation. You can create a :class:`Symfony\\Component\\VarDumper\\Cloner\\Data` object this way:: + use Symfony\Component\VarDumper\Cloner\VarCloner; + $cloner = new VarCloner(); $data = $cloner->cloneVar($myVar); + // this is commonly then passed to the dumpe + // see the example at the top of this page + // $dumper->dump($data); -A cloner also applies limits when creating this representation, so that the +A cloner also applies limits when creating the representation, so that the corresponding Data object could represent only a subset of the cloned variable. -Before :method:`Symfony\\Component\\VarDumper\\Cloner\\VarCloner::cloneVar`, +Before calling :method:`Symfony\\Component\\VarDumper\\Cloner\\VarCloner::cloneVar`, you can configure these limits: * :method:`Symfony\\Component\\VarDumper\\Cloner\\VarCloner::setMaxItems` - configures the maximum number of items that will be cloned *past the first - nesting level*. Items are counted using a breadth-first algorithm so that - lower level items have higher priority than deeply nested items; + configures the maximum number of items that will be cloned + *past the first nesting level*. Items are counted using a breadth-first + algorithm so that lower level items have higher priority than deeply nested + items; * :method:`Symfony\\Component\\VarDumper\\Cloner\\VarCloner::setMaxString` configures the maximum number of characters that will be cloned before cutting overlong strings; @@ -45,7 +67,7 @@ method: * the first ``$maxDepth`` argument allows limiting dumps in the depth dimension, * the second ``$maxItemsPerDepth`` limits the number of items per depth level, -* and the last ``$useRefHandles`` defaults to ``true`` but allows removing +* and the last ``$useRefHandles`` defaults to ``true``, but allows removing internal objects' handles for sparser output, * but unlike the previous limits on cloners that remove data on purpose, these can be changed back and forth before dumping since they do not affect @@ -54,11 +76,11 @@ method: .. note:: When no limit is applied, a :class:`Symfony\\Component\\VarDumper\\Cloner\\Data` - object is as accurate as the native :phpfunction:`serialize` function - and thus could have a wider purpose than strictly dumping for debugging. + object is as accurate as the native :phpfunction:`serialize` function, + and thus could be for purposes beyond dumping for debugging. Dumpers -~~~~~~~ +------- A dumper is responsible for outputting a string representation of a PHP variable, using a :class:`Symfony\\Component\\VarDumper\\Cloner\\Data` object as input. @@ -70,6 +92,9 @@ for optionally colored command line output. For example, if you want to dump some ``$variable``, just do:: + use Symfony\Component\VarDumper\Cloner\VarCloner; + use Symfony\Component\VarDumper\Dumper\CliDumper; + $cloner = new VarCloner(); $dumper = new CliDumper(); @@ -77,7 +102,7 @@ For example, if you want to dump some ``$variable``, just do:: By using the first argument of the constructor, you can select the output stream where the dump will be written. By default, the ``CliDumper`` writes -on ``php://stdout`` and the ``HtmlDumper`` on ``php://output``, but any PHP +on ``php://stdout`` and the ``HtmlDumper`` on ``php://output``. But any PHP stream (resource or URL) is acceptable. Instead of a stream destination, you can also pass it a ``callable`` that @@ -90,6 +115,9 @@ method or the second argument of the For example, to get a dump as a string in a variable, you can do:: + use Symfony\Component\VarDumper\Cloner\VarCloner; + use Symfony\Component\VarDumper\Dumper\CliDumper; + $cloner = new VarCloner(); $dumper = new CliDumper(); $output = ''; @@ -107,7 +135,10 @@ For example, to get a dump as a string in a variable, you can do:: // $output is now populated with the dump representation of $variable -An other option for doing the same could be:: +Another option for doing the same could be:: + + use Symfony\Component\VarDumper\Cloner\VarCloner; + use Symfony\Component\VarDumper\Dumper\CliDumper; cloner = new VarCloner(); $dumper = new CliDumper(); @@ -128,9 +159,9 @@ them from re-implementing the logic required to walk through a :class:`Symfony\\Component\\VarDumper\\Cloner\\Data` object's internal structure. Casters -~~~~~~~ +------- -Objects and resources nested in a PHP variable are casted to arrays in the +Objects and resources nested in a PHP variable are "cast" to arrays in the intermediate :class:`Symfony\\Component\\VarDumper\\Cloner\\Data` representation. You can tweak the array representation for each object/resource by hooking a Caster into this process. The component already includes many @@ -140,6 +171,8 @@ If you want to build your own Caster, you can register one before cloning a PHP variable. Casters are registered using either a Cloner's constructor or its ``addCasters()`` method:: + use Symfony\Component\VarDumper\Cloner\VarCloner; + $myCasters = array(...); $cloner = new VarCloner($myCasters); @@ -172,7 +205,7 @@ being cloned in an array. They are callables that accept four arguments: * an array modelled for objects after PHP's native ``(array)`` cast operator, * a :class:`Symfony\\Component\\VarDumper\\Cloner\\Stub` object representing the main properties of the object (class, type, etc.), -* true/false when the caster is called nested is a structure or not. +* true/false when the caster is called nested in a structure or not. Here is a simple caster not doing anything:: @@ -186,18 +219,18 @@ Here is a simple caster not doing anything:: For objects, the ``$array`` parameter comes pre-populated using PHP's native ``(array)`` casting operator or with the return value of ``$object->__debugInfo()`` if the magic method exists. Then, the return value of one Caster is given -as argument to the next Caster in the chain. +as the array argument to the next Caster in the chain. When casting with the ``(array)`` operator, PHP prefixes protected properties -with a ``\0*\0`` and private ones with the class owning the property: -e.g. ``\0Foobar\0`` prefixes all private properties of objects of type Foobar. -Casters follow this convention and add two more prefixes: ``\0~\0`` is used -for virtual properties and ``\0+\0`` for dynamic ones (runtime added +with a ``\0*\0`` and private ones with the class owning the property. For example, +``\0Foobar\0`` will be the prefix for all private properties of objects of +type Foobar. Casters follow this convention and add two more prefixes: ``\0~\0`` +is used for virtual properties and ``\0+\0`` for dynamic ones (runtime added properties not in the class declaration). .. note:: - Although you can, it is best advised not to alter the state of an object + Although you can, it is advised to not alter the state of an object while casting it in a Caster. .. tip:: diff --git a/components/var_dumper/introduction.rst b/components/var_dumper/introduction.rst index 6f43b67ef3d..aadfa6e2704 100644 --- a/components/var_dumper/introduction.rst +++ b/components/var_dumper/introduction.rst @@ -37,13 +37,21 @@ use instead of e.g. :phpfunction:`var_dump`. By using it, you'll gain: reference structure of your data; * Ability to operate in the context of an output buffering handler. +For example:: + + require __DIR__.'/vendor/autoload.php'; + // create a variable, which could be anything! + $someVar = '...'; + + dump($someVar); + By default, the output format and destination are selected based on your current PHP SAPI: * On the command line (CLI SAPI), the output is written on ``STDOUT``. This can be surprising to some because this bypasses PHP's output buffering mechanism; -* On other SAPIs, dumps are written as HTML on the regular output. +* On other SAPIs, dumps are written as HTML in the regular output. .. note:: @@ -101,8 +109,8 @@ original value. You can configure the limits in terms of: -Reading a Dump --------------- +Dump Examples and Output +------------------------ For simple variables, reading the output should be straightforward. Here are some examples showing first a variable defined in PHP, @@ -115,6 +123,7 @@ then its dump representation:: 'a boolean' => true, 'an empty array' => array(), ); + dump($var); .. image:: /images/components/var_dumper/01-simple.png @@ -131,6 +140,7 @@ then its dump representation:: $var .= "Non-UTF-8 strings length are counted in octet size.\n"; $var .= "Because of this `\xE9` octet (\\xE9),\n"; $var .= "this string is not UTF-8 valid, thus the `b` prefix.\n"; + dump($var); .. image:: /images/components/var_dumper/02-multi-line-str.png @@ -144,6 +154,7 @@ then its dump representation:: } $var = new PropertyExample(); + dump($var); .. image:: /images/components/var_dumper/03-object.png @@ -161,6 +172,7 @@ then its dump representation:: $var = new DynamicPropertyExample(); $var->undeclaredProperty = 'Runtime added dynamic properties have `"` around their name.'; + dump($var); .. image:: /images/components/var_dumper/04-dynamic-property.png @@ -172,12 +184,20 @@ then its dump representation:: } $var = new ReferenceExample(); $var->aCircularReference = $var; + dump($var); .. image:: /images/components/var_dumper/05-soft-ref.png .. code-block:: php - $var = new \ErrorException("For some objects, properties have special values\nthat are best represented as constants, like\n`severity` below. Hovering displays the value (`2`).\n", 0, E_WARNING); + $var = new \ErrorException( + "For some objects, properties have special values + that are best represented as constants, like + `severity` below. Hovering displays the value (`2`).", + 0, + E_WARNING + ); + dump($var); .. image:: /images/components/var_dumper/06-constants.png @@ -190,6 +210,7 @@ then its dump representation:: $var[2] = array("Hard references (circular or sibling)"); $var[3] =& $var[2]; $var[3][] = "are dumped using `&number` prefixes."; + dump($var); .. image:: /images/components/var_dumper/07-hard-ref.png @@ -199,12 +220,20 @@ then its dump representation:: $var[] = "Some resources and special objects like the current"; $var[] = "one are sometimes best represented using virtual"; $var[] = "properties that describe their internal state."; + dump($var); .. image:: /images/components/var_dumper/08-virtual-property.png .. code-block:: php - $var = new AcmeController("When a dump goes over its maximum items limit,\nor when some special objects are encountered,\nchildren can be replaced by an ellipsis and\noptionnally followed by a number that says how\nmany have been removed; `9` in this case.\n"); + $var = new AcmeController( + "When a dump goes over its maximum items limit, + or when some special objects are encountered, + children can be replaced by an ellipsis and + optionnally followed by a number that says how + many have been removed; `9` in this case." + ); + dump($var); .. image:: /images/components/var_dumper/09-cut.png