rfc:class_name_scalars

Differences

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

Link to this comparison view

Next revision
Previous revision
Next revisionBoth sides next revision
rfc:class_name_scalars [2012/04/17 14:30] – created ralphschindlerrfc:class_name_scalars [2012/09/14 15:16] – [Request for Comments: Class Name Resolution As Scalar Via class Keyword] ralphschindler
Line 1: Line 1:
-====== Request for Comments: How to write RFCs ======+====== Request for Comments: Class Name Resolution As Scalar Via "class" Keyword ======
   * Version: 1.0   * Version: 1.0
   * Date: 2012-04-17   * Date: 2012-04-17
Line 8: Line 8:
 ===== Introduction ===== ===== Introduction =====
  
-Reuse the "class" keyword in order to provide class name resolution according to current namespace and use rules.+This RFC proposes to add a new ''ClassName::class'' syntax, which provides the fully qualified class name as a string.
  
-===== Proposal =====+===== Use case ===== 
 + 
 +Class names in strings have to be fully qualified in PHP. It is not possible to utilize aliases registered through ''use'' statements: 
 + 
 +<code php> 
 +use A\Namespaced\ClassName; 
 + 
 +// this will try to create a mock of the global class ClassName, not 
 +// of the aliased class A\Namespaced\ClassName 
 +$mock = $this->getMock('ClassName'); 
 +</code> 
 + 
 +''ClassName::class'' allows the programmer to easily obtain the fully qualified class name from an aliased name: 
 + 
 +<code php> 
 +use A\Namespaced\ClassName; 
 + 
 +// ClassName::class resolves to 'A\Namespaced\ClassName' 
 +$mock = $this->getMock(ClassName::class); 
 +</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 ===== 
 + 
 +The ''ClassName::class'' syntax was chosen because it can not clash with existing constants (as ''class'' is a keyword). The feature addition thus is fully backwards compatible. 
 + 
 +Furthermore the syntax resembles the semantically equivalent Java syntax ''ClassName.class''
 + 
 +Note: since this feature reuses T_CLASS/class keyword, it is case-insensitive.  Therefore, Foo::class is semantically equivalent to Foo::Class, Foo::CLASS and the like. 
 + 
 +===== More examples =====
  
 From the test for the feature: From the test for the feature:
Line 19: Line 101:
 namespace Foo\Bar { namespace Foo\Bar {
     class Baz {}     class Baz {}
-    var_dump(Moo::CLASS); // resolve in namespace+    var_dump(Moo::class); // resolve in namespace
     class Box {     class Box {
         public static function registerClassName($class = Baz::class) {         public static function registerClassName($class = Baz::class) {
Line 33: Line 115:
     var_dump(Baz::class); // resolve from use     var_dump(Baz::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 = Baz::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
Line 52: Line 134:
 } }
 </code> </code>
 +
 +===== Considerations =====
 +
 +One situation in need of a solution is what to do with ''self::class'', ''static::class'', and ''parent::class''
 +
 +Do we:
 +
 +  * <del>Throw a compile error?</del>
 +  * <del>Resolve as best as possible, meaning error in non-class context, do a runtime lookup in a class context</del>
 +
 +**Note:** (as of 9/8/12)
 +
 +In the current patch, the following resolutions take place:
 +  * self::class resolves the same as %%__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.)
 +
  
 ===== Patch ===== ===== Patch =====
  
-Patch located here: https://github.com/ralphschindler/php-src/compare/master...feature/class-name-scalar+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)
  
rfc/class_name_scalars.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1