Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Syntax error with array access in string interpolation #62

Open
mpesari opened this issue Jun 23, 2020 · 11 comments · May be fixed by #87
Open

Syntax error with array access in string interpolation #62

mpesari opened this issue Jun 23, 2020 · 11 comments · May be fixed by #87
Labels

Comments

@mpesari
Copy link

mpesari commented Jun 23, 2020

I have only used this library through another library, but here's a reproducible code:

$ composer require opis/closure
<?php

require_once __DIR__ . '/vendor/autoload.php';

use Opis\Closure\SerializableClosure;

$object = new SerializableClosure(function (): string {
    $a = new \ArrayObject(['foo' => 'bar']);

    return "$a[foo]";
});

$function = unserialize(serialize($object));

var_dump($function());

Result (version 3.5.5):

PHP Parse error:  syntax error, unexpected '' (T_ENCAPSED_AND_WHITESPACE), expecting '-' or identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in closure://function (): string {
    $a = new \ArrayObject(['foo' => 'bar']);

    return "$a[\foo]";
} on line 5

Result (commit 82cc21f):

string(3) "bar"

I think the problematic commit is c17ece0

Of course a workaround is to "fix" all interpolations like this with

return "{$a['foo']}";
@GrahamCampbell
Copy link
Contributor

You actually need to always put those single quotes in. The other code you have will generate a warning saying constant 'foo' undefined, treated as string, in PHP 5 and 7, and in PHP 8 will be a hard error.

@GrahamCampbell
Copy link
Contributor

So, this is actually not a bug, and it is doing the correct thing, to escape the constant to the global namespace with a slash.

@mpesari
Copy link
Author

mpesari commented Jun 23, 2020

AFAIK string interpolation has different rules, e.g. theres two are different:

$a = ['foo' => 'bar'];

print $a[foo]; // references a  nonexistant constant, emits a warning
print "$a[foo]"; // "knows" the context, this does not emit a warning

See https://www.php.net/manual/en/language.types.string.php Example 10 which uses this syntax.

I tried it with a PHP 8 Docker image too:

$ docker run --rm -it keinos/php8-jit
Interactive shell

php > print phpversion();
8.0.0-dev
php > $a = ['foo' => 'bar'];
php > print "$a[foo]";
bar
php > print $a[foo];

Warning: Uncaught Error: Undefined constant 'foo' in php shell code:1
Stack trace:
#0 {main}
  thrown in php shell code on line 1

@GrahamCampbell
Copy link
Contributor

Ah, yes. You are right! Hmmm. There is a bug here then. 👍

@n00dl3
Copy link

n00dl3 commented Apr 9, 2021

Hello there,
I have experienced troubles with string interpolations too, but that does not only occur with arrays. I created a repo with some tests :

https://github.com/n00dl3/opis-closure-tests

I also tried with @abdrzakoxa PR (branch abdrzakoxa-pr on the test repo), but it only fixes simple array syntax.

Maybe I should open a new issue ?

@sorinsarca
Copy link
Member

Yes, please open a new issue.
Meanwhile I'll check to see where the problem is.

It would have been very helpful to put those tests directly inside opis/closure :)

@sorinsarca
Copy link
Member

Ok, I've found the problem, a fix is coming in the next minutes.

@n00dl3
Copy link

n00dl3 commented Apr 9, 2021

It would have been very helpful to put those tests directly inside opis/closure :)

Yeah, sorry, I started with a single test case and it grew up very quickly...

@sorinsarca
Copy link
Member

String interpolation error was solved in 85fec0b
A new version will be released soon.

This issue (with array access) is not solved yet.

@abdrzakoxa
Copy link
Contributor

Hello @sorinsarca
How about my PR, it solves this issue!

@sorinsarca
Copy link
Member

@abdrzakoxa I'm looking at that PR right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants