2015-11-09 16:27 GMT+01:00 Steven Hilder <
steven.hilder@sevenpercent.solutions>:

> On Thu, 05 Nov 2015 15:14:47, Leigh <lei...@gmail.com> wrote:
>
>> On 5 November 2015 at 14:59, Rowan Collins <rowan.coll...@gmail.com>
>> wrote:
>>
>>> PHP uses null bytes quite a lot to produce deliberately illegal
>>> identifiers. For instance the old eval-like create_function() [e.g.
>>> https://3v4l.org/hqHjh] and the serialization of private members [e.g.
>>> https://3v4l.org/R6Y6k]
>>>
>>> In this case, I guess the "@" in "class@anonymous" makes the name
>>> illegal
>>> anyway, but I'm not sold on the null byte being more unacceptable here
>>> than anywhere else.
>>>
>>> Regards,
>>>
>>> --
>>> Rowan Collins
>>> [IMSoP]
>>>
>>
>> That doesn't mean it's a good approach (*cough* namespaces *cough*), and
>> these bits of "magic" are supposed to be hidden away from users. I'm
>> guessing in this particular instance, the point of the null is to make
>> string operations cut off after "anonymous", however string operations
>> that respect the zval string length aren't going to do this.
>>
>> e.g. var_dump() the class name is put through sprintf and it cuts off at
>> the null, but get_class or ReflectionClass::getName() just returns the
>> original string, and exposes the implementation details.
>>
>
> Internal names for anonymous classes need to be unique.
>
> The current method of ensuring uniqueness ('\0' + filename + lexer pos) was
> written by Dmitry[1], following from Joe's original implementation[2]. As I
> understand it, this was supposed to be entirely hidden from userland; hence
> the null byte.
>
> So, I prepared a patch for `get_class()` and `ReflectionClass::getName()`,
> which in my view should behave the same way as `var_dump()` etc., but I've
> now realised that ignoring the unique suffix from the class name will break
> functionality that is otherwise desirable:
>
> * Aliasing an anonymous class... (see bug70106[3])
>
>     $instance = new class {};
>     $class_name = get_class($instance);
>     class_alias($class_name, 'MyAlias');
>
> * Creating a new anonymous class instance dynamically...
>
>     $instance = new class {};
>     $class_name = get_class($instance);
>     $new_instance = new $class_name;
>
>     ...although the `get_class()` used here isn't necessary, and you could
>     write `= new $instance;` without ever knowing $instance's class.
>
> Our options seem to be:
>
> (A) Leave everything as it is. This puts us in a situation where anonymous
>     class names are treated inconsistently in userland; a situation that I
>     think could lead to considerable confusion about the "real" names of
>     these classes and how they should be used.
>
> (B) Patch `get_class()` and `ReflectionClass::getName()` (any others?) to
>     strip the suffix (the '\0' and everything after it) from anonymous
> class
>     names prior to display. This prevents userland code from distinguishing
>     between multiple anonymous classes; breaking functionality as described
>     above. To mitigate this, we could allow `class_alias()` to accept
> either
>     a class name OR an instance in the first argument. The `new` operator
>     already supports an instance in place of a class name.
>
> (C) Assuming that userland SHOULD have access to the internal names of
>     anonymous classes, remove the null byte so that the full names are
>     displayed everywhere. The drawback of this option is that class names
>     won't be as predictable. It occurs to me that a different naming scheme
>     could help here - wouldn't a monotonically increasing integer suffix be
>     enough? The current scheme seems like an awful waste of memory, too.
>
> Option (B) seems like the best to me, because I can't really see a need to
> know the unique suffix -- provided any use-cases are catered for by an
> alternative (modifying `class_alias()` should be enough).
>
> Thoughts?
>
> Steve
>
> [1] http://git.php.net/?p=php-src.git;a=commitdiff;h=2a1b0b1#patch1
> [2] http://git.php.net/?p=php-src.git;a=commitdiff;h=49608e0#patch12
> [3] https://bugs.php.net/bug.php?id=70106
>

Having the path info is quite useful for debugging purposes.

Regards, Niklas

Reply via email to