Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] Reflection API: Add ::getFullName() method.

Posted by Andreas Hennings 
Andreas Hennings
[PHP-DEV] Reflection API: Add ::getFullName() method.
December 11, 2017 04:10AM
I propose a new method ::getFullName() for all methods that implement
\Reflector.
(I would add it to the \Reflector interface, but this would be a BC break.)

The full name would be, depending on the type:

function: "str_replace()", "Acme\foo()".
class: "Acme\Animal\Cat", "stdClass".
method: "Acme\Animal\Cat::meow()".
property: "Acme\Animal\Cat::$color".
etc.

I don't know if we can cover all reflection API classes in a meaningful way.
E.g. for ReflectionObject, the full name would be the same as for the
class, otherwise it would get complicated.

Currently the ::__toString() and ::export() return something else,
which is not really useful.

The goal is to have something that is different for different items.
E.g. a class and a function with the same name need to have a
different "full name", hence the added "()" for functions and methods.

As a rule of thumb, the "full name" is what one would put after a @see
tag in phpDoc, but without the leading "\\".
For consistency with the rest of PHP and reflection API, we should use
QN and not FQN as return value.


Related: I started another thread proposing a ::getHash() method.
I originally though to propose the two things in the same thread, but
I now think they should be discussed independently.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Marco Pivetta
Re: [PHP-DEV] Reflection API: Add ::getFullName() method.
December 11, 2017 09:20AM
If you really want to expose a symbol's FQN, I suggest exposing the
internal name as per `(array)` cast semantics.

namespace A {
class B {
public $c;
private $d;
private $e;
}
}

That would be:

"A\B#\$c"
"A\B#\0*\0\$d"
"A\B#\0A\\B\0\$e"

Obviously, the `\0` is horrible and can probably be improved: depends on
whether the API is intended for human or machine consumption. If it is
machine consumption, strings are the wrong approach anyway.

I'd also add that this would be (fucking finally!) a good way to fix PHP's
documentation horrible usage of `::` for both instance and static members.

On 11 Dec 2017 04:00, "Andreas Hennings" <[email protected]> wrote:

I propose a new method ::getFullName() for all methods that implement
\Reflector.
(I would add it to the \Reflector interface, but this would be a BC break.)

The full name would be, depending on the type:

function: "str_replace()", "Acme\foo()".
class: "Acme\Animal\Cat", "stdClass".
method: "Acme\Animal\Cat::meow()".
property: "Acme\Animal\Cat::$color".
etc.

I don't know if we can cover all reflection API classes in a meaningful way.
E.g. for ReflectionObject, the full name would be the same as for the
class, otherwise it would get complicated.

Currently the ::__toString() and ::export() return something else,
which is not really useful.

The goal is to have something that is different for different items.
E.g. a class and a function with the same name need to have a
different "full name", hence the added "()" for functions and methods.

As a rule of thumb, the "full name" is what one would put after a @see
tag in phpDoc, but without the leading "\\".
For consistency with the rest of PHP and reflection API, we should use
QN and not FQN as return value.


Related: I started another thread proposing a ::getHash() method.
I originally though to propose the two things in the same thread, but
I now think they should be discussed independently.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Andreas Hennings
Re: [PHP-DEV] Reflection API: Add ::getFullName() method.
December 11, 2017 10:10AM
On 11 December 2017 at 09:16, Marco Pivetta <[email protected]> wrote:
> If you really want to expose a symbol's FQN,

Just to clarify: For me, "FQN" means "fully-qualified name", which
begins with "\\".
This is specifically not what I propose here. I want the name without
the leading namespace separator.
So maybe "getFullName()" is misleading.

> I suggest exposing the internal
> name as per `(array)` cast semantics.

This distinction is not needed here.
The semantics for array keys in array-to-object casting are to
distinguish overshadowed private properties from parent classes.
This is because values for these properties can coexist within one object.

E.g.

class B {
private $x = 'b';
}

class C extends B {
private $x = 'c';
}

var_export((array)(new C));


Output: https://3v4l.org/0QE3s

array (
'' . "\0" . 'C' . "\0" . 'x' => 'c',
'' . "\0" . 'B' . "\0" . 'x' => 'b',
)


For ReflectionClass->getProperties() and ->getProperty($name) only
gives us the version of each property that is visible on the top
level.

https://3v4l.org/LWWSf

E.g.

$obj = new

(new \ReflectionClass(C::class)->getProperty('x')



>
> namespace A {
> class B {
> public $c;
> private $d;
> private $e;
> }
> }
>
> That would be:
>
> "A\B#\$c"
> "A\B#\0*\0\$d"
> "A\B#\0A\\B\0\$e"
>
> Obviously, the `\0` is horrible and can probably be improved: depends on
> whether the API is intended for human or machine consumption. If it is
> machine consumption, strings are the wrong approach anyway.

Machine or human?
One goal is that these names can be used as array keys or unique
identifiers whenever we deal with a collection of reflectors of mixed
type.
At the same time, the name is designed to be very close to what is
printed in exception messages, @see doc comment, etc.
In this case, I don't see a conflict between human-readable and
machine-readable.

Maybe when you say "machine consumption" you are thinking of something else?


>
> I'd also add that this would be (fucking finally!) a good way to fix PHP's
> documentation horrible usage of `::` for both instance and static members.

Ok, tbh, so far I thought of using the same "::" for both :)
So for all properties it would be Cat::$color.

Maybe instead we could do Cat->color for instance members?

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Marco Pivetta
Re: [PHP-DEV] Reflection API: Add ::getFullName() method.
December 11, 2017 10:20AM
On Mon, Dec 11, 2017 at 10:03 AM, Andreas Hennings <[email protected]>
wrote:

> On 11 December 2017 at 09:16, Marco Pivetta <[email protected]> wrote:
> > If you really want to expose a symbol's FQN,
>
> Just to clarify: For me, "FQN" means "fully-qualified name", which
> begins with "\\".
> This is specifically not what I propose here. I want the name without
> the leading namespace separator.
> So maybe "getFullName()" is misleading.
>

A FQN does not start with `\`. In strings, you always use the FQN


>
> > I suggest exposing the internal
> > name as per `(array)` cast semantics.
>
> This distinction is not needed here.
> The semantics for array keys in array-to-object casting are to
> distinguish overshadowed private properties from parent classes.
> This is because values for these properties can coexist within one object.
>
> E.g.
>
> class B {
> private $x = 'b';
> }
>
> class C extends B {
> private $x = 'c';
> }
>
> var_export((array)(new C));
>
>
> Output: https://3v4l.org/0QE3s
>
> array (
> '' . "\0" . 'C' . "\0" . 'x' => 'c',
> '' . "\0" . 'B' . "\0" . 'x' => 'b',
> )
>
>
> For ReflectionClass->getProperties() and ->getProperty($name) only
> gives us the version of each property that is visible on the top
> level.
>
> https://3v4l.org/LWWSf
>
> E.g.
>
> $obj = new
>
> (new \ReflectionClass(C::class)->getProperty('x')
>

That still makes merging property definitions extremely messy - as a heavy
reflection user, I don't see the value in such an API then, besides display
(var_dump()) purposes...

>
> > namespace A {
> > class B {
> > public $c;
> > private $d;
> > private $e;
> > }
> > }
> >
> > That would be:
> >
> > "A\B#\$c"
> > "A\B#\0*\0\$d"
> > "A\B#\0A\\B\0\$e"
> >
> > Obviously, the `\0` is horrible and can probably be improved: depends on
> > whether the API is intended for human or machine consumption. If it is
> > machine consumption, strings are the wrong approach anyway.
>
> Machine or human?
> One goal is that these names can be used as array keys or unique
> identifiers whenever we deal with a collection of reflectors of mixed
> type.
> At the same time, the name is designed to be very close to what is
> printed in exception messages, @see doc comment, etc.
> In this case, I don't see a conflict between human-readable and
> machine-readable.
>
> Maybe when you say "machine consumption" you are thinking of something
> else?
>

Machine consumption would be VOs, not strings ;-)

>
> > I'd also add that this would be (fucking finally!) a good way to fix
> PHP's
> > documentation horrible usage of `::` for both instance and static
> members.
>
> Ok, tbh, so far I thought of using the same "::" for both :)
> So for all properties it would be Cat::$color.
>
> Maybe instead we could do Cat->color for instance members?
>

I have been using `#` for a while, but I can adapt as long as the problem
is being fixed at some point in time :P

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/
Andreas Hennings
Re: [PHP-DEV] Reflection API: Add ::getFullName() method.
December 11, 2017 10:30AM
On 11 December 2017 at 10:16, Marco Pivetta <[email protected]> wrote:
> On Mon, Dec 11, 2017 at 10:03 AM, Andreas Hennings <[email protected]>
> wrote:
>>
>> On 11 December 2017 at 09:16, Marco Pivetta <[email protected]> wrote:
>> > If you really want to expose a symbol's FQN,
>>
>> Just to clarify: For me, "FQN" means "fully-qualified name", which
>> begins with "\\".
>> This is specifically not what I propose here. I want the name without
>> the leading namespace separator.
>> So maybe "getFullName()" is misleading.
>
>
> A FQN does not start with `\`. In strings, you always use the FQN

I was following the FQN definition from php-fig group like here,

https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md

Maybe this is wrong?

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Marco Pivetta
Re: [PHP-DEV] Reflection API: Add ::getFullName() method.
December 11, 2017 10:40AM
Weird, that looks wrong to me, so I may be wrong here.

When receiving a string containing a symbol, the only sensible approach is
to consider it a FQN, as no context is provided with the string.

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On Mon, Dec 11, 2017 at 10:23 AM, Andreas Hennings <[email protected]>
wrote:

> On 11 December 2017 at 10:16, Marco Pivetta <[email protected]> wrote:
> > On Mon, Dec 11, 2017 at 10:03 AM, Andreas Hennings <[email protected]>
> > wrote:
> >>
> >> On 11 December 2017 at 09:16, Marco Pivetta <[email protected]> wrote:
> >> > If you really want to expose a symbol's FQN,
> >>
> >> Just to clarify: For me, "FQN" means "fully-qualified name", which
> >> begins with "\\".
> >> This is specifically not what I propose here. I want the name without
> >> the leading namespace separator.
> >> So maybe "getFullName()" is misleading.
> >
> >
> > A FQN does not start with `\`. In strings, you always use the FQN
>
> I was following the FQN definition from php-fig group like here,
>
> https://github.com/php-fig/fig-standards/blob/master/
> accepted/PSR-4-autoloader.md
>
> Maybe this is wrong?
>
Andreas Hennings
Re: [PHP-DEV] Reflection API: Add ::getFullName() method.
December 11, 2017 10:40AM
See http://php.net/manual/en/language.namespaces.rules.php

What you mean is a "qualified name" so it would be a QN.

On 11 December 2017 at 10:28, Marco Pivetta <[email protected]> wrote:
> Weird, that looks wrong to me, so I may be wrong here.
>
> When receiving a string containing a symbol, the only sensible approach is
> to consider it a FQN, as no context is provided with the string.
>
> Marco Pivetta
>
> http://twitter.com/Ocramius
>
> http://ocramius.github.com/
>
> On Mon, Dec 11, 2017 at 10:23 AM, Andreas Hennings <[email protected]>
> wrote:
>>
>> On 11 December 2017 at 10:16, Marco Pivetta <[email protected]> wrote:
>> > On Mon, Dec 11, 2017 at 10:03 AM, Andreas Hennings <[email protected]>
>> > wrote:
>> >>
>> >> On 11 December 2017 at 09:16, Marco Pivetta <[email protected]> wrote:
>> >> > If you really want to expose a symbol's FQN,
>> >>
>> >> Just to clarify: For me, "FQN" means "fully-qualified name", which
>> >> begins with "\\".
>> >> This is specifically not what I propose here. I want the name without
>> >> the leading namespace separator.
>> >> So maybe "getFullName()" is misleading.
>> >
>> >
>> > A FQN does not start with `\`. In strings, you always use the FQN
>>
>> I was following the FQN definition from php-fig group like here,
>>
>>
>> https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md
>>
>> Maybe this is wrong?
>
>

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Andreas Hennings
Re: [PHP-DEV] Reflection API: Add ::getFullName() method.
December 11, 2017 11:30AM
>> >
>> > Obviously, the `\0` is horrible and can probably be improved: depends on
>> > whether the API is intended for human or machine consumption. If it is
>> > machine consumption, strings are the wrong approach anyway.
>>
>> Machine or human?
>> One goal is that these names can be used as array keys or unique
>> identifiers whenever we deal with a collection of reflectors of mixed
>> type.
>> At the same time, the name is designed to be very close to what is
>> printed in exception messages, @see doc comment, etc.
>> In this case, I don't see a conflict between human-readable and
>> machine-readable.
>>
>> Maybe when you say "machine consumption" you are thinking of something
>> else?
>
>
> Machine consumption would be VOs, not strings ;-)

One purpose of such names would be that they can be saved in a file or
database, and read in another process.

If you want a value object, then why not use the reflector object directly?
Ok, because "side effects" - I agree.

If we want a value object, it should be named like "ReflectorHandle",
and then "ClassHandle", "FunctionHandle" etc.
These would provide the name of a class, but not any information about it.

But this should be in a separate method, e.g.
ReflectionClass->getHandle(), and it would be a separate feature for a
separate thread.

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Sorry, only registered users may post in this forum.

Click here to login