Skip to content

Commit

Permalink
feature #4424 [#4243] Tweaks to the new var-dumper component (weaverr…
Browse files Browse the repository at this point in the history
…yan, nicolas-grekas)

This PR was merged into the master branch.

Discussion
----------

[#4243] Tweaks to the new var-dumper component

| Q             | A
| ------------- | ---
| Doc fix?      | yes
| New docs?     | no
| Applies to    | 2.6
| Fixed tickets | none

Hi guys!

This follows after #4243 - the best way to review it was to merge, read from scratch, and make these final tweaks. As always, I've certainly made some mistakes, so I appreciate the review.

Thanks!

Commits
-------

1a29f24 typos in the var-dumper component
265604b [#4243] Tweaks to the new var-dumper component
  • Loading branch information
weaverryan committed Nov 13, 2014
2 parents 9caea6f + 1a29f24 commit 3329bd2
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 29 deletions.
81 changes: 57 additions & 24 deletions components/var_dumper/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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() <Symfony\\Component\\VarDumper\\VarDumper::dump>`.
You can change the behavior of this function by calling
:method:`VarDumper::setHandler($callable) <Symfony\\Component\\VarDumper\\VarDumper::setHandler>`:
calls to ``dump()`` will then be forwarded to ``$callable``.
:method:`VarDumper::setHandler($callable) <Symfony\\Component\\VarDumper\\VarDumper::setHandler>`.
Calls to ``dump()`` will then be forwarded to ``$callable``.

By adding a handler, you can customize the `Cloners`_, `Dumpers`_ and `Casters`_
as 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`
Expand All @@ -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 dumper
// 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;
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -70,14 +92,17 @@ 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();

$dumper->dump($cloner->cloneVar($variable));

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
Expand All @@ -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 = '';
Expand All @@ -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();
Expand All @@ -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
Expand All @@ -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);

Expand Down Expand Up @@ -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::

Expand All @@ -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::
Expand Down
39 changes: 34 additions & 5 deletions components/var_dumper/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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::

Expand Down Expand Up @@ -101,8 +109,8 @@ original value. You can configure the limits in terms of:
<config max-items="250" max-string-length="-1" />
</container>
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,
Expand All @@ -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

Expand All @@ -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

Expand All @@ -144,6 +154,7 @@ then its dump representation::
}
$var = new PropertyExample();
dump($var);
.. image:: /images/components/var_dumper/03-object.png

Expand All @@ -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

Expand All @@ -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\n"
."that are best represented as constants, like\n"
."`severity` below. Hovering displays the value (`2`).\n",
0,
E_WARNING
);
dump($var);
.. image:: /images/components/var_dumper/06-constants.png

Expand All @@ -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

Expand All @@ -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,\n"
."or when some special objects are encountered,\n"
."children can be replaced by an ellipsis and\n"
."optionnally followed by a number that says how\n"
."many have been removed; `9` in this case.\n"
);
dump($var);
.. image:: /images/components/var_dumper/09-cut.png

Expand Down

0 comments on commit 3329bd2

Please sign in to comment.