php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #81635 No example of complex interpolation syntax with filenames
Submitted: 2021-11-18 11:06 UTC Modified: 2021-11-18 14:29 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: shealavington at gmail dot com Assigned: cmb (profile)
Status: Closed Package: Scripting Engine problem
PHP Version: 8.0.12 OS: Windows 10
Private report: No CVE-ID: None
 [2021-11-18 11:06 UTC] shealavington at gmail dot com
Description:
------------
When curly braces are escaped within a string "", the back-slash isn't removed \{. For example `"hello\{$foo}"` is outputting `hello\{bar}` instead of `hello{bar}`

Test script:
---------------
<?php

$foo = "bar";
$test_script = "hello\{$foo}"

//- Explanation output below.

echo "If `\` is the escape character, why are the escaped characters and the escape character both shown?<br>";
echo "Res: <b>c:\path\hello\{$foo}</b><br>";
echo "Expected: <b>c:\path\hello"."{"."$foo}</b><br>";

echo "<br>Notice how in this example, I haven't used a `\` but the `{}` characters are gone when not escaped?<br>";
echo "Res: <b>c:\path\hello{$foo}</b><br>";

echo "<br>If I use `\ n`, it replaces the `\`, I don't see `\ n` like I do in the first example above.<br>";
echo "Res: <b>c:\path\hello\note\{$foo}</b><br>";

Expected result:
----------------
`hello{bar}`

Actual result:
--------------
`hello\{bar}` 

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-11-18 11:21 UTC] cmb@php.net
-Status: Open +Status: Not a bug -Package: *General Issues +Package: Scripting Engine problem -Assigned To: +Assigned To: cmb
 [2021-11-18 11:21 UTC] cmb@php.net
The docs do not list \$ as escape sequence[1].  They are actually
very explicit about that[2]:

| Since { can not be escaped, […]

What you're looking for is <https://3v4l.org/hndfP>.

[1] <https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.double>
[2] <https://www.php.net/manual/en/language.types.string.php#language.types.string.parsing.complex>
 [2021-11-18 11:26 UTC] shealavington at gmail dot com
I now see that `\{` is not an escape sequence. However, that doesn't explain why the following

```
$foo = "bar";
var_dump("hello\{$foo}");
```

outputs `"hello\{bar}"` instead of `"hello\bar"`... The curly braces should act as a variable wrap and should therefore be removed? 

Please do correct me if I'm mis-understanding here.
 [2021-11-18 11:31 UTC] shealavington at gmail dot com
Notice how with this example I actually get one output with curlys and one without, which would suggest to me that there is a bug in the template parsing.

```
$foo = "bar";
var_dump("hello\{$foo}");
var_dump("hello\x{$foo}x");
```
 [2021-11-18 11:40 UTC] cmb@php.net
-Status: Not a bug +Status: Open
 [2021-11-18 11:40 UTC] cmb@php.net
Yeah, this is actually unclear.

    "hello\{$foo}"

This looks like complex string interpolation syntax, but is
apparently parsed as simple string interpolation syntax, so $foo
is being replaced with its value.  So, I assume, that the
backslash acts as escape for the open *and* the closing curly
braces.
 [2021-11-18 11:56 UTC] shealavington at gmail dot com
Indeed unclear, and most confusing.

I'm working with a filesystem path within a larger string. 

I need to insert my variable after a backslash. 

For simplicity, we're using curly braces around all of our variables used within the string, and this situation doesn't allow us to do so.

```
$foo = 'bar';
$newFoo = "(FILENAME='C:\folder\{$var}.txt')"
```
outputs a string with a now invalid file path due to the parsing inconsistency.
```
(FILENAME='C:\folder\{bar}.txt')
```
As you mentioned, `\{` should not be escaping, but does.

Hopefully this issue can be looked into being fixed for later versions.
 [2021-11-18 13:37 UTC] cmb@php.net
-Summary: When curly braces are escaped, the back-slash isn't removed \{ +Summary: \{ is a valid escape sequence in double-quoted strings
 [2021-11-18 13:37 UTC] cmb@php.net
Thanks for the further clarification!

> $newFoo = "(FILENAME='C:\folder\{$var}.txt')"

You really should escape the backslashes in the first place;
then you get the desired output: <https://3v4l.org/EKFq2>.

> As you mentioned, `\{` should not be escaping, but does.

Indeed: <https://3v4l.org/lLZqF>.  That needs to be fixed in the
docs.
 [2021-11-18 13:44 UTC] cmb@php.net
-Summary: \{ is a valid escape sequence in double-quoted strings +Summary: \{ has special meaning in double-quoted strings
 [2021-11-18 13:55 UTC] cmb@php.net
-Summary: \{ has special meaning in double-quoted strings +Summary: No example of complex interpolation syntax with filenames
 [2021-11-18 13:55 UTC] cmb@php.net
Nah, there is nothing special about \{[1]:

| As in single quoted strings, escaping any other character will
| result in the backslash being printed too.

Still, it makes sense to add an example, since backslashes in
filenames and the given use-case are common on Windows. 

[1] <https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.double>
 [2021-11-18 14:18 UTC] git@php.net
Automatic comment on behalf of cmb69
Revision: https://github.com/php/doc-en/commit/59244d9ae93cc5059a07c7eadf36b02a1704512c
Log: Fix #81635: No example of complex interpolation syntax with filenames
 [2021-11-18 14:18 UTC] git@php.net
-Status: Assigned +Status: Closed
 [2021-11-18 14:18 UTC] shealavington at gmail dot com
Regarding the comment from the docs, it states specifically in single-quoted strings. I am doing this in a double-quoted string. I'm not sure if that poses an issue or just a documentation change.

| As in single-quoted strings, escaping any other character will result in the backslash being printed too.

In reference to escaping file paths, I completely agree they should be, however, due to legacy systems in place, I'm trying to not modify too much of the original code.
 [2021-11-18 14:29 UTC] cmb@php.net
> As in single-quoted strings, […]

That means "like in single-quoted strings". :)

You can often get away without escapting literal backslashes,
but you should not rely on that, especially in double-quoted
strings, since new escape sequences might be introduced, breaking
your code; e.g. \e has been introduced with 5.4.4.

> […] however, due to legacy systems in place, I'm trying to not
> modify too much of the original code.

Understandable, but we can't change long-standing and mostly
well-documented behavior just because of that. :)
 [2021-11-18 14:49 UTC] shealavington at gmail dot com
> Understandable, but we can't change long-standing and mostly well-documented behavior just because of that. :)

I completely agree, I appreciate your comments! Ah, Perhaps a misunderstanding, I consider `'` a single-quoted string and `"` a double-quoted string haha. There's too much technical jargon to consider when you're deep in an issue.
 
PHP Copyright © 2001-2023 The PHP Group
All rights reserved.
Last updated: Sat Feb 04 12:03:44 2023 UTC