Skip to content

Implement "Deprecate functions with overloaded signatures" RFC for PHP 8.3 #11703

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

Merged
merged 13 commits into from
Jul 18, 2023
Merged
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
17 changes: 14 additions & 3 deletions Zend/tests/009.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,16 @@ class foo2 extends foo {
$f1 = new foo;
$f2 = new foo2;

$f1->bar();
set_error_handler(function ($severity, $message, $file, $line) {
throw new Exception($message);
});
try {
$f1->bar();
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
set_error_handler(null);

$f2->bar();

try {
Expand All @@ -44,8 +53,10 @@ $f1->testNull();

echo "Done\n";
?>
--EXPECT--
string(3) "foo"
--EXPECTF--
Calling get_class() without arguments is deprecated

Deprecated: Calling get_class() without arguments is deprecated in %s on line %d
string(3) "foo"
get_class() without arguments must be called from within a class
get_class(): Argument #1 ($object) must be of type object, string given
Expand Down
19 changes: 17 additions & 2 deletions Zend/tests/010.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,23 @@ class foo implements i {

class bar extends foo {
function test_bar() {
var_dump(get_parent_class());
var_dump(get_parent_class($this));
}
}

$bar = new bar;
$foo = new foo;

set_error_handler(function ($severity, $message, $file, $line) {
throw new Exception($message);
});
try {
$foo->test();
} catch (Exception $e) {
echo $e->getMessage() . "\n";
}
set_error_handler(null);

$foo->test();
$bar->test();
$bar->test_bar();
Expand Down Expand Up @@ -66,8 +76,13 @@ try {

echo "Done\n";
?>
--EXPECT--
--EXPECTF--
Calling get_parent_class() without arguments is deprecated

Deprecated: Calling get_parent_class() without arguments is deprecated in %s on line %d
bool(false)

Deprecated: Calling get_parent_class() without arguments is deprecated in %s on line %d
bool(false)
string(3) "foo"
string(3) "foo"
Expand Down
2 changes: 1 addition & 1 deletion Zend/tests/bug78868.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ spl_autoload_register('main_autoload');

$classA = new ReflectionClass("A");
$props = $classA->getProperties();
$props[0]->setValue(2); //causes constant resolving, which runs autoload, all with EG(fake_scope) == "A"
$props[0]->setValue(null, 2); //causes constant resolving, which runs autoload, all with EG(fake_scope) == "A"

echo "OK\n";
?>
Expand Down
6 changes: 5 additions & 1 deletion Zend/tests/class_alias_017.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ baz::test();
bar::test();

?>
--EXPECT--
--EXPECTF--
foo
baz

Deprecated: Calling get_class() without arguments is deprecated in %s on line %d
foo

Deprecated: Calling get_class() without arguments is deprecated in %s on line %d
foo
4 changes: 2 additions & 2 deletions Zend/tests/closure_058.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ Closure 058: Closure scope and object
<?php
class A {
static function foo() {
return function () {var_dump(get_class(),get_called_class());};
return function () {var_dump(self::class,get_called_class());};
}
function bar() {
return function () {var_dump(get_class(),get_called_class(),$this);};
return function () {var_dump(self::class,get_called_class(),$this);};
}
}
$z = "call_user_func";
Expand Down
3 changes: 2 additions & 1 deletion Zend/tests/generators/generator_static_method.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ foreach (ExtendedTest::gen() as $i) {
}

?>
--EXPECT--
--EXPECTF--
Deprecated: Calling get_class() without arguments is deprecated in %s on line %d
string(4) "Test"
string(12) "ExtendedTest"
int(1)
Expand Down
5 changes: 4 additions & 1 deletion Zend/tests/get_parent_class_001.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ $a = new foo;
$a->foo();

?>
--EXPECT--
--EXPECTF--
Deprecated: Calling get_parent_class() without arguments is deprecated in %s on line %d
string(3) "bar"

Deprecated: Calling get_parent_class() without arguments is deprecated in %s on line %d
bool(false)
8 changes: 8 additions & 0 deletions Zend/zend_builtin_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,10 @@ ZEND_FUNCTION(get_class)
zend_class_entry *scope = zend_get_executed_scope();

if (scope) {
zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated");
if (UNEXPECTED(EG(exception))) {
RETURN_THROWS();
}
RETURN_STR_COPY(scope->name);
} else {
zend_throw_error(NULL, "get_class() without arguments must be called from within a class");
Expand Down Expand Up @@ -596,6 +600,10 @@ ZEND_FUNCTION(get_parent_class)
ZEND_PARSE_PARAMETERS_END();

if (!ce) {
zend_error(E_DEPRECATED, "Calling get_parent_class() without arguments is deprecated");
if (UNEXPECTED(EG(exception))) {
RETURN_THROWS();
}
ce = zend_get_executed_scope();
}

Expand Down
6 changes: 5 additions & 1 deletion Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -9355,13 +9355,17 @@ ZEND_VM_COLD_CONST_HANDLER(191, ZEND_GET_CLASS, UNUSED|CONST|TMPVAR|CV, UNUSED)
USE_OPLINE

if (OP1_TYPE == IS_UNUSED) {
SAVE_OPLINE();
if (UNEXPECTED(!EX(func)->common.scope)) {
SAVE_OPLINE();
zend_throw_error(NULL, "get_class() without arguments must be called from within a class");
ZVAL_UNDEF(EX_VAR(opline->result.var));
HANDLE_EXCEPTION();
} else {
zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated");
ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name);
if (UNEXPECTED(EG(exception))) {
HANDLE_EXCEPTION();
}
ZEND_VM_NEXT_OPCODE();
}
} else {
Expand Down
24 changes: 20 additions & 4 deletions Zend/zend_vm_execute.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

127 changes: 84 additions & 43 deletions ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -4843,6 +4843,88 @@ static bool date_period_initialize(timelib_time **st, timelib_time **et, timelib
return retval;
} /* }}} */

static bool date_period_init_iso8601_string(php_period_obj *dpobj, char *isostr, size_t isostr_len, zend_long options, zend_long *recurrences) {
if (!date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), recurrences, isostr, isostr_len)) {
return false;
}

if (dpobj->start == NULL) {
zend_string *func = get_active_function_or_method_name();
zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain a start date, \"%s\" given", ZSTR_VAL(func), isostr);
zend_string_release(func);
return false;
}
if (dpobj->interval == NULL) {
zend_string *func = get_active_function_or_method_name();
zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain an interval, \"%s\" given", ZSTR_VAL(func), isostr);
zend_string_release(func);
return false;
}
if (dpobj->end == NULL && recurrences == 0) {
zend_string *func = get_active_function_or_method_name();
zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain an end date or a recurrence count, \"%s\" given", ZSTR_VAL(func), isostr);
zend_string_release(func);
return false;
}

if (dpobj->start) {
timelib_update_ts(dpobj->start, NULL);
}
if (dpobj->end) {
timelib_update_ts(dpobj->end, NULL);
}
dpobj->start_ce = date_ce_date;

return true;
}

static bool date_period_init_finish(php_period_obj *dpobj, zend_long options, zend_long recurrences) {
if (dpobj->end == NULL && recurrences < 1) {
zend_string *func = get_active_function_or_method_name();
zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): Recurrence count must be greater than 0", ZSTR_VAL(func));
zend_string_release(func);
return false;
}

/* options */
dpobj->include_start_date = !(options & PHP_DATE_PERIOD_EXCLUDE_START_DATE);
dpobj->include_end_date = options & PHP_DATE_PERIOD_INCLUDE_END_DATE;

/* recurrrences */
dpobj->recurrences = recurrences + dpobj->include_start_date + dpobj->include_end_date;

dpobj->initialized = 1;

initialize_date_period_properties(dpobj);

return true;
}

PHP_METHOD(DatePeriod, createFromISO8601String)
{
php_period_obj *dpobj;
zend_long recurrences = 0, options = 0;
char *isostr = NULL;
size_t isostr_len = 0;

if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|l", &isostr, &isostr_len, &options) == FAILURE) {
RETURN_THROWS();
}

object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_period);
dpobj = Z_PHPPERIOD_P(return_value);

dpobj->current = NULL;

if (!date_period_init_iso8601_string(dpobj, isostr, isostr_len, options, &recurrences)) {
RETURN_THROWS();
}

if (!date_period_init_finish(dpobj, options, recurrences)) {
RETURN_THROWS();
}
}

/* {{{ Creates new DatePeriod object. */
PHP_METHOD(DatePeriod, __construct)
{
Expand All @@ -4867,36 +4949,9 @@ PHP_METHOD(DatePeriod, __construct)
dpobj->current = NULL;

if (isostr) {
if (!date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), &recurrences, isostr, isostr_len)) {
RETURN_THROWS();
}

if (dpobj->start == NULL) {
zend_string *func = get_active_function_or_method_name();
zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain a start date, \"%s\" given", ZSTR_VAL(func), isostr);
zend_string_release(func);
RETURN_THROWS();
}
if (dpobj->interval == NULL) {
zend_string *func = get_active_function_or_method_name();
zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain an interval, \"%s\" given", ZSTR_VAL(func), isostr);
zend_string_release(func);
if (!date_period_init_iso8601_string(dpobj, isostr, isostr_len, options, &recurrences)) {
RETURN_THROWS();
}
if (dpobj->end == NULL && recurrences == 0) {
zend_string *func = get_active_function_or_method_name();
zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain an end date or a recurrence count, \"%s\" given", ZSTR_VAL(func), isostr);
zend_string_release(func);
RETURN_THROWS();
}

if (dpobj->start) {
timelib_update_ts(dpobj->start, NULL);
}
if (dpobj->end) {
timelib_update_ts(dpobj->end, NULL);
}
dpobj->start_ce = date_ce_date;
} else {
/* init */
php_interval_obj *intobj = Z_PHPINTERVAL_P(interval);
Expand Down Expand Up @@ -4925,23 +4980,9 @@ PHP_METHOD(DatePeriod, __construct)
}
}

if (dpobj->end == NULL && recurrences < 1) {
zend_string *func = get_active_function_or_method_name();
zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): Recurrence count must be greater than 0", ZSTR_VAL(func));
zend_string_release(func);
if (!date_period_init_finish(dpobj, options, recurrences)) {
RETURN_THROWS();
}

/* options */
dpobj->include_start_date = !(options & PHP_DATE_PERIOD_EXCLUDE_START_DATE);
dpobj->include_end_date = options & PHP_DATE_PERIOD_INCLUDE_END_DATE;

/* recurrrences */
dpobj->recurrences = recurrences + dpobj->include_start_date + dpobj->include_end_date;

dpobj->initialized = 1;

initialize_date_period_properties(dpobj);
}
/* }}} */

Expand Down
Loading