Hi all,
There are many different use cases were in code we expect classes names
as arguments to functions as fully qualified names. We do this in ZF a
lot with our Service Location and DI components, but also with our code
reflection API, etc. A more interesting use case I would like to call
out is with PHPUnit, for example in a test, you might find this:
$mock = $this->getMock('A\Namespaced\ClassName');
This becomes cumbersome when you are dealing with lots of strings about
lots of class names. This is also an area where, currently, namespace
declaration and use statements offer no real support.
The patch located here:
https://github.com/ralphschindler/php-src/commit/02210d51851a96d723fbedcfc64cde9f9ae2b22a
... implements the ability for a developer to leverage the file's
namespace declaration and use statements to be able to produce a scalar
(string) of the class name that can be then used, for example, as an
argument to a function elsewhere.
This overloads the "class" keyword, and by virtue of the existing usage
of "class" this feature is completely backwards compatible. All
existing tests pass. For example, the above PHPUnit snipped would become:
use A\Namespaced\ClassName;
$mock = $this->getMock(ClassName::class);
Another example with reflection:
use SomeOther\FullyNamespaced\ClassElsewhere as CE;
$r = new ReflectionClass(CE::class);
More examples from the test file:
namespace Foo\Bar {
class Baz {}
var_dump(Moo::CLASS); // "Foo\Bar\Moo"
}
namespace {
use Bee\Bop as Moo,
Foo\Bar\Baz;
var_dump(Baz::class); // "Foo\Bar\Baz"
var_dump(Boo::class); // "Boo"
var_dump(Moo::CLASS); // "Bee\Bop"
var_dump(\Moo::Class); // "Moo"
$class = Baz::class; // assign class as scalar to var
$x = new $class;
var_dump($x); object(Foo\Bar\Baz)#1 (0) {}
}
What do you guys think?
-ralph
I used to implement public static function getClass() { return
get_called_class(); }
, so I really like this one, makes it also easier for
IDEs when refactoring code :)
I was wondering about class A { const CLASS = 'hello'; }
but that would
cause an unexpected T_CLASS
, so I guess there's no conflicts...
Marco Pivetta
Hi all,
There are many different use cases were in code we expect classes names as
arguments to functions as fully qualified names. We do this in ZF a lot
with our Service Location and DI components, but also with our code
reflection API, etc. A more interesting use case I would like to call out
is with PHPUnit, for example in a test, you might find this:$mock = $this->getMock('A\Namespaced**ClassName');
This becomes cumbersome when you are dealing with lots of strings about
lots of class names. This is also an area where, currently, namespace
declaration and use statements offer no real support.The patch located here:
https://github.com/ralphschindler/php-src/commit/
02210d51851a96d723fbedcfc64cde**9f9ae2b22ahttps://github.com/ralphschindler/php-src/commit/02210d51851a96d723fbedcfc64cde9f9ae2b22a... implements the ability for a developer to leverage the file's
namespace declaration and use statements to be able to produce a scalar
(string) of the class name that can be then used, for example, as an
argument to a function elsewhere.This overloads the "class" keyword, and by virtue of the existing usage of
"class" this feature is completely backwards compatible. All existing
tests pass. For example, the above PHPUnit snipped would become:use A\Namespaced\ClassName;
$mock = $this->getMock(ClassName::**class);Another example with reflection:
use SomeOther\FullyNamespaced**ClassElsewhere as CE;
$r = new ReflectionClass(CE::class);More examples from the test file:
namespace Foo\Bar {
class Baz {}
var_dump(Moo::CLASS); // "Foo\Bar\Moo"
}namespace {
use Bee\Bop as Moo,
Foo\Bar\Baz;var_dump(Baz::class); // "Foo\Bar\Baz"
var_dump(Boo::class); // "Boo"
var_dump(Moo::CLASS); // "Bee\Bop"
var_dump(\Moo::Class); // "Moo"$class = Baz::class; // assign class as scalar to var
$x = new $class;
var_dump($x); object(Foo\Bar\Baz)#1 (0) {}
}What do you guys think?
-ralph
Am 14.04.2012 23:14, schrieb Marco Pivetta:
I used to implement
public static function getClass() { return
get_called_class(); }
, so I really like this one, makes it also easier for
IDEs when refactoring code :)I was wondering about
class A { const CLASS = 'hello'; }
but that would
cause an unexpectedT_CLASS
, so I guess there's no conflicts...
I have
class A { const _CLASS = __CLASS__; }
in many classes. This feature would help a lot.
Marco Pivetta
I used to implement
public static function getClass() { return
get_called_class(); }
, so I really like this one, makes it also easier
for IDEs when refactoring code :)
Oh completely, that is one of the major benefits. My current workflow
for refactoring is to refactor with the built-in support, but then also
having to go find/replace on the full class name, just in case.
-ralph
Hi Ralph, hi everybody,
given the clear use case and the simplicity of the patch, a very good idea.
With regards,
Lars
Am 15.04.2012 um 16:13 schrieb Ralph Schindler:
I used to implement
public static function getClass() { return
get_called_class(); }
, so I really like this one, makes it also easier
for IDEs when refactoring code :)Oh completely, that is one of the major benefits. My current workflow for refactoring is to refactor with the built-in support, but then also having to go find/replace on the full class name, just in case.
-ralph
2012/4/14 Ralph Schindler ralph@ralphschindler.com:
Hi all,
There are many different use cases were in code we expect classes names as
arguments to functions as fully qualified names. We do this in ZF a lot
with our Service Location and DI components, but also with our code
reflection API, etc. A more interesting use case I would like to call out
is with PHPUnit, for example in a test, you might find this:$mock = $this->getMock('A\Namespaced\ClassName');
This becomes cumbersome when you are dealing with lots of strings about lots
of class names. This is also an area where, currently, namespace
declaration and use statements offer no real support.The patch located here:
https://github.com/ralphschindler/php-src/commit/02210d51851a96d723fbedcfc64cde9f9ae2b22a
... implements the ability for a developer to leverage the file's namespace
declaration and use statements to be able to produce a scalar (string) of
the class name that can be then used, for example, as an argument to a
function elsewhere.This overloads the "class" keyword, and by virtue of the existing usage of
"class" this feature is completely backwards compatible. All existing tests
pass. For example, the above PHPUnit snipped would become:use A\Namespaced\ClassName;
$mock = $this->getMock(ClassName::class);Another example with reflection:
use SomeOther\FullyNamespaced\ClassElsewhere as CE;
$r = new ReflectionClass(CE::class);More examples from the test file:
namespace Foo\Bar {
class Baz {}
var_dump(Moo::CLASS); // "Foo\Bar\Moo"
}namespace {
use Bee\Bop as Moo,
Foo\Bar\Baz;var_dump(Baz::class); // "Foo\Bar\Baz"
var_dump(Boo::class); // "Boo"
var_dump(Moo::CLASS); // "Bee\Bop"
var_dump(\Moo::Class); // "Moo"$class = Baz::class; // assign class as scalar to var
$x = new $class;
var_dump($x); object(Foo\Bar\Baz)#1 (0) {}
}What do you guys think?
-ralph
--
Hi, Ralph
I really like this feature in general.
One thing I personally dislike in this implementation is the
difference between CLASS and class ... One with and one without
namespaces ...
If we can unify that, this would be a great help in understanding that
feature in future and getting the difference while reading code.
And please don't forget: Code will be written once, maybe rewritten
some times, but it will be read way more times!
Bye
Simon
One thing I personally dislike in this implementation is the
difference between CLASS and class ... One with and one without
namespaces ...
I am not quite following. There is no functional difference between
"class", "CLASS", or "Class". The parser is case insensitive with
regards to keywords, which "class" or T_CLASS
is on of. The code
snipped I showed there was from the .phpt test that I had included in
the Zend/test code base to ensure it worked and did not break existing
tests.
As per the namespaced and non-namespaced blocks, I was demonstrating how
::class would resolve names regardless of if it were a FQCN or a short
class name. Effectively, you can put ::class behind any "type" name and
it should work as demonstrated.
-ralph
2012/4/16 Ralph Schindler ralph@ralphschindler.com
I am not quite following. There is no functional difference between
"class", "CLASS", or "Class". The parser is case insensitive with regards
to keywords, which "class" orT_CLASS
is on of. The code snipped I showed
there was from the .phpt test that I had included in the Zend/test code base
to ensure it worked and did not break existing tests.As per the namespaced and non-namespaced blocks, I was demonstrating how
::class would resolve names regardless of if it were a FQCN or a short class
name. Effectively, you can put ::class behind any "type" name and it should
work as demonstrated.-ralph
Hi, Ralph
Thanks for clarification.
I was missing the backslash before Moo::Class which lead to that thought.
As the class-definition for Moo is missing, I think it's an empty
class (like Baz) on the root-level defined somewhere else, right?
Otherwise this should do something else than guessing the class-name.
Bye
Simon
Hey Simon,
As the class-definition for Moo is missing, I think it's an empty
class (like Baz) on the root-level defined somewhere else, right?
Otherwise this should do something else than guessing the class-name.
If you look at the patch, this feature is not doing anything PHP doesn't
already do in other circumstances - demonstrated by the fact that its
only about 4 lines of code ;)
In PHP, in situations like (instanceof):
if ($foo instanceof Bar)
or (catch)
} catch (SomeException $e) {
or (method signature)
public function setFoo(FooInterface $foo)
... PHP does not invoke the autoloader to determine if the class name
actually exists as a declaration somewhere, it simply resolves it
according to some very specific rules (in the case of this patch,
carried out by zend_resolve_class_name()).
If I am within a namespace and am using a short name without a preceding
"", it means the class I am referencing exists in the current
namespace. Whether or not that class exists is irrelevant as my short
name can only mean "a class by this name in the current namespace". In
this code:
namespace Foo\Bar {
global $foo;
if ($foo && $foo instance Bar) {
// ...
}
}
... that you, the developer, intend that your reference to Baz actually
means "Foo\Bar\Baz", it can never mean anything else.
So, in a nutshell, there is no guessing going on ;)
-ralph
2012/4/16 Ralph Schindler ralph@ralphschindler.com
... PHP does not invoke the autoloader to determine if the class name
actually exists as a declaration somewhere, it simply resolves it according
to some very specific rules (in the case of this patch, carried out by
zend_resolve_class_name()).If I am within a namespace and am using a short name without a preceding
"", it means the class I am referencing exists in the current namespace.
Whether or not that class exists is irrelevant as my short name can only
mean "a class by this name in the current namespace". In this code:namespace Foo\Bar {
global $foo;
if ($foo && $foo instance Bar) {
// ...
}
}... that you, the developer, intend that your reference to Baz actually
means "Foo\Bar\Baz", it can never mean anything else.So, in a nutshell, there is no guessing going on ;)
-ralph
Hi, Ralph
Agree on that. I'd like to have a comment in the test, specially for
this line where you're checking for non-existing classes. It does not
seem to be obvious what should be tested here (at least it was not
obvious for me). This may make it easier to fix stuff if this test
should fail in future.
I don't know if this here is the right test to put the comment in, but
it's at least relying on something global that may change.
Thanks for giving me a deeper knowledge here :)
Bye
Simon
So, at current, is this small enough for just a pull request, or does
this deserve its own RFC?
-ralph
Hi all,
There are many different use cases were in code we expect classes names
as arguments to functions as fully qualified names. We do this in ZF a
lot with our Service Location and DI components, but also with our code
reflection API, etc. A more interesting use case I would like to call
out is with PHPUnit, for example in a test, you might find this:$mock = $this->getMock('A\Namespaced\ClassName');
This becomes cumbersome when you are dealing with lots of strings about
lots of class names. This is also an area where, currently, namespace
declaration and use statements offer no real support.The patch located here:
https://github.com/ralphschindler/php-src/commit/02210d51851a96d723fbedcfc64cde9f9ae2b22a
... implements the ability for a developer to leverage the file's
namespace declaration and use statements to be able to produce a scalar
(string) of the class name that can be then used, for example, as an
argument to a function elsewhere.This overloads the "class" keyword, and by virtue of the existing usage
of "class" this feature is completely backwards compatible. All existing
tests pass. For example, the above PHPUnit snipped would become:use A\Namespaced\ClassName;
$mock = $this->getMock(ClassName::class);Another example with reflection:
use SomeOther\FullyNamespaced\ClassElsewhere as CE;
$r = new ReflectionClass(CE::class);More examples from the test file:
namespace Foo\Bar {
class Baz {}
var_dump(Moo::CLASS); // "Foo\Bar\Moo"
}namespace {
use Bee\Bop as Moo,
Foo\Bar\Baz;var_dump(Baz::class); // "Foo\Bar\Baz"
var_dump(Boo::class); // "Boo"
var_dump(Moo::CLASS); // "Bee\Bop"
var_dump(\Moo::Class); // "Moo"$class = Baz::class; // assign class as scalar to var
$x = new $class;
var_dump($x); object(Foo\Bar\Baz)#1 (0) {}
}What do you guys think?
-ralph
May I suggest using foo::CLASS instead of foo::class ? It's longer, but
closer to what already exists for this semantic (class name as string),
don't you think ?
So, at current, is this small enough for just a pull request, or does this
deserve its own RFC?
Personnaly, I would say that an RFC would be good for historical reference
and documentation.
Nicolas
May I suggest using foo::CLASS instead of foo::class ? It's longer,
but closer to what already exists for this semantic (class name as
string), don't you think ?
As Marco suggested, I think using CLASS would be confusing to some.
CLASS generally means, "where you see this, replace it with the
class you are in right now".
I generally don't like to draw comparisons too closely to Java and .NET,
but Java has this, they call it a "class literal", which works the same
way as described in my new feature:
http://stackoverflow.com/questions/2160788/what-is-a-class-literal-in-java
In .net, if a type is a SystemType.Type object (which I think are all
types), you can simply call a function on it to get the name:
http://msdn.microsoft.com/en-us/library/9f49ew66.aspx
In addition, I am unsure if there would be any BC issues with your
proposed syntax. I do know with mine (::class) does not pose any BC
issues since the class keyword was limited to declaring a class only.
At least, the tests prove this, and I can't find any other usages of
T_CLASS
in the parser.
Personnaly, I would say that an RFC would be good for historical
reference and documentation.
I think you're right, I'll do this today.
-ralph
Hi!
May I suggest using foo::CLASS instead of foo::class ? It's longer, but
closer to what already exists for this semantic (class name as string),
don't you think ?
I like this. CLASS is already being used as class name, and little
chance of colliding with some code since you're not supposed to be using
__ prefix in your names.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Hi!
May I suggest using foo::CLASS instead of foo::class ? It's longer, but
closer to what already exists for this semantic (class name as string),
don't you think ?I like this. CLASS is already being used as class name, and little
chance of colliding with some code since you're not supposed to be using
__ prefix in your names.
From the collisions point of viewclass
and__CLASS__
are equally
safe. They both are lexer keywords, so it's not possible to declare
constants with them as name.
Imho ClassName::class reads nicer and also looks similar to the
similar ClassName.class syntax in Java.
Nikita
From the collisions point of view
class
and__CLASS__
are equally
safe.
Imho ClassName::class reads nicer and also looks similar to the
similar ClassName.class syntax in Java.
The current CLASS could then be written self::class. Looks more
"namespace/object oriented", where CLASS feels procedural?
How would static::class behave ? is it handled by the current patch?
Maybe the test case could be extended to reflect this, and also for
self::class?
How would static::class behave ? is it handled by the current patch?
Maybe the test case could be extended to reflect this, and also for
self::class?
Fantastic question. I am unsure how to handle this. Currently, it will
simply resolve those names against the rules (I am sure this is the
wrong behavior.) So,
namespace Foo\Bar { var_dump(self::class); }
Would now produce:
string(12) "Foo\Bar\self"
This is the same with 'self', 'static', and 'parent'. I guess the
question is, should that produce a compile error, or conditionally work
depending on if you are inside of a class declaration or not?
I will add this consideration to the RFC.
-ralph
Hi!
Fantastic question. I am unsure how to handle this. Currently, it will
simply resolve those names against the rules (I am sure this is the
wrong behavior.) So,namespace Foo\Bar { var_dump(self::class); }
This should produce an error outside of class context, I think. Inside
of class context, self & parent should work, I think, but static can't
work as it's caller-dependent.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
May I suggest using foo::CLASS instead of foo::class ? It's longer, but
closer to what already exists for this semantic (class name as string),
don't you think ?I like this. CLASS is already being used as class name, and little
chance of colliding with some code since you're not supposed to be using
__ prefix in your names.
"class" won't collide anyways, as it's already a keyword, and you can't use it
in your constant or function names. CLASS has bad connotations for me, as it
resolves to the declaring class normally, not the class invoked.
--
Matthew Weier O'Phinney
Project Lead | matthew@zend.com
Zend Framework | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
"class" won't collide anyways, as it's already a keyword, and you can't use it
in your constant or function names. CLASS has bad connotations for me, as it
resolves to the declaring class normally, not the class invoked.
I tend to agree. CLASS to me belongs to the family of constants
like DIR and FILE where they are meant to be evaluated in-place
and are simply a substitution for something completely static.
In my mind, while Foo::class returns a scalar, it is subject to
resolution by use statements generally at the top of a file or namespace
declaration and is computed based on what namespace it is in and what
use statements affect it.
-ralph
Hi!
I tend to agree. CLASS to me belongs to the family of constants
like DIR and FILE where they are meant to be evaluated in-place
and are simply a substitution for something completely static.
But that's exactly what Foo::class is - completely static constant.
In my mind, while Foo::class returns a scalar, it is subject to
resolution by use statements generally at the top of a file or namespace
declaration and is computed based on what namespace it is in and what
use statements affect it.
In the same vein you could say class statements affect CLASS :).
They are both compile-time constants.
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
On Sat, Apr 14, 2012 at 9:50 PM, Ralph Schindler
ralph@ralphschindler.com wrote:
Hi all,
There are many different use cases were in code we expect classes names as
arguments to functions as fully qualified names. We do this in ZF a lot
with our Service Location and DI components, but also with our code
reflection API, etc. A more interesting use case I would like to call out
is with PHPUnit, for example in a test, you might find this:$mock = $this->getMock('A\Namespaced\ClassName');
This becomes cumbersome when you are dealing with lots of strings about lots
of class names. This is also an area where, currently, namespace
declaration and use statements offer no real support.The patch located here:
https://github.com/ralphschindler/php-src/commit/02210d51851a96d723fbedcfc64cde9f9ae2b22a
... implements the ability for a developer to leverage the file's namespace
declaration and use statements to be able to produce a scalar (string) of
the class name that can be then used, for example, as an argument to a
function elsewhere.This overloads the "class" keyword, and by virtue of the existing usage of
"class" this feature is completely backwards compatible. All existing tests
pass. For example, the above PHPUnit snipped would become:use A\Namespaced\ClassName;
$mock = $this->getMock(ClassName::class);Another example with reflection:
use SomeOther\FullyNamespaced\ClassElsewhere as CE;
$r = new ReflectionClass(CE::class);More examples from the test file:
namespace Foo\Bar {
class Baz {}
var_dump(Moo::CLASS); // "Foo\Bar\Moo"
}namespace {
use Bee\Bop as Moo,
Foo\Bar\Baz;var_dump(Baz::class); // "Foo\Bar\Baz"
var_dump(Boo::class); // "Boo"
var_dump(Moo::CLASS); // "Bee\Bop"
var_dump(\Moo::Class); // "Moo"$class = Baz::class; // assign class as scalar to var
$x = new $class;
var_dump($x); object(Foo\Bar\Baz)#1 (0) {}
}What do you guys think?
Hey Ralph!
I like the proposal :)
A quick note on the patch: As the class name is compile-time
resolvable it should in my eyes also be available as a
static_scalar
, so that it can be used in initialization lists:
public function doFoo($withClass = ABC::class) {
new $withClass; // or whatever
}
To be available as both a static_scalar
and a general scalar
one
should put the rule in the common_scalar
section.
What do you think?
Nikita
@Nicolas: wouldn't CLASS introduce a bit of confusion with the existing
constant?
Marco Pivetta
On Sat, Apr 14, 2012 at 9:50 PM, Ralph Schindler
ralph@ralphschindler.com wrote:Hi all,
There are many different use cases were in code we expect classes names
as
arguments to functions as fully qualified names. We do this in ZF a lot
with our Service Location and DI components, but also with our code
reflection API, etc. A more interesting use case I would like to call
out
is with PHPUnit, for example in a test, you might find this:$mock = $this->getMock('A\Namespaced\ClassName');
This becomes cumbersome when you are dealing with lots of strings about
lots
of class names. This is also an area where, currently, namespace
declaration and use statements offer no real support.The patch located here:
https://github.com/ralphschindler/php-src/commit/02210d51851a96d723fbedcfc64cde9f9ae2b22a
... implements the ability for a developer to leverage the file's
namespace
declaration and use statements to be able to produce a scalar (string) of
the class name that can be then used, for example, as an argument to a
function elsewhere.This overloads the "class" keyword, and by virtue of the existing usage
of
"class" this feature is completely backwards compatible. All existing
tests
pass. For example, the above PHPUnit snipped would become:use A\Namespaced\ClassName;
$mock = $this->getMock(ClassName::class);Another example with reflection:
use SomeOther\FullyNamespaced\ClassElsewhere as CE;
$r = new ReflectionClass(CE::class);More examples from the test file:
namespace Foo\Bar {
class Baz {}
var_dump(Moo::CLASS); // "Foo\Bar\Moo"
}namespace {
use Bee\Bop as Moo,
Foo\Bar\Baz;var_dump(Baz::class); // "Foo\Bar\Baz"
var_dump(Boo::class); // "Boo"
var_dump(Moo::CLASS); // "Bee\Bop"
var_dump(\Moo::Class); // "Moo"$class = Baz::class; // assign class as scalar to var
$x = new $class;
var_dump($x); object(Foo\Bar\Baz)#1 (0) {}
}What do you guys think?
Hey Ralph!I like the proposal :)
A quick note on the patch: As the class name is compile-time
resolvable it should in my eyes also be available as a
static_scalar
, so that it can be used in initialization lists:public function doFoo($withClass = ABC::class) {
new $withClass; // or whatever
}To be available as both a
static_scalar
and a generalscalar
one
should put the rule in thecommon_scalar
section.What do you think?
Nikita
Hi Nikita,
A quick note on the patch: As the class name is compile-time
resolvable it should in my eyes also be available as a
static_scalar
, so that it can be used in initialization lists:public function doFoo($withClass = ABC::class) { new $withClass; // or whatever }
To be available as both a
static_scalar
and a generalscalar
one
should put the rule in thecommon_scalar
section.What do you think?
I've added this to the patch and Zend/tests:
https://github.com/ralphschindler/php-src/compare/master...feature/class-name-scalar
I've also added an RFC page, any thoughts on improving the RFC?
-ralph
Hi Nikita,
A quick note on the patch: As the class name is compile-time
resolvable it should in my eyes also be available as a
static_scalar
, so that it can be used in initialization lists:public function doFoo($withClass = ABC::class) { new $withClass; // or whatever }
To be available as both a
static_scalar
and a generalscalar
one
should put the rule in thecommon_scalar
section.What do you think?
I've added this to the patch and Zend/tests:
https://github.com/ralphschindler/php-src/compare/master...feature/class-name-scalar
I've also added an RFC page, any thoughts on improving the RFC?
In the examples, you mix case:
Boo::class
Moo::Class
\Moo::CLASS
Make sure you note that this is intentional, and that the keyword is
case insensitive -- i.e., changing the case does not alter the use cases
presented.
Also, I'd note why you're selecting "class" as the keyword (basically,
because it is a keyword, and thus will never conflict with any class
constants or method names).
Otherwise, very straight-forward.
--
Matthew Weier O'Phinney
Project Lead | matthew@zend.com
Zend Framework | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc
Hi Ralph,
I've also added an RFC page, any thoughts on improving the RFC?
- https://wiki.php.net/rfc/class_name_scalars
Are you sure that the example section is correct? Because your first
var_dump is Moo::CLASS but the symbol Moo does not exist yet, only the
class Foo\Bar\Baz was declared at this point.
Btw, interesting patch and nice implementation. I approved.
Best regards.
--
Ivan Enderlin
Developer of Hoa
http://hoa.42/ or http://hoa-project.net/
PhD. student at DISC/Femto-ST (Vesontio) and INRIA (Cassis)
http://lifc.univ-fcomte.fr/ and http://www.inria.fr/
Member of HTML and WebApps Working Group of W3C
http://w3.org/
var_dump is Moo::CLASS but the symbol Moo does not exist yet, only the
class Foo\Bar\Baz was declared at this point.
It could exist. It could be a class name handled by an autoloader
somewhere else.
This method of class name resolving operates in the spirit of how our
namespace implementation works. Namespaces don't actually "import"
things into the files symbol table, it makes aliases for them, as such
the namespace implementation alone never triggers an autoload simply b/c
you were talking about a class somewhere.
The ::class resolver essentially does the same thing, for any given name
you are talking about, it will resolve that name against the current
namespace resolution rules.
Btw, interesting patch and nice implementation. I approved.
Best regards.
Thanks!
-ralph
On Tue, Apr 17, 2012 at 4:54 PM, Ralph Schindler
ralph@ralphschindler.com wrote:
I've also added an RFC page, any thoughts on improving the RFC?
* https://wiki.php.net/rfc/class_name_scalars
-ralph
What's the state of this RFC?
Nikita
I need to address Stas's concerns.
Is there a particular time frame I should be aware of?
-ralph
On Tue, Apr 17, 2012 at 4:54 PM, Ralph Schindler
ralph@ralphschindler.com wrote:I've also added an RFC page, any thoughts on improving the RFC?
-ralph
What's the state of this RFC?
Nikita
Hi!
I need to address Stas's concerns.
Is there a particular time frame I should be aware of?
For 5.5, no rush so far but I imagine we'd want to start figuring out
5.5 feature set in a couple of months, so if you want it there you may
want to have it ready by then.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
I'm a bit confused by the "class" keyword in the syntax ClassName::class.
We already have the magic constant CLASS which does exactly the same
class name resolving, if you refer it within the class.
So why to introduce a new keyword instead of using CLASS, like
ClassName::CLASS?
Eugene
"Ralph Schindler" ralph@ralphschindler.com wrote in message
news:4F89D4F1.8070009@ralphschindler.com...
Hi all,
There are many different use cases were in code we expect classes names as
arguments to functions as fully qualified names. We do this in ZF a lot
with our Service Location and DI components, but also with our code
reflection API, etc. A more interesting use case I would like to call out
is with PHPUnit, for example in a test, you might find this:$mock = $this->getMock('A\Namespaced\ClassName');
This becomes cumbersome when you are dealing with lots of strings about
lots of class names. This is also an area where, currently, namespace
declaration and use statements offer no real support.The patch located here:
https://github.com/ralphschindler/php-src/commit/02210d51851a96d723fbedcfc64cde9f9ae2b22a
... implements the ability for a developer to leverage the file's
namespace declaration and use statements to be able to produce a scalar
(string) of the class name that can be then used, for example, as an
argument to a function elsewhere.This overloads the "class" keyword, and by virtue of the existing usage of
"class" this feature is completely backwards compatible. All existing
tests pass. For example, the above PHPUnit snipped would become:use A\Namespaced\ClassName;
$mock = $this->getMock(ClassName::class);Another example with reflection:
use SomeOther\FullyNamespaced\ClassElsewhere as CE;
$r = new ReflectionClass(CE::class);More examples from the test file:
namespace Foo\Bar {
class Baz {}
var_dump(Moo::CLASS); // "Foo\Bar\Moo"
}namespace {
use Bee\Bop as Moo,
Foo\Bar\Baz;var_dump(Baz::class); // "Foo\Bar\Baz" var_dump(Boo::class); // "Boo" var_dump(Moo::CLASS); // "Bee\Bop" var_dump(\Moo::Class); // "Moo" $class = Baz::class; // assign class as scalar to var $x = new $class; var_dump($x); object(Foo\Bar\Baz)#1 (0) {}
}
What do you guys think?
-ralph
I'm a bit confused by the "class" keyword in the syntax ClassName::class.
We already have the magic constant CLASS which does exactly the same
class name resolving, if you refer it within the class.So why to introduce a new keyword instead of using CLASS, like
ClassName::CLASS?
"class" is already a keyword, making it a simpler, easier to remember, and
easier to type choice.
"Ralph Schindler" ralph@ralphschindler.com wrote in message
news:4F89D4F1.8070009@ralphschindler.com...Hi all,
There are many different use cases were in code we expect classes names as
arguments to functions as fully qualified names. We do this in ZF a lot
with our Service Location and DI components, but also with our code
reflection API, etc. A more interesting use case I would like to call out
is with PHPUnit, for example in a test, you might find this:$mock = $this->getMock('A\Namespaced\ClassName');
This becomes cumbersome when you are dealing with lots of strings about
lots of class names. This is also an area where, currently, namespace
declaration and use statements offer no real support.The patch located here:
https://github.com/ralphschindler/php-src/commit/02210d51851a96d723fbedcfc64cde9f9ae2b22a
... implements the ability for a developer to leverage the file's
namespace declaration and use statements to be able to produce a scalar
(string) of the class name that can be then used, for example, as an
argument to a function elsewhere.This overloads the "class" keyword, and by virtue of the existing usage of
"class" this feature is completely backwards compatible. All existing
tests pass. For example, the above PHPUnit snipped would become:use A\Namespaced\ClassName;
$mock = $this->getMock(ClassName::class);Another example with reflection:
use SomeOther\FullyNamespaced\ClassElsewhere as CE;
$r = new ReflectionClass(CE::class);More examples from the test file:
namespace Foo\Bar {
class Baz {}
var_dump(Moo::CLASS); // "Foo\Bar\Moo"
}namespace {
use Bee\Bop as Moo,
Foo\Bar\Baz;var_dump(Baz::class); // "Foo\Bar\Baz" var_dump(Boo::class); // "Boo" var_dump(Moo::CLASS); // "Bee\Bop" var_dump(\Moo::Class); // "Moo" $class = Baz::class; // assign class as scalar to var $x = new $class; var_dump($x); object(Foo\Bar\Baz)#1 (0) {}
}
What do you guys think?
-ralph
--
Matthew Weier O'Phinney
Project Lead | matthew@zend.com
Zend Framework | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc