rfc:class_name_scalars

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
rfc:class_name_scalars [2012/09/08 22:40]
ralphschindler Updated as per considerations, and mailing list case question
rfc:class_name_scalars [2013/01/18 18:51]
ralphschindler Added updates and notes as of current implemntation's details
Line 31: Line 31:
 </code> </code>
  
 +==== Real World Usage Scenarios ====
 +
 +1. PHPUnit's Mocking
 +
 +<code php>
 +
 +use MyVendor\SomeComponent\TargetSubNs;
 +
 +// inside a test case
 +$this->getMock(TargetSubNs\Foo::class);
 +// as opposed to
 +$this->getMock('MyVendor\SomeComponent\TargetSubNs\Foo');
 +</code>
 +
 +2. Doctrine
 +
 +<code php>
 +
 +use MyVendor\SomeComponent\TargetEntityNs as Entity;
 +
 +// inside a test case
 +$entityManager->find(Entity\User::class, 5);
 +// as opposed to
 +$entityManager->find('MyVendor\SomeComponent\TargetEntityNs\User', 5);
 +
 +</code>
 +
 +3. Any Real (auto-wiring || auto-instantiating) Dependency Injection Container
 +
 +<code php>
 +
 +use MyVendor\SomeComponent\TargetNs as T;
 +
 +// inside a test case
 +$dic->newInstance(T\Foo::class);
 +// as opposed to
 +$dic->newInstance('MyVendor\SomeComponent\TargetEntityNs\Foo');
 +
 +</code>
 +
 +4. General PHP Usage:
 +
 +<code php>
 +
 +use MyVendor\SomeComponent\TargetNs as T;
 +
 +// reflection
 +$r = new ReflectionClass(T\Foo::class); // instead of new ReflectionClass('MyVendor\SomeComponent\TargetNs\Foo');
 +
 +// class_exists, also applies to any php function that takes a class name (is_subclass_of, get_class_methods, etc)
 +if (class_exists(T\Foo::class, true)) {} // instead of class_exists('MyVendor\SomeComponent\TargetNs\Foo')
 +
 +</code>
 ===== Choice of syntax ===== ===== Choice of syntax =====
  
Line 44: Line 97:
  
 <code php> <code php>
 +
 +--TEST--
 +class name as scalar from ::class keyword
 +--FILE--
 <?php <?php
  
 namespace Foo\Bar { namespace Foo\Bar {
-    class Baz {} +    class One { 
-    var_dump(Moo::class); // resolve in namespace +        // compile time constants 
-    class Box +        const A = self::class; 
-        public static function registerClassName($class = Baz::class) { +        const B = Two::class; 
-            var_dump($class);+    
 +    class Two extends One { 
 +        public static function run() { 
 +            var_dump(self::class); // self compile time lookup 
 +            var_dump(static::class); // runtime lookup 
 +            var_dump(parent::class); // runtime lookup 
 +            var_dump(Baz::class); // default compile time lookup 
 +        } 
 +    } 
 +    class Three extends Two { 
 +        // compile time static lookups 
 +        public static function checkCompileTime( 
 +            $one = self::class
 +            $two = Baz::class
 +            $three = One::A, 
 +            $four = self::B 
 +        ) { 
 +            var_dump($one, $two, $three, $four);
         }         }
     }     }
-    Box::registerClassName();+    echo "In NS\n"; 
 +    var_dump(Moo::CLASS); // resolve in namespace
 } }
  
 namespace { namespace {
     use Bee\Bop as Moo,     use Bee\Bop as Moo,
-        Foo\Bar\Baz+        Foo\Bar\One; 
-    var_dump(Baz::class); // resolve from use+    echo "Top\n"
 +    var_dump(One::class); // resolve from use
     var_dump(Boo::class); // resolve in global namespace     var_dump(Boo::class); // resolve in global namespace
-    var_dump(Moo::class); // resolve from use as +    var_dump(Moo::CLASS); // resolve from use as 
-    var_dump(\Moo::class); // resolve fully qualified +    var_dump(\Moo::Class); // resolve fully qualified 
-    $class = Baz::class; // assign class as scalar to var+    $class = One::class; // assign class as scalar to var
     $x = new $class; // create new class from original scalar assignment     $x = new $class; // create new class from original scalar assignment
-    var_dump($x);    +    var_dump($x); 
 +    Foo\Bar\Two::run(); // resolve runtime lookups 
 +    echo "Parent\n"; 
 +    Foo\Bar\Three::run(); // resolve runtime lookups with inheritance 
 +    echo "Compile Check\n"; 
 +    Foo\Bar\Three::checkCompileTime();
 } }
- 
  
 ?> ?>
---EXPECTF--    +--EXPECTF-- 
 +In NS
 string(11) "Foo\Bar\Moo" string(11) "Foo\Bar\Moo"
-string(11) "Foo\Bar\Baz" +Top 
-string(11) "Foo\Bar\Baz"+string(11) "Foo\Bar\One"
 string(3) "Boo" string(3) "Boo"
 string(7) "Bee\Bop" string(7) "Bee\Bop"
 string(3) "Moo" string(3) "Moo"
-object(Foo\Bar\Baz)#1 (0) {+object(Foo\Bar\One)#1 (0) {
 } }
 +string(11) "Foo\Bar\Two"
 +string(11) "Foo\Bar\Two"
 +string(11) "Foo\Bar\One"
 +string(11) "Foo\Bar\Baz"
 +Parent
 +string(11) "Foo\Bar\Two"
 +string(13) "Foo\Bar\Three"
 +string(11) "Foo\Bar\One"
 +string(11) "Foo\Bar\Baz"
 +Compile Check
 +string(13) "Foo\Bar\Three"
 +string(11) "Foo\Bar\Baz"
 +string(11) "Foo\Bar\One"
 +string(11) "Foo\Bar\Two"
 </code> </code>
  
Line 88: Line 183:
 Do we: Do we:
  
-  * Throw a compile error? +  * <del>Throw a compile error?</del> 
-  * Resolve as best as possible, meaning error in non-class context, do a runtime lookup in a class context+  * <del>Resolve as best as possible, meaning error in non-class context, do a runtime lookup in a class context</del> 
 + 
 +**Note:** (as of 1/18/13)
  
-Note: (as of 9/8/12) 
 In the current patch, the following resolutions take place: In the current patch, the following resolutions take place:
-  * self::class resolves the same as __CLASS__ would+  * self::class resolves the same as %%__CLASS__%% would
   * static::class resolves the same as get_called_class() would   * static::class resolves the same as get_called_class() would
   * parent::class resolves the same as get_parent_class() would, (in fact, would return false if not inherited.)   * parent::class resolves the same as get_parent_class() would, (in fact, would return false if not inherited.)
 +  * static::class & parent::class when used in compile-time only places (like method signatures), will throw an exception
  
  
Line 101: Line 198:
  
 * Pull Request located here: https://github.com/php/php-src/pull/187/files * Pull Request located here: https://github.com/php/php-src/pull/187/files
 +
 +===== Vote =====
  
  
 +<doodle title="Should the ::class feature be merged to master?" auth="ralphschindler" voteType="single" closed="true">
 +   * Yes
 +   * No
 +</doodle>
  
 +Note: This Vote has been closed as the RFC will be moved back to discussion at the time being while the RFC and associated patch become more mature.
 ===== Changelog ===== ===== Changelog =====
  
   * 2012-04-17 Initially created by Ralph Schindler   * 2012-04-17 Initially created by Ralph Schindler
   * 2012-09-08 Updated RFC and added link to Pull Request (which addresses considerations and on-list questions)   * 2012-09-08 Updated RFC and added link to Pull Request (which addresses considerations and on-list questions)
 +  * 2013-01-18 Updated RFC to reflect design decisions, updated the test/example
  
rfc/class_name_scalars.txt · Last modified: 2017/09/22 13:28 (external edit)