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(), $params];
}
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:
- Forbid using "yield" inside strings
- Expect not a variable name as a result of this expression, but a
substitution value.
What do you think?
Kirill Nesmeyanov
Пятница, 8 октября 2021, 12:14 +03:00 от Kirill Nesmeyanov nesk@xakep.ru:
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(), $params]; }
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/2e7702620480fbce6c24bc87bfb9cb0eI think it makes sense to do something about it.
I have two suggestions:
- Forbid using "yield" inside strings
- Expect not a variable name as a result of this expression, but a
substitution value.What do you think?
Kirill Nesmeyanov
I apologize for the mail duplication. I did not see it receiving on the mailing list (https://news-web.php.net/php.internals) so I sent it again. However, the first came through.
--
Kirill Nesmeyanov