This RFC aims to remove some restrictions which are due to the fact that keywords are not included in T_STRING (especially for class const, method and class names).
This especially could be useful to preserve more BC compatibility whenever new keywords are introduced.
class HTTP { const CONTINUE = 100; // Works with patch // But currently this fails with a parse error, because continue is a keyword. const SWITCHING_PROTOCOLS = 101; // etc. ... }
class Cond { public static function and (...) { // using an "and" or "or" as name currently fails // some logic here return $andCondition; } public static function or (...) { // some logic here return $orCondition; } } Cond::and($cond1, $cond2);
// Ugly, current code class SomeClass { private $list = []; public function _list () { return $this->list; } public function __call ($func, $args) { if (method_exists($this, "_".$func)) { return call_user_func_array("_".$func, $args); // or some similar thing, if not underscores etc.... } // some error handling here } } // How we could write it with the patch class SomeClass { private $list = []; public function list () { return $this->list; } }
Concretely this patch enables:
An example what is possible with this patch:
namespace Class { class List { const default = 0; public $case = array(array(self::default)); public static function echo (List $instance) { var_dump($instance->case); } public function new (array $entry) { $this->case[] = $entry; return $this; } } } namespace { \Class\List::echo((new Class\List)->new(array(1))); }
Currently when using array or callable as typehint, the old behaviour is preferred over comparing if it's a class/interface named array or callable. I'm not sure if we should just allow both in this special case.
The transformation of alphabetic tokens to a T_STRING is done in lexer (post-processing output of lexer).
Initially it was done in parser, but that had a few disadvantages:
That is also why performance is affected, as it is some code which needs to be run on every token.
There is a slight decrease in compilation performance of up to 10% in worst case. So, actually, when used with opcache (execution only), any impact shouldn't be noticeable.
For that benchmark I used an 1.5 megabyte big file wrapped in an if (false) (so that nothing is executed): https://raw.github.com/nikic/PHP-Parser/master/lib/PHPParser/Parser.php
Compare actual run time:
time ./sapi/cli/php -r 'for($i=0;$i++<5000;)require "Parser.php";' real 0m33.132s user 0m32.816s sys 0m0.313s
To run time with patch applied:
time ./sapi/cli/php -r 'for($i=0;$i++<5000;)require "Parser.php";' real 0m36.720s user 0m36.400s sys 0m0.316s
This RFC should go into next PHP 5.x.
Deadline was Monday, 28th october 2013.