On Tue, Jan 27, 2015 at 11:21 PM, Rowan Collins <rowan.coll...@gmail.com> wrote:
> Hi All, > > I would like to propose that the error given for an undefined constant > should be raised from E_NOTICE, probably to E_RECOVERABLE_ERROR, in PHP 7. > > I'm happy to expand this into a proper RFC, and work on patches for the > engine, tests, and spec, but want to see if initial reception to the idea > is favourable first. > > Current behaviour: any bare word which is not a defined constant is > treated as though it were a quoted string, with an E_NOTICE issued. > > Proposed behaviour: an E_RECOVERABLE_ERROR is issued; if the error is > caught, either the existing string behaviour could be retained, or the > value could be treated as NULL. (I'm open to other alternatives.) > > PROS > > 1. Consistency. > > An undefined class constant (e.g. Foo::BAR) gives a fatal error, but a > normal global constant gives only a notice. Class constants being "more > modern" made this seem reasonable, but with namespaces, it's even worse - a > qualified namespace constant (e.g. Foo\BAR) gives a fatal error, as does a > global constant in namespace notation (e.g. \BAR); but a namespace constant > referenced relative to the current namespace is a bare word, and gives only > a notice (e.g. namespace Foo; const BAR=42; echo BAAR;). > > Functions and classes also give fatal errors if used without declaring; > variables do not, but this is more useful, because they can meaningfully be > created as null, and there isn't a syntax to declare a local variable, only > to initialise it. > > 2. Inherent severity. > > It's probably relatively common to turn off E_NOTICE in error_reporting, > or to miss one notice among many others. But an undefined constant > magically turning into a string could cause relatively major problems. > > Firstly, a constant is likely to have some value which needs to be used or > matched somewhere else. A READ_ONLY flag mis-typed as REED_ONLY could be > interpreted as int(0) (i.e. intval('REED_ONLY')) and cause a catastrophic > error. > > Secondly, keywords are also bare words, and any expression can be a > statement. Thus the following is an infinite loop, no matter what > blahblah() returns: > while(true) { > if ( blahblah() ) { > brek; > } > } > > Obviously, there are other mistakes which could cause such errors, but > this is one that the engine could easily pick up on and protect the user. > > > CONS > > Like most changes, the downside is a break in compatibility. > > As far as I can make out, the current behaviour is actually for > compatibility back as far as PHP 3 (correct me if I'm wrong, I didn't dig > far). > > I'm not aware of any notice officially deprecating barewords-as-strings, > but nor can I find many references to it in the manual at all. Its use for > array keys has been explicitly discouraged in the manual since some time in > 2001. [1] > > Outside code golf, I'd be very surprised if any code written or updated in > the last 10 years deliberately uses this "feature", and I think changing it > in PHP 7 is justifiable given the benefits to maintainers of even the > simplest non-OO, non-namespaced code. > > > What do people think? > I think this is too big a BC break. The usage of $array[key] = 0 instead of "key" is widespread. > > [1] http://web.archive.org/web/20010614144157/http://www.php. > net/manual/en/language.types.array.php#language.types.array.donts > > Regards, > > -- > Rowan Collins > [IMSoP] > > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > >