Debug output improvement thoughts - markstory/cakephp GitHub Wiki
Problems with current implementation
- Cyclic objects are dumped endlessly until depth is reached.
- HTML output doesn't use any interactive features making the output fully expanded by default.
- Output has no formatting/highlight in HTML or CLI modes.
Good things to keep
- Disable in non-debug mode.
- Includes line ref to where the dump is.
- CLI output has start/end delimiters.
Things to improve
- ✅ Fix cyclic reference handling.
- ✅ Each object could be stored in the context map based on its id. This could help prevent duplicate visits.
- Traverse the provided variable and store each part of the graph in container objects that allow data to be annotated for formatted.
- Use a formatter (CLI/HTML) that can render output based on the data graph generated in the step above. The formatter would need to track which nodes have had their representation dumped and which can be output as a 'reference'.
- For HTML dumping clicking a reference would need JS to reveal the path to the representation, and highlighting.
Variable Annotation
In order to enable multiple output formats, the variable dumping and output have to be separated. Right now the string output is built during tree traversal. If we first converted the value in a DumpNode
tree we could also annotation the nodes in that tree with metadata to use in formatting. Each DumpNode
would need:
- The child nodes, this would be a list of nodes or a single node.
- The type of node (object, scalar, array, resource, unknown)
- The value of the node if it is a leaf node.
Some examples:
$v = new stdClass();
$v->name = 'foo';
$v->list = ['bar', 'key' => 'value', 1];
$v->obj = $v
Could be turned into a tree that looks like:
ClassNode(
class=stdClass
id=1
properties=[
PropertyNode(
name=name
visibility=public
value=ScalarNode(type=string, value='foo'
)
PropertyNode(
name=list
visibility=protected
value=ArrayNode(
items=[
ItemNode(key=0, value=ScalarNode(type=string, value='bar'))
ItemNode(key='key', value=ScalarNode(type=string, value='value'))
ItemNode(key=1, value=ScalarNode(type=int, value=1))
]
),
PropertyNode(
name=obj
value=ReferenceNode(
class=stdClass
id=2
)
)
)
Nodes would have methods to iterate their children (items, properties). Container types would have methods to append children. Value types would have method to get the type/value, and reference nodes would act as links to other objects in the tree.
Creating an abstract tree will take more time/memory than the current implementation but will enable more rich output to be created. It will also allow us to consolidate the dump output in debugkit with core code.