Yes you are right. The same thing happens if you put a function there.
```
function hi(): string
{
return ‘World’;
}
echo <<<MSG
Hello ${hi()}
MSG;
// Warning: Undefined variable $World!
```
For some reason, I did not take this case into account.
Although it seems to me such semantics are old and require removal from the
language, I admit that there is code that uses it and changing the behavior
will break a lot. Ideally, I would like to see a similar behavior:
```
echo "Hello ${ $var }"; // Hello World
echo "Hello ${ 'Wo' . 'rld' }"; // same
echo "Foo ${ some_foo(42) }";
echo "Foo ${ 23 + 42 }";
echo "Some ${ ClassName::method() >> 2 ?? $any }";
// etc
```
>
>Пятница, 8 октября 2021, 12:22 +03:00 от Nikita Popov <nikita....@gmail.com>:
>
>On Fri, Oct 8, 2021 at 10:55 AM Nesmeyanov Kirill < n...@xakep.ru > wrote:
>
>> Hello Internals!
>>
>>
>> At the moment, there is a feature/bug in the PHP that allows to use
>> interpolation of generators.
>>
>> ```
>>
>> $code = <<<EXAMPLE
>>
>> Hello ${yield}
>>
>> EXAMPLE;
>>
>> ```
>>
>> I suspect that initially this functionality was not thought out, but it
>> partially works, which allows you to implement useful functionality.
>>
>> ```
>>
>> [$query, $params] = sql(fn() => <<<SQL
>>
>> SELECT * FROM users WHERE id = ${yield 42} OR id = ${yield 0xDEADBEEF}
>>
>> SQL);
>>
>> // Expected
>> // $query = "SELECT * FROM users WHERE id = ? OR id = ?"
>> // $params = [ 42, 0xDEADBEEF ]
>>
>> ```
>>
>> When I say that the functionality was not thought out initially, I mean
>> the behavior of generators within strings. For example, the following
>> code, which should (seemingly) implement this functionality:
>>
>> ```
>>
>> function sql(\Closure $expr)
>>
>> {
>>
>> [$generator, $params] = [$expr(), $params];
>>
>> while ($generator->valid()) {
>>
>> $params[] = $generator->current(); // Get the value from "yield"
>>
>> $generator->send('?'); // Insert placeholder
>>
>> }
>>
>> return [$generator->getReturn()];
>>
>> }
>>
>> ```
>>
>> Causes an error:
>>
>> ```
>>
>> Warning: Undefined variable $?
>>
>> ```
>>
>>
>> That is, the expression "${yield 42}" expects back not the result of
>> this expression, but the name of the variable. Therefore, a complete and
>> workable implementation of such a functionality is as follows:
>> https://gist.github.com/SerafimArts/2e7702620480fbce6c24bc87bfb9cb0e
>>
>>
>> I think it makes sense to do something about it. I have two suggestions:
>>
>> 1) Forbid using "yield" inside strings
>>
>> 2) Expect not a variable name as a result of this expression, but a
>> substitution value.
>>
>This doesn't really have anything to do with yield. ${expr} is PHP's
>general variable-variable syntax, which looks up the variable with name
>returned by expr. The syntax also works inside strings in the form of
>"${expr}". Using "${yield $v}" is just a specific instance of the general
>pattern following the same rules. (This syntax has a special case that
>should be deprecated: "${label}" will be interpreted the same as "$label"
>instead, which is inconsistent with how it works everywhere else. This is
>also why ${yield} without argument will not perform a yield and instead
>look for a variable called $yield.)
>
>PHP unfortunately doesn't have a general expression interpolation syntax,
>you can only interpolate variables and certain variable-like constructs.
>
>Regards,
>Nikita
--
Kirill Nesmeyanov