Req #47577 [Opn->Ver]: { should be an escapable special character when paired with a trailing $

From: Date: Sat, 16 Jan 2016 13:47:51 +0000
Subject: Req #47577 [Opn->Ver]: { should be an escapable special character when paired with a trailing $
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-198717@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=47577&edit=1 ID: 47577 Updated by: danack@php.net Reported by: bob at trivectus dot com Summary: { should be an escapable special character when paired with a trailing $ -Status: Open +Status: Verified Type: Feature/Change Request Package: Scripting Engine problem Operating System: * PHP Version: 5.2.9 Block user comment: N Private report: N New Comment: The TL:DR version: the programmer wants the code to output "/a{2,5}b/", but this cannot be achieved with the current syntax. $minCount = 2; $maxCount = 5; echo "/a\{$minCount,$maxCount}b/"; // output is /a\{2,5}b/ echo "/a{$minCount,$maxCount}b/"; //PHP Parse error: syntax error, unexpected ',', expecting '} Previous Comments: ------------------------------------------------------------------------ [2009-03-05 18:38:53] bob at trivectus dot com Description: ------------ Prior to 5.1.1, PHP always treated { as a special character that was escapable. From 5.1.1 on, it's never treated as a special, escapable character. Both behaviors are wrong in that both produce inconsistent results when the { character is used in strings. The correct behavior is to treat { as a special, escapable character only in the specific case that it's immediately followed by a $. The inconsistent behavior was discussed in bug 37263, but that bug did not directly address the core issue. Reproduce code: --------------- Dbeckham in bug 37263 is right: either { is a special character that should be escapable as can any other special character, or it's a normal character that doesn't affect string processing. Right now, it's an incomprehensible mix of both. Another example that hits the problem from a different direction is use of curly braces in PCRE expressions, where they're are used to tell the engine the minimum and maximum number of times the preceding pattern should be repeated to be a match. Assume we're trying to do a replace with this PCRE search pattern: /a{2,5}b/ Now, in our PHP context, assume the 2 and 5 are variables: $min = 2; $max = 5; The most obvious syntax for the preg_replace call is: $foo = preg_replace("/a{$minCount,$maxCount}b/", 'x', $foo); However, it won't work. Neither do any of these alternatives that a reasonable programmer might try: $foo = preg_replace("/a\{$minCount,$maxCount}b/", 'x', $foo); $foo = preg_replace("/a{\$minCount,$maxCount}b/", 'x', $foo); $foo = preg_replace("/a\{\$minCount,$maxCount}b/", 'x', $foo); To get this to work, one must use this: $foo = preg_replace("/a{{$minCount},$maxCount}b/", 'x', $foo); Yes, I know it's documented that { is not a special character, but a documented design bug is still very much a design bug. But the problem is, { *is* a special character when followed by a $. The need to document how to handle the situations where you don't want the { processed--and how, even now, those situations are only partly documented--illustrates that PHP's approach here is ill-thought. I think the root of this problem is that PHP treats { as special only when it's paired with a $. This means it's special in some cases and not special in others, which in turn means that always making it escapable (the pre-5.1.1 behavior) or always making it not escapable (the current behavior) are both inherently going to be wrong in some situations. The correct solution is to make { an escapable special character in exactly those situations when it is, in fact, special. Namely, when it's immediately followed by a $. When the preceding { is escaped, PHP should attempt to interpret the $ expression just as it would without the {. When the { is not followed by a $ and thus is not special, it should not be escapable. Thus: $world = 'foo'; "hello $world" => "hello foo" "hello {$world}" => "hello foo" "hello \{$world}" => "hello {foo}" "hello {\$world}" => "hello {$world}" "hello \{\$world}" => "hello \{$world}" The result is completely self-consistent and consistent with the rest of PHP's escaping behavior, which means there aren't exceptions to document and confuse the poor programmer just trying to write some code. ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=47577&edit=1

« previous php.bugs (#198717) next »