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.
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.
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.
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.
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?
On Mon, Dec 11, 2017 at 10:03 AM, Andreas Hennings andreas@dqxtech.net
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.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
On Mon, Dec 11, 2017 at 10:03 AM, Andreas Hennings andreas@dqxtech.net
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?
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
On Mon, Dec 11, 2017 at 10:23 AM, Andreas Hennings andreas@dqxtech.net
wrote:
On Mon, Dec 11, 2017 at 10:03 AM, Andreas Hennings andreas@dqxtech.net
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 FQNI was following the FQN definition from php-fig group like here,
https://github.com/php-fig/fig-standards/blob/master/
accepted/PSR-4-autoloader.mdMaybe this is wrong?
See http://php.net/manual/en/language.namespaces.rules.php
What you mean is a "qualified name" so it would be a QN.
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
On Mon, Dec 11, 2017 at 10:23 AM, Andreas Hennings andreas@dqxtech.net
wrote:On Mon, Dec 11, 2017 at 10:03 AM, Andreas Hennings andreas@dqxtech.net
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 FQNI 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?
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.