Skip to content

[RFC] Deprecate ${} string interpolation #8212

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

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Zend/tests/bug61681.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ $la = "ooxx";
echo "${substr('laruence', 0, 2)}";

?>
--EXPECT--
--EXPECTF--
Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d
ooxx
12 changes: 12 additions & 0 deletions Zend/tests/deprecate_dollar_brace_string_interpolation_1.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
--TEST--
"${}" emits a deprecation
--FILE--
<?php

$foo = 'bar';
var_dump("${foo}");

?>
--EXPECTF--
Deprecated: Using ${var} in strings is deprecated, use {$var} instead in %s on line %d
string(3) "bar"
3 changes: 2 additions & 1 deletion Zend/tests/exception_in_nested_rope.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ try {
}

?>
--EXPECT--
--EXPECTF--
Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d
Exception
5 changes: 4 additions & 1 deletion Zend/tests/flexible-heredoc-complex-test1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ var_dump(<<<DOC1
DOC1);

?>
--EXPECT--
--EXPECTF--
Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d

Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d
string(5) "a
b
c"
5 changes: 4 additions & 1 deletion Zend/tests/flexible-heredoc-complex-test2.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ var_dump(<<<DOC1
DOC1);

?>
--EXPECT--
--EXPECTF--
Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d

Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d
string(5) "a
b
c"
5 changes: 4 additions & 1 deletion Zend/tests/flexible-heredoc-complex-test3.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ var_dump(<<<DOC1
DOC1);

?>
--EXPECT--
--EXPECTF--
Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d

Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d
string(8) " a
b
c"
5 changes: 4 additions & 1 deletion Zend/tests/flexible-heredoc-complex-test4.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ the same delimiter name as the heredoc
}

?>
--EXPECT--
--EXPECTF--
Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d

Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d
string(8) "Test
FOO"
string(16) " Test
Expand Down
3 changes: 2 additions & 1 deletion Zend/tests/temporary_cleaning_016.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ try {
}
?>
DONE
--EXPECT--
--EXPECTF--
Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d
DONE
2 changes: 2 additions & 0 deletions Zend/tests/warning_during_heredoc_scan_ahead.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ Warning: Octal escape sequence overflow \400 is greater than \377 in %s on line

Warning: Octal escape sequence overflow \400 is greater than \377 in %s on line %d

Deprecated: Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead in %s on line %d

Warning: Undefined variable $ in %s on line %d
11 changes: 10 additions & 1 deletion Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -9504,7 +9504,16 @@ static void zend_compile_encaps_list(znode *result, zend_ast *ast) /* {{{ */
j = 0;
last_const_node.op_type = IS_UNUSED;
for (i = 0; i < list->children; i++) {
zend_compile_expr(&elem_node, list->child[i]);
zend_ast *encaps_var = list->child[i];
if (encaps_var->attr & (ZEND_ENCAPS_VAR_DOLLAR_CURLY|ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR)) {
if (encaps_var->attr & ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR) {
zend_error(E_DEPRECATED, "Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead");
} else {
zend_error(E_DEPRECATED, "Using ${var} in strings is deprecated, use {$var} instead");
}
}

zend_compile_expr(&elem_node, encaps_var);

if (elem_node.op_type == IS_CONST) {
convert_to_string(&elem_node.u.constant);
Expand Down
4 changes: 4 additions & 0 deletions Zend/zend_compile.h
Original file line number Diff line number Diff line change
Expand Up @@ -1077,6 +1077,10 @@ static zend_always_inline bool zend_check_arg_send_type(const zend_function *zf,
/* Attribute for ternary inside parentheses */
#define ZEND_PARENTHESIZED_CONDITIONAL 1

/* Attributes for ${} encaps var in strings */
#define ZEND_ENCAPS_VAR_DOLLAR_CURLY (1<<0)
#define ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR (1<<1)

/* For "use" AST nodes and the seen symbol table */
#define ZEND_SYMBOL_CLASS (1<<0)
#define ZEND_SYMBOL_FUNCTION (1<<1)
Expand Down
6 changes: 3 additions & 3 deletions Zend/zend_language_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -1490,11 +1490,11 @@ encaps_var:
{ $$ = zend_ast_create(ZEND_AST_NULLSAFE_PROP,
zend_ast_create(ZEND_AST_VAR, $1), $3); }
| T_DOLLAR_OPEN_CURLY_BRACES expr '}'
{ $$ = zend_ast_create(ZEND_AST_VAR, $2); }
{ $$ = zend_ast_create_ex(ZEND_AST_VAR, ZEND_ENCAPS_VAR_DOLLAR_CURLY_VAR_VAR, $2); }
| T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}'
{ $$ = zend_ast_create(ZEND_AST_VAR, $2); }
{ $$ = zend_ast_create_ex(ZEND_AST_VAR, ZEND_ENCAPS_VAR_DOLLAR_CURLY, $2); }
| T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
{ $$ = zend_ast_create(ZEND_AST_DIM,
{ $$ = zend_ast_create_ex(ZEND_AST_DIM, ZEND_ENCAPS_VAR_DOLLAR_CURLY,
zend_ast_create(ZEND_AST_VAR, $2), $4); }
| T_CURLY_OPEN variable '}' { $$ = $2; }
;
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_vm_gen.php
Original file line number Diff line number Diff line change
Expand Up @@ -2865,7 +2865,7 @@ function gen_vm($def, $skel) {
out($f, "\t\t\t\t\tbreak;\n");
out($f, "\t\t\t\t}\n");
}
out($f, "\t\t\t\tspec = ${spec_dsc['spec_code']};\n");
out($f, "\t\t\t\tspec = {$spec_dsc['spec_code']};\n");
if (isset($spec_dsc["spec"]["COMMUTATIVE"]) && !isset($dsc["spec"]["COMMUTATIVE"])) {
out($f, "\t\t\t\tif (op->op1_type < op->op2_type) {\n");
out($f, "\t\t\t\t\tzend_swap_operands(op);\n");
Expand Down
2 changes: 1 addition & 1 deletion build/gen_stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -1484,7 +1484,7 @@ public function getDeclaration(): string {
} else {
$escapedClassName = $arginfoType->classTypes[0]->toEscapedName();
$varEscapedClassName = $arginfoType->classTypes[0]->toVarEscapedName();
$code .= "\tzend_string *property_{$propertyName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"${escapedClassName}\")-1, 1);\n";
$code .= "\tzend_string *property_{$propertyName}_class_{$varEscapedClassName} = zend_string_init(\"{$escapedClassName}\", sizeof(\"{$escapedClassName}\")-1, 1);\n";

$typeCode = "(zend_type) ZEND_TYPE_INIT_CLASS(property_{$propertyName}_class_{$varEscapedClassName}, 0, " . $arginfoType->toTypeMask() . ")";
}
Expand Down
6 changes: 3 additions & 3 deletions ext/oci8/tests/lob_prefetch.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ $ora_sql =
end loop;
dbms_lob.createtemporary(b, false);
dbms_lob.converttoblob(b, c, dbms_lob.lobmaxsize, dest_offset, src_offset, dbms_lob.default_csid, ctx, warn);
insert /*+ APPEND */ into ${schema}${table_name} (id, clob, blob) values (j, c, b);
insert /*+ APPEND */ into {$schema}{$table_name} (id, clob, blob) values (j, c, b);
end loop;
commit;
end;";
Expand Down Expand Up @@ -119,7 +119,7 @@ try {

print("Test 3 - CLOB prefetch_lob_size 100000\n");

$sql = "select clob from ${schema}${table_name}" . " order by id";
$sql = "select clob from {$schema}{$table_name}" . " order by id";
$locarr = get_clob_loc($c, $sql, 100000);
$inlinearr = get_clob_inline($c, $sql, 100000);

Expand All @@ -138,7 +138,7 @@ check_clobs($locarr, $inlinearr);

print("Test 4 - BLOB prefetch_lob_size 100000\n");

$sql = "select blob from ${schema}${table_name}" . " order by id";
$sql = "select blob from {$schema}{$table_name}" . " order by id";
$locarr = get_blob_loc($c, $sql, 100000);

print(count($locarr) . "\n");
Expand Down
6 changes: 3 additions & 3 deletions ext/oci8/tests/lob_prefetch_ini.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ $ora_sql =
end loop;
dbms_lob.createtemporary(b, false);
dbms_lob.converttoblob(b, c, dbms_lob.lobmaxsize, dest_offset, src_offset, dbms_lob.default_csid, ctx, warn);
insert /*+ APPEND */ into ${schema}${table_name} (id, clob, blob) values (j, c, b);
insert /*+ APPEND */ into {$schema}{$table_name} (id, clob, blob) values (j, c, b);
end loop;
commit;
end;";
Expand Down Expand Up @@ -108,7 +108,7 @@ var_dump($r);

print("Test 2 - CLOB with current oci8.prefetch_lob_size\n");

$sql = "select clob from ${schema}${table_name}" . " order by id";
$sql = "select clob from {$schema}{$table_name}" . " order by id";
$locarr = get_clob_loc($c, $sql, -1);
$inlinearr = get_clob_inline($c, $sql, -1);

Expand Down Expand Up @@ -136,7 +136,7 @@ check_clobs($locarr, $inlinearr);

print("Test 5 - BLOB with current ocig8.prefetch_lob_size \n");

$sql = "select blob from ${schema}${table_name}" . " order by id";
$sql = "select blob from {$schema}{$table_name}" . " order by id";
$locarr = get_blob_loc($c, $sql, -1);

print(count($locarr) . "\n");
Expand Down
2 changes: 1 addition & 1 deletion ext/opcache/tests/opt/gh8140a.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ GH-8140 (Wrong first class callable by name optimization)
namespace Test;

function greeter(string $name) {
echo "Hello, ${name}!";
echo "Hello, {$name}!";
}

$mycallable = greeter(...);
Expand Down
2 changes: 1 addition & 1 deletion ext/opcache/tests/opt/gh8140b.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ GH-8140 (Wrong first class callable by name optimization)
$mycallable = greeter(...);

function greeter(string $name) {
echo "Hello, ${name}!";
echo "Hello, {$name}!";
}

$mycallable("world");
Expand Down
4 changes: 2 additions & 2 deletions ext/pgsql/tests/config.inc
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ $view_name = "php_pgsql_viewtest";
$view_def = "CREATE VIEW {$view_name} AS SELECT * FROM {$table_name};";

// Test table
$table_def = "CREATE TABLE ${table_name} (num int, str text, bin bytea);";
$table_def_92 = "CREATE TABLE ${table_name_92} (textary text[], jsn json);";
$table_def = "CREATE TABLE {$table_name} (num int, str text, bin bytea);";
$table_def_92 = "CREATE TABLE {$table_name_92} (textary text[], jsn json);";
$field_name = "num"; // For pg_field_num()

?>
16 changes: 8 additions & 8 deletions ext/phar/phar/clicommand.inc
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ abstract class CLICommand
$this->typs = self::getArgTyps($this);

if ($argc < 2) {
self::error("No command given, check ${argv[0]} help\n");
self::error("No command given, check {$argv[0]} help\n");
} elseif (!isset($this->cmds[$argv[1]]['run'])) {
self::error("Unknown command '${argv[1]}', check ${argv[0]} help\n");
self::error("Unknown command '{$argv[1]}', check {$argv[0]} help\n");
} else {
$command = $argv[1];
}
Expand All @@ -46,12 +46,12 @@ abstract class CLICommand
if (strlen($argv[$i]) == 2 && isset($this->args[$argv[$i][1]])) {
$arg = $argv[$i][1];
if (++$i >= $argc) {
self::error("Missing argument to parameter '$arg' of command '$command', check ${argv[0]} help\n");
self::error("Missing argument to parameter '$arg' of command '$command', check {$argv[0]} help\n");
} else {
$this->args[$arg]['val'] = $this->checkArgTyp($arg, $i, $argc, $argv);
}
} else {
self::error("Unknown parameter '${argv[$i]}' to command $command, check ${argv[0]} help\n");
self::error("Unknown parameter '{$argv[$i]}' to command $command, check {$argv[0]} help\n");
}
} else {
break;
Expand All @@ -61,7 +61,7 @@ abstract class CLICommand
if (isset($this->args[''])) {
if ($i >= $argc) {
if (isset($this->args['']['require']) && $this->args['']['require']) {
self::error("Missing default trailing arguments to command $command, check ${argv[0]} help\n");
self::error("Missing default trailing arguments to command $command, check {$argv[0]} help\n");
}
} else {
$this->args['']['val'] = array();
Expand All @@ -70,12 +70,12 @@ abstract class CLICommand
}
}
} else if ($i < $argc) {
self::error("Unexpected default arguments to command $command, check ${argv[0]} help\n");
self::error("Unexpected default arguments to command $command, check {$argv[0]} help\n");
}

foreach($this->args as $arg => $inf) {
if (strlen($arg) && !isset($inf['val']) && isset($inf['required']) && $inf['required']) {
$missing .= "Missing parameter '-$arg' to command $command, check ${argv[0]} help\n";
$missing .= "Missing parameter '-$arg' to command $command, check {$argv[0]} help\n";
}
}

Expand Down Expand Up @@ -265,7 +265,7 @@ abstract class CLICommand
$sp3 = $this->cli_get_SP3($l, $ls, $inf);
$l3 = strlen($sp3);
foreach($conf['select'] as $opt => $what) {
$inf .= $this->cli_wordwrap($sp2 . " " . sprintf("%-${ls}s ", $opt) . $what, $l3, $sp3) . "\n";
$inf .= $this->cli_wordwrap($sp2 . " " . sprintf("%-{$ls}s ", $opt) . $what, $l3, $sp3) . "\n";
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion ext/phar/phar/pharcommand.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1598,7 +1598,7 @@ class PharCommand extends CLICommand
if (is_bool($v)) {
$v = $v ? 'enabled' : 'disabled';
}
printf("%-${klen}s %s\n", $k.':', $v);
printf("%-{$klen}s %s\n", $k.':', $v);
}
}
// }}}
Expand Down
16 changes: 8 additions & 8 deletions ext/session/tests/save_handler.inc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ function open($save_path, $session_name) {
global $session_save_path, $name;
$session_save_path = $save_path;
$name = $session_name;
echo "Open [${session_save_path},${session_name}]\n";
echo "Open [{$session_save_path},{$session_name}]\n";

// MUST return bool. Return TRUE for success.
return true;
Expand All @@ -39,7 +39,7 @@ function close() {
// NOTE: This function should unlock session data, if write() does not unlock it.

global $session_save_path, $name;
echo "Close [${session_save_path},${name}]\n";
echo "Close [{$session_save_path},{$name}]\n";

// MUST return bool. Return TRUE for success.
return true;
Expand All @@ -54,7 +54,7 @@ function read($id) {

global $session_save_path, $name, $session_id;
$session_id = $id;
echo "Read [${session_save_path},${id}]\n";
echo "Read [{$session_save_path},{$id}]\n";
$session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id;
// read MUST create file. Otherwise, strict mode will not work
touch($session_file);
Expand All @@ -74,7 +74,7 @@ function write($id, $session_data) {

global $session_save_path, $name, $session_id;
$session_id = $id;
echo "Write [${session_save_path},${id},${session_data}]\n";
echo "Write [{$session_save_path},{$id},{$session_data}]\n";
$session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id;
if ($fp = fopen($session_file, "w")) {
$return = fwrite($fp, $session_data);
Expand All @@ -91,7 +91,7 @@ function destroy($id) {
// string $id - Session ID string

global $session_save_path, $name;
echo "Destroy [${session_save_path},${id}]\n";
echo "Destroy [{$session_save_path},{$id}]\n";
$session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id;
unlink($session_file);

Expand Down Expand Up @@ -136,7 +136,7 @@ function create_sid() {
// e.g. hash('sha2', random_bytes(64)) or use /dev/urandom

$id = ('PHPT-'.time());
echo "CreateID [${id}]\n";
echo "CreateID [{$id}]\n";

// MUST return session ID string.
// Return FALSE for error.
Expand All @@ -148,7 +148,7 @@ function validate_sid($id) {
// string $id - Session ID string

global $session_save_path, $name;
echo "ValidateID [${session_save_path},${id}]\n";
echo "ValidateID [{$session_save_path},{$id}]\n";
$session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id;
$ret = file_exists($session_file);

Expand All @@ -168,7 +168,7 @@ function update($id, $session_data) {
// support time stamp updating, you must not define this.

global $session_save_path, $name;
echo "Update [${session_save_path},${id}]\n";
echo "Update [{$session_save_path},{$id}]\n";
$session_file = "$session_save_path/".SESSION_FILE_PREFIX.$id;
$ret = touch($session_file);

Expand Down
2 changes: 1 addition & 1 deletion ext/soap/tests/bug73037.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ Content-Type: application/soap+xml; charset=UTF-8
Accept: application/soap+xml, application/dime, multipart/related, text/*
SOAPAction: "urn:adressen#adressen#SetAda"
Expect: 100-continue
Content-Length: ${len}
Content-Length: {$len}
HDRS;
if ($b) {
$hdrs .="\nContent-Encoding: gzip";
Expand Down
4 changes: 2 additions & 2 deletions ext/standard/tests/file/windows_mb_path/test_big5_1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ include __DIR__ . DIRECTORY_SEPARATOR . "util.inc";

$item = "���զh�r�`���|"; // BIG5 string
$prefix = create_data("dir_big5", $item . "5", 950);
$path = $prefix . DIRECTORY_SEPARATOR . "${item}5";
$path = $prefix . DIRECTORY_SEPARATOR . "{$item}5";

$subpath = $path . DIRECTORY_SEPARATOR . "${item}4";
$subpath = $path . DIRECTORY_SEPARATOR . "{$item}4";

/* The mb dirname exists*/
var_dump(file_exists($path));
Expand Down
Loading