mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
ext/standard: Deprecate $http_response_header (#19464)
RFC: https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable
This commit is contained in:
committed by
GitHub
parent
e87767686c
commit
8a5972fd83
@@ -339,6 +339,7 @@ void zend_oparray_context_begin(zend_oparray_context *prev_context, zend_op_arra
|
||||
CG(context).try_catch_offset = -1;
|
||||
CG(context).current_brk_cont = -1;
|
||||
CG(context).last_brk_cont = 0;
|
||||
CG(context).has_assigned_to_http_response_header = false;
|
||||
CG(context).brk_cont_array = NULL;
|
||||
CG(context).labels = NULL;
|
||||
CG(context).in_jmp_frameless_branch = false;
|
||||
@@ -2867,7 +2868,7 @@ static void zend_compile_class_ref(znode *result, zend_ast *name_ast, uint32_t f
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_result zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */
|
||||
static zend_result zend_try_compile_cv(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
|
||||
{
|
||||
zend_ast *name_ast = ast->child[0];
|
||||
if (name_ast->kind == ZEND_AST_ZVAL) {
|
||||
@@ -2884,6 +2885,16 @@ static zend_result zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (!CG(context).has_assigned_to_http_response_header && zend_string_equals_literal(name, "http_response_header")) {
|
||||
if (type == BP_VAR_R) {
|
||||
zend_error(E_DEPRECATED,
|
||||
"The predefined locally scoped $http_response_header variable is deprecated,"
|
||||
" call http_get_last_response_headers() instead");
|
||||
} else if (type == BP_VAR_W) {
|
||||
CG(context).has_assigned_to_http_response_header = true;
|
||||
}
|
||||
}
|
||||
|
||||
result->op_type = IS_CV;
|
||||
result->u.op.var = lookup_cv(name);
|
||||
|
||||
@@ -2920,6 +2931,14 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint
|
||||
|
||||
opline->extended_value = ZEND_FETCH_GLOBAL;
|
||||
} else {
|
||||
// TODO: Have a test case for this?
|
||||
if (name_node.op_type == IS_CONST
|
||||
&& type == BP_VAR_R
|
||||
&& zend_string_equals_literal(Z_STR(name_node.u.constant), "http_response_header")) {
|
||||
zend_error(E_DEPRECATED,
|
||||
"The predefined locally scoped $http_response_header variable is deprecated,"
|
||||
" call http_get_last_response_headers() instead");
|
||||
}
|
||||
opline->extended_value = ZEND_FETCH_LOCAL;
|
||||
}
|
||||
|
||||
@@ -2991,7 +3010,7 @@ static zend_op *zend_compile_simple_var(znode *result, zend_ast *ast, uint32_t t
|
||||
result->op_type = IS_TMP_VAR;
|
||||
}
|
||||
return opline;
|
||||
} else if (zend_try_compile_cv(result, ast) == FAILURE) {
|
||||
} else if (zend_try_compile_cv(result, ast, type) == FAILURE) {
|
||||
return zend_compile_simple_var_no_cv(result, ast, type, delayed);
|
||||
}
|
||||
return NULL;
|
||||
@@ -3417,7 +3436,7 @@ static void zend_compile_expr_with_potential_assign_to_self(
|
||||
/* $a[0] = $a should evaluate the right $a first */
|
||||
znode cv_node;
|
||||
|
||||
if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) {
|
||||
if (zend_try_compile_cv(&cv_node, expr_ast, BP_VAR_R) == FAILURE) {
|
||||
zend_compile_simple_var_no_cv(expr_node, expr_ast, BP_VAR_R, 0);
|
||||
} else {
|
||||
zend_emit_op_tmp(expr_node, ZEND_QM_ASSIGN, &cv_node, NULL);
|
||||
@@ -3507,7 +3526,7 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
|
||||
/* list($a, $b) = $a should evaluate the right $a first */
|
||||
znode cv_node;
|
||||
|
||||
if (zend_try_compile_cv(&cv_node, expr_ast) == FAILURE) {
|
||||
if (zend_try_compile_cv(&cv_node, expr_ast, BP_VAR_R) == FAILURE) {
|
||||
zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0);
|
||||
} else {
|
||||
zend_emit_op_tmp(&expr_node, ZEND_QM_ASSIGN, &cv_node, NULL);
|
||||
@@ -3822,7 +3841,7 @@ static uint32_t zend_compile_args(
|
||||
opcode = ZEND_SEND_VAR_EX;
|
||||
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
|
||||
break;
|
||||
} else if (zend_try_compile_cv(&arg_node, arg) == SUCCESS) {
|
||||
} else if (zend_try_compile_cv(&arg_node, arg, BP_VAR_R) == SUCCESS) {
|
||||
opcode = ZEND_SEND_VAR_EX;
|
||||
break;
|
||||
}
|
||||
@@ -5427,7 +5446,7 @@ static void zend_compile_global_var(zend_ast *ast) /* {{{ */
|
||||
// TODO(GLOBALS) Forbid "global $GLOBALS"?
|
||||
if (is_this_fetch(var_ast)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot use $this as global variable");
|
||||
} else if (zend_try_compile_cv(&result, var_ast) == SUCCESS) {
|
||||
} else if (zend_try_compile_cv(&result, var_ast, BP_VAR_R) == SUCCESS) {
|
||||
zend_op *opline = zend_emit_op(NULL, ZEND_BIND_GLOBAL, &result, &name_node);
|
||||
opline->extended_value = zend_alloc_cache_slot();
|
||||
} else {
|
||||
@@ -5553,7 +5572,7 @@ static void zend_compile_unset(zend_ast *ast) /* {{{ */
|
||||
case ZEND_AST_VAR:
|
||||
if (is_this_fetch(var_ast)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot unset $this");
|
||||
} else if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
|
||||
} else if (zend_try_compile_cv(&var_node, var_ast, BP_VAR_UNSET) == SUCCESS) {
|
||||
opline = zend_emit_op(NULL, ZEND_UNSET_CV, &var_node, NULL);
|
||||
} else {
|
||||
opline = zend_compile_simple_var_no_cv(NULL, var_ast, BP_VAR_UNSET, 0);
|
||||
@@ -6116,7 +6135,7 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */
|
||||
if (is_this_fetch(value_ast)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
|
||||
} else if (value_ast->kind == ZEND_AST_VAR &&
|
||||
zend_try_compile_cv(&value_node, value_ast) == SUCCESS) {
|
||||
zend_try_compile_cv(&value_node, value_ast, BP_VAR_R) == SUCCESS) {
|
||||
SET_NODE(opline->op2, &value_node);
|
||||
} else {
|
||||
opline->op2_type = IS_VAR;
|
||||
@@ -10842,7 +10861,7 @@ static void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */
|
||||
if (is_this_fetch(var_ast)) {
|
||||
opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_THIS, NULL, NULL);
|
||||
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
|
||||
} else if (zend_try_compile_cv(&var_node, var_ast) == SUCCESS) {
|
||||
} else if (zend_try_compile_cv(&var_node, var_ast, BP_VAR_IS) == SUCCESS) {
|
||||
opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_CV, &var_node, NULL);
|
||||
} else {
|
||||
opline = zend_compile_simple_var_no_cv(result, var_ast, BP_VAR_IS, 0);
|
||||
|
||||
@@ -208,6 +208,7 @@ typedef struct _zend_oparray_context {
|
||||
zend_string *active_property_info_name;
|
||||
zend_property_hook_kind active_property_hook_kind;
|
||||
bool in_jmp_frameless_branch;
|
||||
bool has_assigned_to_http_response_header;
|
||||
} zend_oparray_context;
|
||||
|
||||
/* Class, property and method flags class|meth.|prop.|const*/
|
||||
|
||||
@@ -15,7 +15,7 @@ $responses = array(
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
var_dump(file_get_contents($uri));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
|
||||
@@ -33,7 +33,8 @@ var_dump(http_get_last_response_headers());
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 23
|
||||
NULL
|
||||
array(3) {
|
||||
[0]=>
|
||||
|
||||
@@ -30,7 +30,8 @@ for ($i = 0; $i < count($responses); ++$i) {
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 17
|
||||
http_get_last_response_headers() before stream layer call:
|
||||
NULL
|
||||
$http_response_header
|
||||
|
||||
@@ -36,7 +36,7 @@ $clientCode = <<<'CODE'
|
||||
$ctx = stream_context_create();
|
||||
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
|
||||
var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx)));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -36,7 +36,7 @@ $clientCode = <<<'CODE'
|
||||
$ctx = stream_context_create();
|
||||
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
|
||||
var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx)));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -33,7 +33,7 @@ $clientCode = <<<'CODE'
|
||||
];
|
||||
$ctx = stream_context_create($opts);
|
||||
var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx))));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -33,7 +33,7 @@ $clientCode = <<<'CODE'
|
||||
];
|
||||
$ctx = stream_context_create($opts);
|
||||
var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx))));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -33,7 +33,7 @@ $clientCode = <<<'CODE'
|
||||
];
|
||||
$ctx = stream_context_create($opts);
|
||||
var_dump(explode("\r\n", base64_decode(file_get_contents("http://user:pwd@{{ ADDR }}", false, $ctx))));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -32,7 +32,7 @@ $clientCode = <<<'CODE'
|
||||
$ctx = stream_context_create();
|
||||
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
|
||||
var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -32,7 +32,7 @@ $clientCode = <<<'CODE'
|
||||
$ctx = stream_context_create();
|
||||
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
|
||||
var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -32,7 +32,7 @@ $clientCode = <<<'CODE'
|
||||
$ctx = stream_context_create();
|
||||
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
|
||||
var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx)));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -32,7 +32,7 @@ $clientCode = <<<'CODE'
|
||||
$ctx = stream_context_create();
|
||||
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
|
||||
var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx)));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -32,7 +32,7 @@ $clientCode = <<<'CODE'
|
||||
$ctx = stream_context_create();
|
||||
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
|
||||
var_dump(trim(file_get_contents("http://{{ ADDR }}", false, $ctx)));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -32,7 +32,7 @@ $clientCode = <<<'CODE'
|
||||
$ctx = stream_context_create();
|
||||
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
|
||||
var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -32,7 +32,7 @@ $clientCode = <<<'CODE'
|
||||
$ctx = stream_context_create();
|
||||
stream_context_set_params($ctx, array("notification" => "stream_notification_callback"));
|
||||
var_dump(file_get_contents("http://{{ ADDR }}", false, $ctx));
|
||||
var_dump($http_response_header);
|
||||
var_dump(http_get_last_response_headers());
|
||||
CODE;
|
||||
|
||||
include sprintf("%s/../../../openssl/tests/ServerClientTestCase.inc", __DIR__);
|
||||
|
||||
@@ -24,7 +24,8 @@ var_dump(http_get_last_response_headers());
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 14
|
||||
NULL
|
||||
string(4) "Body"
|
||||
array(3) {
|
||||
|
||||
@@ -26,7 +26,8 @@ var_dump(http_get_last_response_headers());
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
--EXPECTF--
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 16
|
||||
NULL
|
||||
string(4) "Body"
|
||||
array(5) {
|
||||
|
||||
@@ -27,6 +27,7 @@ http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 16
|
||||
NULL
|
||||
|
||||
Warning: file_get_contents(http://%s:%d): Failed to open stream: HTTP request failed! HTTP/1.0 404 Not Found%a
|
||||
|
||||
@@ -24,7 +24,9 @@ var_dump(http_get_last_response_headers());
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
|
||||
--EXPECTF--
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 14
|
||||
NULL
|
||||
string(4) "Body"
|
||||
array(2) {
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
--TEST--
|
||||
Ensure suggested cross-version compatible code for $http_reponse_header provided by the RFC works
|
||||
--SKIPIF--
|
||||
<?php require 'server.inc'; http_server_skipif(); ?>
|
||||
--INI--
|
||||
allow_url_fopen=1
|
||||
--FILE--
|
||||
<?php
|
||||
require 'server.inc';
|
||||
|
||||
$responses = array(
|
||||
"data://text/plain,HTTP/1.0 200 Ok\r\nSome: Header\r\nSome: Header\r\n\r\nBody",
|
||||
);
|
||||
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
var_dump(http_get_last_response_headers());
|
||||
|
||||
$f = file_get_contents($uri);
|
||||
var_dump($f);
|
||||
|
||||
if (function_exists('http_get_last_response_headers')) {
|
||||
$http_response_header = http_get_last_response_headers();
|
||||
}
|
||||
var_dump($http_response_header);
|
||||
|
||||
http_server_kill($pid);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
NULL
|
||||
string(4) "Body"
|
||||
array(3) {
|
||||
[0]=>
|
||||
string(15) "HTTP/1.0 200 Ok"
|
||||
[1]=>
|
||||
string(12) "Some: Header"
|
||||
[2]=>
|
||||
string(12) "Some: Header"
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
$http_reponse_header should warn once per file
|
||||
--SKIPIF--
|
||||
<?php require 'server.inc'; http_server_skipif(); ?>
|
||||
--INI--
|
||||
allow_url_fopen=1
|
||||
--FILE--
|
||||
<?php
|
||||
require 'server.inc';
|
||||
|
||||
include 'http_response_header_deprecated_multiple_files_1.inc';
|
||||
|
||||
include 'http_response_header_deprecated_multiple_files_2.inc';
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %shttp_response_header_deprecated_multiple_files_1.inc on line %d
|
||||
string(6) "Body11"
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(15) "HTTP/1.0 200 Ok"
|
||||
[1]=>
|
||||
string(13) "Some: Header1"
|
||||
}
|
||||
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %shttp_response_header_deprecated_multiple_files_2.inc on line %d
|
||||
string(5) "Body2"
|
||||
array(2) {
|
||||
[0]=>
|
||||
string(15) "HTTP/1.0 200 Ok"
|
||||
[1]=>
|
||||
string(13) "Some: Header2"
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
$responses = array(
|
||||
"data://text/plain,HTTP/1.0 200 Ok\r\nSome: Header1\r\n\r\nBody11",
|
||||
);
|
||||
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
$f = file_get_contents($uri);
|
||||
var_dump($f);
|
||||
var_dump($http_response_header);
|
||||
|
||||
http_server_kill($pid);
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
$responses = array(
|
||||
"data://text/plain,HTTP/1.0 200 Ok\r\nSome: Header2\r\n\r\nBody2",
|
||||
);
|
||||
|
||||
['pid' => $pid, 'uri' => $uri] = http_server($responses, $output);
|
||||
|
||||
$f = file_get_contents($uri);
|
||||
var_dump($f);
|
||||
var_dump($http_response_header);
|
||||
|
||||
http_server_kill($pid);
|
||||
@@ -0,0 +1,20 @@
|
||||
--TEST--
|
||||
$http_reponse_header should warn once per oparray
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function foo() {
|
||||
var_dump($http_response_header);
|
||||
}
|
||||
|
||||
class C {
|
||||
public function bar() {
|
||||
var_dump($http_response_header);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 4
|
||||
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 9
|
||||
@@ -0,0 +1,16 @@
|
||||
--TEST--
|
||||
$http_reponse_header should warn once per oparray even if nested
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function foo() {
|
||||
$http_response_header = "foo";
|
||||
function nested() {
|
||||
echo $http_response_header;
|
||||
}
|
||||
echo $http_response_header;
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Deprecated: The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead in %s on line 6
|
||||
Reference in New Issue
Block a user