Re: Re: [RFC] var_representation() : readable alternative to var_export()
| From: | tyson andre | Date: | Fri, 05 Feb 2021 01:30:35 +0000 |
| Subject: | Re: Re: [RFC] var_representation() : readable alternative to var_export() | ||
| References: | 1 2 3 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-113086@lists.php.net to get a copy of this message | ||
Hi internals,
> > > I've
> > > created https://wiki.php.net/rfc/readable_var_representation based
> > > on
> > > my original proposal in
> > > https://externals.io/message/112924
> > >
> > > This RFC proposes adding a new function
var_representation(mixed
> > > $value, int $flags=0): string
> > > with the following differences from var_export:
> > >
> > > 1. var_representation() unconditionally returns a string
> > > 2. Use null instead of
> > > NULL - lowercase is recommended by more coding
> > > guidelines (https://www.php-fig.org/psr/psr-2/).
> > > 3. Change the way indentation is done for arrays/objects.
> > > See ext/standard/tests/general_functions/short_var_export1.phpt
> > > (e.g. always add 2 spaces, never 3 in objects, and put the array start on the
> > > same line as the key)
> > > 4. Render lists as "['item1']"
> > > rather than "array(\n 0 => 'item1',\n)"
> > >
> > > Always render empty lists on a single line, render multiline by default when
> > > there are 1 or more elements
> > > 5. Prepend \ to class names so that generated code
> > > snippets can be used in
> > > namespaces without any issues.
> > > 6. Support VAR_REPRESENTATION_SINGLE_LINE in
> > > $flags.
> > > This will use a single-line representation for arrays/objects, though
> > > strings with embedded newlines will still cause newlines in the output.
> > > 7. If a string contains control characters("\x00"-"\x1f" and
> > > "\x7f"(backspace)),
> > > then represent the entire string as a double quoted string
> > > escaping \r, \n,
> > > \t, \$, \\óW¶LH…
> > > ^!ê$&�½, and \", in addition to escaping remaining control
> > > characters
> > > with hexadecimal encoding (\x00, \x7f, etc)
> > >
> > > This is different from my original proposal in two ways:
> > > 1. The function signature and name changed from my previous proposal.
> > > It now always returns a string.
> > > 2. Backspace control characters (\x7f) are now also escaped.
> >
> > A reminder that voting on the var_representation RFC starts in a day.
> > This RFC proposes adding a new function var_representation(mixed $value,
> > int $flags=0): string with multiple improvements on
> > var_export().
> >
> > Any other feedback?
>
> Given the recent discussion in the interactive shell thread,
> I think you should consider whether the new function could also be expanded to serve that use
> case.
> I think that if we're going to add one more dumping function to the 4 we already have,
> it better cover all the use-cases we have.
> The "limited size dump" doesn't really fit in with "dump is executable PHP
> code",
> but if I understand correctly, executable PHP code is not the whole goal of the proposal.
I suppose that technically could be done by adding a VAR_REPRESENTATION_DEBUG_DUMP flag to a $flags
bitmask to generate var_dump output,
and allow that to be combined with VAR_REPRESENTATION_SINGLE_LINE and other style flags.
I should at least mention it as an option - that possibly combines unrelated functionality (Debug vs
evaluable code) in flags,
but at least it cuts down on the number of different functions.
I don't plan to include that in this RFC.
-----
I have considered it but think that readable executable PHP code and debug representations are
largely incompatible -
having a function to generate executable PHP code that generates a truncated representation of a
value doesn't seem as useful.
If you're generating code to eval() - you're usually generating all of it.
For example, for this
```
php > $x = (object)[]; $v = [$x, $x]; echo var_representation($v);
[
(object) [],
(object) [],
]
```
In an application where the identity or use of refereinces in the object didn't matter (e.g.
read but not modified), that might be the best representation.
A hypothetical function could emit '(static function () { $t1 = (object)[]; return [$t1,
$t1]; })();'
if it detected object duplication or references (and so on),
and likely be faster at generating output than a userland implementation such as https://github.com/brick/varexporter
(and avoid limitations of ReflectionReference only being able to check individual pairs at a time),
but I'm concerned that there's not much interest in that, and the response would be
"this should go in a PECL instead"
due to the complexity of an implementation, edge cases that unserialize solves but not the
hypothetical function, and due to the ongoing requirement to maintain it.
- e.g. some internal classes forbid newInstanceWithoutConstructor()
- If an application needed all of the functionality of serialize, it's already possible to
generate a call to unserialize instead.
I feel like trying to do everything at once would increase the scope to the point
where the RFC and implementation would be hard to implement and review.
with only a few people responding so far with mixed feedback I think it's too early to do that.
There's other orthogonal improvements
(e.g. Internal objects don't implement __set_state (alternately, have a way to
specify a constructor classes support instead of dumping __set_state)
(ArrayObject::__set_state, SplObjectStorage::__set_state,
GMP::__set_state, etc. currently do not exist))
Thanks,
Tyson