Hi Bob Weinand, > > Am 20.01.2021 um 01:55 schrieb tyson andre <tysonandre...@hotmail.com>: > > > > Hi internals, > > > > 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.) 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. 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. 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; /** * This is a C-like php function used as an example of the proposed logic for truncating strings. * The real implementation would be written in C instead. * * The goal is to limit both of the following: * 1. The **approximate** number of lines, for terminals for limited scrollback. * 2. The **approximate** number of bytes, when that is a limitation (e.g. poor internet connection, inefficient terminal, etc.) * * The ini settings cli.interactive_shell_result_function_byte_limit and cli.interactive_shell_result_function_line_limit * are proposed for controlling this limitation. * * This deliberately makes no attempt at inferring tab width, terminal width, line ending of the **terminal emulator** * (e.g. windows sshed into linux, or a console output log that's viewed later in a web browser), or character encoding. */ function truncate_string(string $raw_output, int $max_lines = 100, int $max_bytes = 8000): ?string { $max_lines = min($max_bytes, $max_lines); if ($max_lines <= 0) { return NULL; } $strlen = strlen($raw_output); if ($strlen <= $max_lines) { return $raw_output; } $max_bytes = min($max_bytes, $strlen); $truncated = false; $original = $raw_output; $total_lines = 0; $offset = 0; for ($i = 0; $i < $max_bytes && $total_lines < $max_lines; $i++) { switch ($raw_output[$i]) { case "\n": case "\v": // give up on obscure vertical tab character, treat it like a newline $total_lines++; $offset = 0; break; case "\r": if (($raw_output[$i + 1] ?? "\0") === "\n") { $i++; } $total_lines++; $offset = 0; break; case "\t"; $offset += ASSUMED_TAB_WIDTH - ($offset % ASSUMED_TAB_WIDTH); if ($offset >= ASSUMED_BYTES_PER_LINE) { $total_lines++; $offset = ($offset - ASSUMED_BYTES_PER_LINE) % ASSUMED_TAB_WIDTH; } break; default: $offset++; if ($offset >= ASSUMED_BYTES_PER_LINE) { $total_lines++; $offset = 0; } break; } } if ($i >= $strlen) { return $raw_output; } return substr($raw_output, 0, $i) . "..."; // C appends newlines already if there was none } // 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))); ``` Thanks, - Tyson -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php