Hi Bob Weinand,

>>>> Voting has started on 
>>>> https://wiki.php.net/rfc/readline_interactive_shell_result_function
>>>> on 2021-01-19, and ends on 2021-02-02.
>>>>
>>>> This RFC proposes to dump the results of non-null expressions using 
>>>> var_dump/var_export() by default in `php -a` (the interactive shell).
>>>> Additionally, this adds a new function 
>>>> `readline_interactive_shell_result_function` to the readline PHP module.
>>>> This function only affects interactive shells - it can optionally be used 
>>>> to set or clear a closure when `extension_loaded('readline') === true`,
>>>> but that closure would only be called in interactive shells (i.e. php -a).
>>>> (That closure would be called instead of the native implementation with 
>>>> the snippet of code that was evaluated and the expression's result,
>>>> if a php statement contained a single expression such as `2+2;` or `$x = 
>>>> [1,2];` (that could be used as the expression of a return statement)
>>>> - Dumping of expression results can be disabled using an ini setting or at 
>>>> runtime
>>>>
>>>> Thanks,
>>>> - Tyson
>>>
>>> Hey Tyson,
>>>
>>> My main concern in this iteration of the RFC is: what happens with 
>>> big/deeply nested objects?
>>> They tend to spew tons of lines if var_dump()'ed. Do we have reasonable 
>>> depth/output limitations in default dumping mode?
>>>
>>> I'm often enough using php -a to do some quick ad-hoc processing (example, 
>>> read a big json file, and then access a value; instantiating a mediawiki 
>>> bot framework and calling replace on it; ...).
>>>
>>> It's really cool to have any interactive feedback at all, but please, at 
>>> least by default, limit the output. (An example is the JS REPL in browser 
>>> console - it shows you a minimal preview of the object, and then you can 
>>> expand with your mouse. Obviously with a pure cli application, this needs 
>>> different - intuitive - navigation.)
>>>
>>> As it currently stands, this makes php -a unusable in any but the simplest 
>>> cases, without just disabling the whole feature.
>>>
>>> I like the whole feature, but the missing output limitation (I have yet 
>>> enough nightmares from var_dump()'ing the wrong object filling my shell 
>>> with tons of irrelevant information… I don't need that potentially 
>>> happening on every single evaluated expression)
>>>
>>> Thus I'm voting no, for now.
>>
>> As-is, the entire object or string would be dumped with var_export/var_dump 
>> to stdout.
>>
>> Thoughts on the adding following output truncation mechanism
>> (for the default C result dumper implementation)
>> before printing the results of the returned expression
>> (the user output continues to be untruncated, and the existence of cli.pager
>> would not affect this mechanism in case the binary is not actually a pager)?
>> For arrays/objects used with var_dump - the equivalent of
>> `ob_start(); var_dump($result); $result = ob_get_clean();`
>> would have to be used first from C since var_dump still writes to the output 
>> buffer (php_printf(), etc.)
>
>var_dump() tends to be quite intensive in newline usage. I don't think 
>var_dump() (as is) is the best mechanism to print. At least I'd use one 
>property/one array argument = single line instead of two lines.
>Additionally, when dumping a nested object, it's more valuable to see as much 
>as possible from the primary object rather than the deep nesting.
>
>
>> I'd omitted output truncation from the RFC because I wasn't sure how many 
>> people
>> would consider it excessive to include a limit on var_dump output, and there 
>> was little feedback before the RFC vote started.
>
>Yeah, sorry for the late comment on that :-)
>
>> The simplest implementation would be to truncate to a byte limit and append 
>> `...` if truncated,
>> but the main concern that's been brought up is the approximate number of 
>> lines.
>> Obviously, there'd be a value in truncating the output if there were to be 
>> megabytes of output,
>> though exactly what settings make sense as a default would vary.
>
>As mentioned a section earlier, there should be limits according to the 
>nesting-level … e.g. if it's the top-level value, a string may have 20 lines 
>printed and array and objects as well. And array entries/properties should 
>then be in a single line or take up to max ... 20 / count(properties or array 
>entries) lines (width before truncation can be determine from terminal width), 
>which then can be mostly in one line flattened output.
>The general rule here should be, show me my object/array at hand and give me a 
>brief overview of what's nested within - and if I'm interested in detail, let 
>me (manually) output that object.
>Also consider, when dumping strings within (nested) arrays/objects to replace 
>newlines with \n, for nicer display.
>
>> C would not print anything (e.g. `=> `) or even call var_dump/var_export if 
>> the limits were set to 0.
>>
>> ```
>> <?php
>>
>> const ASSUMED_BYTES_PER_LINE = 80;
>> const ASSUMED_TAB_WIDTH = 4;
>
>On that topic, may make sense to also fetch the actual terminal width and 
>heights respectively (ioctl TIOCGWINSZ).
>I.e. if terminal is 20 lines high, printing 20 lines is a lot. if it's 80 
>lines high, 20 lines is acceptable.
>
>> // unmodified
>> var_dump(truncate_string("test short string"));
>> // 5000 'A's followed by "...\n"
>> var_dump(truncate_string(str_repeat('A', 10000)));
>> // 100 lines containing "A" followed by "...\n"
>> var_dump(truncate_string(str_repeat("A\n", 10000)));
>> ```
>
>I'd wager nobody needs a hundred lines, I'd use inspiration from debuggers 
>which typically show 5-20 lines max.
>IF you want to print it all, it's just as easy as `echo $var;` though.
>
>So overall: try to make efficient usage of horizontal as well as vertical 
>space while still remaining usable and readable.

I'm not sure if I want to do anything that complicated or if there'd be a 
consensus on how to indent each level.
Having the same rules at any indent level would be my preference.

Another idea I'd had would be to add a new function
`var_dump_as_string(mixed $value, int $use_placeholders_after_lines = -1, int 
$use_placeholders_after_lines = -1)` to

1. Escape control characters in the same way as the proposed var_representation
2. Replace remaining fields with `...` if the line limits or byte limits would 
be exceeded by adding a key-value pair
   in arrays/objects that have more fields. (go back and truncate the string if 
necessary)
3. Possibly revisit other representation choices, e.g. put values on the same 
lines as keys

```
php > echo var_dump_as_string(range(0,99), use_placeholder_after_lines: 5);
array(100) {
  [0]=>int(0)
  [1]=>int(1)
  ...
}
php > var_dump("a\n\"b");
string(4) "a
"b"
php > echo var_dump_as_string("a\n\"b");
string(4) "a\n\"b"
```

This would have the following benefits:

1. In addition to being usable in an interactive shell/REPL,
   it would be possible to use this in other libraries/applications where 
dumping too much debug output is a concern,
   or to invoke it manually (e.g. through a userland wrapper function 
`v($value)`) when debugging.
   (where recursion detection and object ids are useful to have when debugging)
2. Performance and memory usage would be less of a concern when dumping 
extremely large objects.
3. This would avoid the chance of mixing php code output from 
`__debugInfo`/notices with the outputted string,
   which is possible with ob_start()/ob_get_clean()
4. Avoid mixing in control characters such as newlines with debug output when a 
var_dump-like representation is needed.

-Tyson

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to