Hi all,
RFC: about class names as values
PHP uses class names as values, but only in a couple of places.
String constanst after the "new" or "instanceof" operator --correct me if
I'm missing others-- are treated as class names.
if( $obj instanceof MyClass ) {
// $obj is instanceof Bar/Foo/MyClass
}
but what happen if the class name is used on other places?
function newInstance($class) {
return new $class;
}
$obj = newInstance( MyClass ); // notice. undefined constant MyClass
so you have to end up by writting....
$obj = newInstance( '\Bar\Foo\MyClass' );
which lacks of any semantic, it's not a class name, it's just a string.
My idea is that PHP could include a constant on each class, a string with
the full qualified class name
echo MyClass::CLASS; // \Bar\Foo\MyClass
$obj = newInstance( MyClass::CLASS );
As the "CLASS" is currently a reserved word is guarantied that nobody is
using as it today.
What do you think about?
Martin Scotta
$obj = newInstance( MyClass ); // notice. undefined constant MyClass
This describes the major change with your idea.
What happens if a constant MyClass exists?
Another question is something like this:
<?php
function factory($class) {
return new $class();
}
factory( SomeClass );
?>
To proper support this we'd have to make classes first class elements.
For making this consistent it would make sense to make functions first
class elements. And best drop the $ in front of variables and create a
new language. Everything else becomes a mess.
johannes
2011/1/5 Johannes Schlüter johannes@php.net
$obj = newInstance( MyClass ); // notice. undefined constant MyClass
This describes the major change with your idea.
What happens if a constant MyClass exists?
Another question is something like this:
<?php
function factory($class) {
return new $class();
}factory( SomeClass );
?>To proper support this we'd have to make classes first class elements.
For making this consistent it would make sense to make functions first
class elements. And best drop the $ in front of variables and create a
new language. Everything else becomes a mess.johannes
--
I think he's actually proposing creating for each class the magic class
constant CLASS, so your example becomes:
<?php
function factory($class) {
return new $class();
}
factory( SomeClass::CLASS );
?>
This is actually doable without a magic class constant, but requires a
function or class constant to be declared in each class.
<?php
class SomeClass {
const CLASS = NAMESPACE . '' . CLASS;
static function getNameWithNSPath()
{
return NAMESPACE . '' . CLASS;
}
}
factory( SomeClass::getNameWithNSPath() );
?>
Perhaps this could be simplified with traits, if NAMESPACE and CLASS
work in traits that way. In fact, that's an interesting question, what is
NAMESPACE in a trait defined in one namespace, then used in a class in a
different namespace?
I think the point is that the factory function could exist without any
knowledge of the namespaces of the classes it would work on. Then, somewhere
else where the class has been aliased or is otherwise accessible without the
full namespace path, the developer wouldn't need to specify the full
namespace path to the factory, but could ask the class itself what it's full
namespace path was. I don't know that I agree with the idea, but I don't
think it requires making classes first class elements.
John
Yes, my intention was to only add a magic constant with the class, similar
to this
namespace Bar {
class Foo {
const KLASS = CLASS;
}
}
namespace Buzz {
use \Bar\Foo as BazFoo;
class Bar extends BazFoo {
const KLASS = CLASS;
}
$bar = new Bar;
$baz = new BazFoo;
var_dump( get_class($baz), BazFoo::KLASS);
var_dump( get_class($bar), Bar::KLASS );
}
This is 100% valid PHP 5.3.3 code, but that includes a lot of effort from
the developer. Someone miss to include the KLASS constant on a class and the
result is undefined.
If that PHP could add a magic constant --named CLASS or whatever you like--
to each class it will reduce the amount of class names hardcoded onto
strings, probably to zero.
The only issue that I found today is related to interfaces. I'm not sure if
they should include this sort of magic constant, but I would rather include
them just for consistency but, as I previously said, I'm not sure about this
one.
Martin Scotta
2011/1/5 John LeSueur john.lesueur@gmail.com
2011/1/5 Johannes Schlüter johannes@php.net
$obj = newInstance( MyClass ); // notice. undefined constant MyClass
This describes the major change with your idea.
What happens if a constant MyClass exists?
Another question is something like this:
<?php
function factory($class) {
return new $class();
}factory( SomeClass );
?>To proper support this we'd have to make classes first class elements.
For making this consistent it would make sense to make functions first
class elements. And best drop the $ in front of variables and create a
new language. Everything else becomes a mess.johannes
--
I think he's actually proposing creating for each class the magic class
constant CLASS, so your example becomes:<?php
function factory($class) {
return new $class();
}factory( SomeClass::CLASS );
?>
This is actually doable without a magic class constant, but requires a
function or class constant to be declared in each class.<?php
class SomeClass {
const CLASS = NAMESPACE . '' . CLASS;
static function getNameWithNSPath()
{
return NAMESPACE . '' . CLASS;
}
}factory( SomeClass::getNameWithNSPath() );
?>Perhaps this could be simplified with traits, if NAMESPACE and
CLASS work in traits that way. In fact, that's an interesting question,
what is NAMESPACE in a trait defined in one namespace, then used in a
class in a different namespace?I think the point is that the factory function could exist without any
knowledge of the namespaces of the classes it would work on. Then, somewhere
else where the class has been aliased or is otherwise accessible without the
full namespace path, the developer wouldn't need to specify the full
namespace path to the factory, but could ask the class itself what it's full
namespace path was. I don't know that I agree with the idea, but I don't
think it requires making classes first class elements.John
Hi,
To proper support this we'd have to make classes first class elements.
For making this consistent it would make sense to make functions first
class elements. And best drop the $ in front of variables and create a
new language. Everything else becomes a mess.
Closures are first-class citizens and it seems natural that they are so.
Perhaps we should rethink what consistency means for PHP. I don't see any
good reason why first-class objects could be evil, except that the $ could
indeed be a problem.
Regards,
Adrian
2011/1/6 Johannes Schlüter johannes@php.net
$obj = newInstance( MyClass ); // notice. undefined constant MyClass
This describes the major change with your idea.
What happens if a constant MyClass exists?
Another question is something like this:
<?php
function factory($class) {
return new $class();
}factory( SomeClass );
?>To proper support this we'd have to make classes first class elements.
For making this consistent it would make sense to make functions first
class elements. And best drop the $ in front of variables and create a
new language. Everything else becomes a mess.johannes