Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:81264 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 46018 invoked from network); 27 Jan 2015 22:27:23 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 27 Jan 2015 22:27:23 -0000 Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 74.125.82.169 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 74.125.82.169 mail-we0-f169.google.com Received: from [74.125.82.169] ([74.125.82.169:62767] helo=mail-we0-f169.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 02/00-45774-9C018C45 for ; Tue, 27 Jan 2015 17:27:21 -0500 Received: by mail-we0-f169.google.com with SMTP id u56so17562627wes.0 for ; Tue, 27 Jan 2015 14:27:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject :content-type:content-transfer-encoding; bh=5g8bzd+Wz/9Qs+Md+u5Rer6y6vC1H8nH7aXwrhppfd4=; b=YzpAOOf+Mr7lKyKdhpFJLLf2ExQAYJCRjkO0qrIzdlnoTOaJo9qNqz+iWIL/96MyJn kCqNPhE6qaW57W935d2GFAKo6OIZon33PWLmV0TFKZ0l98pJ++rbMQdAvHt/ttG6Y12f +nimGidOIjLPVaqgiwNnY0r1IJnHs99xrU6DIhYD+wZGTgCwSufJf/IuA2gkQisjaHpy oNRfA0O26gfdZTY9yrn/Ag2dH5kQ/fI/eGafhurHzzw4T7hjsbzTRQIkGCFCUw+Zg1UP XwpYVMZnul/HDfUHajJDBIsLMeoWf8QPNH7/CF7ObLePebf8KQpbngcJcMAyVO+WnxL6 kLjQ== X-Received: by 10.180.20.226 with SMTP id q2mr698305wie.28.1422397280840; Tue, 27 Jan 2015 14:21:20 -0800 (PST) Received: from [192.168.0.2] (cpc68956-brig15-2-0-cust215.3-3.cable.virginm.net. [82.6.24.216]) by mx.google.com with ESMTPSA id bj3sm296645wib.3.2015.01.27.14.21.19 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 27 Jan 2015 14:21:19 -0800 (PST) Message-ID: <54C80F4F.7020905@gmail.com> Date: Tue, 27 Jan 2015 22:21:03 +0000 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: PHP Internals Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Subject: Proposal: Raise severity of undefined constants From: rowan.collins@gmail.com (Rowan Collins) 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? [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]