diff --git a/NEWS b/NEWS
index cc4ff914844c..b99bdc51e87c 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,7 @@ PHP NEWS
- Date:
. Update timelib to 2026.02. (Derick, timwolla)
+ . Added Time\Duration. (timwolla, Derick)
- GMP:
. Added optional $definitely_prime output parameter to gmp_prevprime().
@@ -66,6 +67,8 @@ PHP NEWS
is_link(), file_exists(), lstat(), stat(). (Girgias)
. Fixed bug GH-22818 (stream_filter_register() orphaned user_filter_map on
shutdown re-registration). (David Carlier)
+ . Io\Poll\Context::wait() now takes a Time\Duration object as a timeout.
+ (timwolla)
30 Jul 2026, PHP 8.6.0alpha3
diff --git a/UPGRADING b/UPGRADING
index 25a405e1521d..ba4bf182911f 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -313,6 +313,10 @@ PHP 8.6 UPGRADE NOTES
offset and origin, and must return one of CURL_SEEKFUNC_OK,
CURL_SEEKFUNC_FAIL or CURL_SEEKFUNC_CANTSEEK.
+- Date:
+ . Added a new Time\Duration class.
+ RFC: https://wiki.php.net/rfc/duration_class
+
- Fileinfo:
. finfo_file() now works with remote streams.
@@ -553,6 +557,12 @@ PHP 8.6 UPGRADE NOTES
7. New Classes and Interfaces
========================================
+- Date:
+ . Time\Duration
+ RFC: https://wiki.php.net/rfc/duration_class
+ . Time\TimeException
+ RFC: https://wiki.php.net/rfc/duration_class
+
- Intl:
. IntlNumberRangeFormatter
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index a3e4e1690d6c..aff9846d21b8 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -2057,9 +2057,9 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string
#define Z_PARAM_ENUM(dest, _ce) \
{ \
- zend_object *_tmp = NULL; \
- Z_PARAM_OBJ_OF_CLASS(_tmp, _ce); \
- dest = zend_enum_fetch_case_id(_tmp); \
+ zend_object *__##dest = NULL; \
+ Z_PARAM_OBJ_OF_CLASS(__##dest, _ce); \
+ dest = zend_enum_fetch_case_id(__##dest); \
}
/* old "p" */
diff --git a/ext/date/config.w32 b/ext/date/config.w32
index 78cca036d380..327242f128ac 100644
--- a/ext/date/config.w32
+++ b/ext/date/config.w32
@@ -1,6 +1,6 @@
// vim:ft=javascript
-EXTENSION("date", "php_date.c", false, "/Iext/date/lib /DHAVE_TIMELIB_CONFIG_H=1");
+EXTENSION("date", "php_date.c php_time.c time_duration.c", false, "/Iext/date/lib /DHAVE_TIMELIB_CONFIG_H=1");
PHP_DATE = "yes";
ADD_SOURCES("ext/date/lib", "astro.c timelib.c dow.c duration.c parse_date.c parse_posix.c parse_tz.c tm2unixtime.c unixtime2tm.c parse_iso_intervals.c interval.c", "date");
diff --git a/ext/date/config0.m4 b/ext/date/config0.m4
index 4853882465e0..aab6d3d139b3 100644
--- a/ext/date/config0.m4
+++ b/ext/date/config0.m4
@@ -18,7 +18,7 @@ timelib_sources="lib/astro.c lib/dow.c lib/duration.c lib/parse_date.c lib/parse
lib/timelib.c lib/tm2unixtime.c lib/unixtime2tm.c lib/parse_iso_intervals.c lib/interval.c"
PHP_NEW_EXTENSION([date],
- [php_date.c],
+ [php_date.c php_time.c time_duration.c],
[no],,
[$PHP_DATE_CFLAGS])
diff --git a/ext/date/php_date.c b/ext/date/php_date.c
index 0e24e4450641..9f9f0a6159ed 100644
--- a/ext/date/php_date.c
+++ b/ext/date/php_date.c
@@ -18,6 +18,7 @@
#include "ext/standard/info.h"
#include "ext/standard/php_versioning.h"
#include "php_date.h"
+#include "php_time.h"
#include "zend_attributes.h"
#include "zend_interfaces.h"
#include "zend_exceptions.h"
@@ -386,6 +387,7 @@ static PHP_GINIT_FUNCTION(date)
date_globals->default_timezone = NULL;
date_globals->timezone = NULL;
date_globals->tzcache = NULL;
+ date_globals->duration_cache = NULL;
}
/* }}} */
@@ -418,6 +420,10 @@ PHP_RSHUTDOWN_FUNCTION(date)
efree(DATEG(timezone));
}
DATEG(timezone) = NULL;
+ if (DATEG(duration_cache)) {
+ zend_object_release(DATEG(duration_cache));
+ }
+ DATEG(duration_cache) = NULL;
return SUCCESS;
}
@@ -447,6 +453,7 @@ PHP_MINIT_FUNCTION(date)
REGISTER_INI_ENTRIES();
date_register_classes();
register_php_date_symbols(module_number);
+ PHP_MINIT(date_time)(INIT_FUNC_ARGS_PASSTHRU);
php_date_global_timezone_db = NULL;
php_date_global_timezone_db_enabled = 0;
diff --git a/ext/date/php_date.h b/ext/date/php_date.h
index 651cc28225fd..97a49974f1a4 100644
--- a/ext/date/php_date.h
+++ b/ext/date/php_date.h
@@ -115,8 +115,11 @@ ZEND_BEGIN_MODULE_GLOBALS(date)
char *timezone;
HashTable *tzcache;
timelib_error_container *last_errors;
+ zend_object *duration_cache;
ZEND_END_MODULE_GLOBALS(date)
+PHPAPI ZEND_EXTERN_MODULE_GLOBALS(date)
+
#define DATEG(v) ZEND_MODULE_GLOBALS_ACCESSOR(date, v)
PHPAPI time_t php_time(void);
diff --git a/ext/date/php_time.c b/ext/date/php_time.c
new file mode 100644
index 000000000000..2c3698f63fbd
--- /dev/null
+++ b/ext/date/php_time.c
@@ -0,0 +1,65 @@
+/*
+ +----------------------------------------------------------------------+
+ | Copyright © The PHP Group and Contributors. |
+ +----------------------------------------------------------------------+
+ | This source file is subject to the Modified BSD License that is |
+ | bundled with this package in the file LICENSE, and is available |
+ | through the World Wide Web at . |
+ | |
+ | SPDX-License-Identifier: BSD-3-Clause |
+ +----------------------------------------------------------------------+
+ | Authors: Derick Rethans |
+ | Tim Düsterhus |
+ +----------------------------------------------------------------------+
+ */
+
+#include "php.h"
+#include "Zend/zend_exceptions.h"
+
+#include "php_time.h"
+#include "time_arginfo.h"
+
+zend_class_entry *php_date_ce_time_duration;
+zend_class_entry *php_date_ce_time_timeexception;
+
+static zend_object_handlers time_duration_object_handlers;
+
+static zend_object *time_duration_object_create(zend_class_entry *ce)
+{
+ php_date_time_duration *obj = zend_object_alloc(sizeof(*obj), ce);
+
+ zend_object_std_init(&obj->std, ce);
+ object_properties_init(&obj->std, ce);
+
+ timelib_duration_ctor_static(&obj->duration, /* seconds */ 0, /* nanoseconds */ 0, /* negative */ false);
+
+ return &obj->std;
+}
+
+static zend_object *time_duration_object_clone(zend_object *object)
+{
+ const php_date_time_duration *obj = php_date_time_duration_from_obj(object);
+
+ php_date_time_duration *new_obj = php_date_time_duration_from_obj(object->ce->create_object(object->ce));
+
+ new_obj->duration = obj->duration;
+ zend_objects_clone_members(&new_obj->std, &obj->std);
+
+ return &new_obj->std;
+}
+
+PHP_MINIT_FUNCTION(date_time)
+{
+ /* Time\TimeException */
+ php_date_ce_time_timeexception = register_class_Time_TimeException(zend_ce_exception);
+
+ /* Time\Duration */
+ memcpy(&time_duration_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ time_duration_object_handlers.offset = offsetof(php_date_time_duration, std);
+ time_duration_object_handlers.clone_obj = time_duration_object_clone;
+ php_date_ce_time_duration = register_class_Time_Duration();
+ php_date_ce_time_duration->create_object = time_duration_object_create;
+ php_date_ce_time_duration->default_object_handlers = &time_duration_object_handlers;
+
+ return SUCCESS;
+}
diff --git a/ext/date/php_time.h b/ext/date/php_time.h
new file mode 100644
index 000000000000..e6bc7658e389
--- /dev/null
+++ b/ext/date/php_time.h
@@ -0,0 +1,48 @@
+/*
+ +----------------------------------------------------------------------+
+ | Copyright © The PHP Group and Contributors. |
+ +----------------------------------------------------------------------+
+ | This source file is subject to the Modified BSD License that is |
+ | bundled with this package in the file LICENSE, and is available |
+ | through the World Wide Web at . |
+ | |
+ | SPDX-License-Identifier: BSD-3-Clause |
+ +----------------------------------------------------------------------+
+ | Authors: Derick Rethans |
+ | Tim Düsterhus |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHP_DATE_TIME_H
+# define PHP_DATE_TIME_H
+
+# include "php.h"
+# include "lib/timelib.h"
+
+typedef struct php_date_time_duration {
+ timelib_duration duration;
+ zend_object std;
+} php_date_time_duration;
+
+# define php_date_time_duration_from_obj(obj) ZEND_CONTAINER_OF(obj, php_date_time_duration, std)
+
+# define Z_DATE_TIME_DURATION_P(zv) php_date_time_duration_from_obj(Z_OBJ_P((zv)))
+
+# define Z_PARAM_DATE_TIME_DURATION(d) { \
+ zend_object *__##d; \
+ Z_PARAM_OBJ_OF_CLASS(__##d, php_date_ce_time_duration); \
+ d = php_date_time_duration_from_obj(__##d); \
+ }
+
+# define Z_PARAM_DATE_TIME_DURATION_OR_NULL(d) { \
+ zend_object *__##d; \
+ Z_PARAM_OBJ_OF_CLASS_OR_NULL(__##d, php_date_ce_time_duration); \
+ d = __##d ? php_date_time_duration_from_obj(__##d) : NULL; \
+ }
+
+PHPAPI extern zend_class_entry *php_date_ce_time_duration;
+PHPAPI extern zend_class_entry *php_date_ce_time_timeexception;
+
+PHP_MINIT_FUNCTION(date_time);
+
+#endif /* PHP_DATE_TIME_H */
diff --git a/ext/date/tests/time/duration/clone.phpt b/ext/date/tests/time/duration/clone.phpt
new file mode 100644
index 000000000000..06ad23dfe633
--- /dev/null
+++ b/ext/date/tests/time/duration/clone.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Time\Duration: clone
+--FILE--
+negate()), PHP_EOL;
+echo fc(Time\Duration::fromSeconds(1, 1)->negate()), PHP_EOL;
+
+?>
+--EXPECT--
+ +0.000000000
+ +0.000000001
+ +1.000000001
+ -0.000000001
+ -1.000000001
diff --git a/ext/date/tests/time/duration/helper.inc b/ext/date/tests/time/duration/helper.inc
new file mode 100644
index 000000000000..e95f8a6b5b9d
--- /dev/null
+++ b/ext/date/tests/time/duration/helper.inc
@@ -0,0 +1,32 @@
+negative ? "-" : ($plus_sign ? "+" : " ")), $d->seconds, $d->nanoseconds);
+ if ($pad) {
+ $result = str_pad($result, 21, pad_type: STR_PAD_LEFT);
+ }
+
+ return $result;
+}
+
+function as_int(Time\Duration $d): int {
+ return ($d->negative ? -1 : 1) * ($d->seconds * 1_000_000_000 + $d->nanoseconds);
+}
+
+function negate(Time\Duration $d): Time\Duration {
+ return $d->negate();
+}
+
+function is_negative(Time\Duration $d): bool {
+ return $d->negative;
+}
+
+/** @return Time\Duration[] */
+function negate_all(
+ array $d /** @param Time\Duration[] */,
+): array {
+ $negated = array_map(negate(...), $d);
+
+ /* Filter out values that were not successfully negated (i.e. 0-values). */
+ return array_filter($negated, is_negative(...));
+}
diff --git a/ext/date/tests/time/duration/methods/absolute.phpt b/ext/date/tests/time/duration/methods/absolute.phpt
new file mode 100644
index 000000000000..86578488ae89
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/absolute.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Time\Duration::absolute()
+--FILE--
+absolute()), PHP_EOL;
+echo f(Time\Duration::fromSeconds(0, 0)->negate()->absolute()), PHP_EOL;
+
+echo f(Time\Duration::fromSeconds(1, 0)->absolute()), PHP_EOL;
+echo f(Time\Duration::fromSeconds(1, 0)->negate()->absolute()), PHP_EOL;
+
+echo f(Time\Duration::fromSeconds(0, 1)->absolute()), PHP_EOL;
+echo f(Time\Duration::fromSeconds(0, 1)->negate()->absolute()), PHP_EOL;
+
+echo f(Time\Duration::fromSeconds(1, 1)->absolute()), PHP_EOL;
+echo f(Time\Duration::fromSeconds(1, 1)->negate()->absolute()), PHP_EOL;
+
+?>
+--EXPECT--
+ +0.000000000
+ +0.000000000
+ +1.000000000
+ +1.000000000
+ +0.000000001
+ +0.000000001
+ +1.000000001
+ +1.000000001
diff --git a/ext/date/tests/time/duration/methods/add.phpt b/ext/date/tests/time/duration/methods/add.phpt
new file mode 100644
index 000000000000..825bd45de2fe
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/add.phpt
@@ -0,0 +1,371 @@
+--TEST--
+Time\Duration::add()
+--FILE--
+add($b);
+ echo f($a, pad: false, plus_sign: false), " + ", f($b, pad: false, plus_sign: false), " = ", f($result, pad: false), PHP_EOL;
+ if (PHP_INT_SIZE != 4 && (as_int($a) + as_int($b) !== as_int($result))) {
+ throw new \Exception('Verification failed');
+ }
+ }
+}
+
+?>
+--EXPECT--
+========
+ 0.000000000 + 0.000000000 = +0.000000000
+ 0.000000000 + 0.000000001 = +0.000000001
+ 0.000000000 + 0.000000002 = +0.000000002
+ 0.000000000 + 1.000000000 = +1.000000000
+ 0.000000000 + 1.000000001 = +1.000000001
+ 0.000000000 + 1.000000002 = +1.000000002
+ 0.000000000 + 2.000000000 = +2.000000000
+ 0.000000000 + 2.000000001 = +2.000000001
+ 0.000000000 + 2.000000002 = +2.000000002
+====
+ 0.000000000 + -0.000000001 = -0.000000001
+ 0.000000000 + -0.000000002 = -0.000000002
+ 0.000000000 + -1.000000000 = -1.000000000
+ 0.000000000 + -1.000000001 = -1.000000001
+ 0.000000000 + -1.000000002 = -1.000000002
+ 0.000000000 + -2.000000000 = -2.000000000
+ 0.000000000 + -2.000000001 = -2.000000001
+ 0.000000000 + -2.000000002 = -2.000000002
+========
+ 0.000000001 + 0.000000000 = +0.000000001
+ 0.000000001 + 0.000000001 = +0.000000002
+ 0.000000001 + 0.000000002 = +0.000000003
+ 0.000000001 + 1.000000000 = +1.000000001
+ 0.000000001 + 1.000000001 = +1.000000002
+ 0.000000001 + 1.000000002 = +1.000000003
+ 0.000000001 + 2.000000000 = +2.000000001
+ 0.000000001 + 2.000000001 = +2.000000002
+ 0.000000001 + 2.000000002 = +2.000000003
+====
+ 0.000000001 + -0.000000001 = +0.000000000
+ 0.000000001 + -0.000000002 = -0.000000001
+ 0.000000001 + -1.000000000 = -0.999999999
+ 0.000000001 + -1.000000001 = -1.000000000
+ 0.000000001 + -1.000000002 = -1.000000001
+ 0.000000001 + -2.000000000 = -1.999999999
+ 0.000000001 + -2.000000001 = -2.000000000
+ 0.000000001 + -2.000000002 = -2.000000001
+========
+ 0.000000002 + 0.000000000 = +0.000000002
+ 0.000000002 + 0.000000001 = +0.000000003
+ 0.000000002 + 0.000000002 = +0.000000004
+ 0.000000002 + 1.000000000 = +1.000000002
+ 0.000000002 + 1.000000001 = +1.000000003
+ 0.000000002 + 1.000000002 = +1.000000004
+ 0.000000002 + 2.000000000 = +2.000000002
+ 0.000000002 + 2.000000001 = +2.000000003
+ 0.000000002 + 2.000000002 = +2.000000004
+====
+ 0.000000002 + -0.000000001 = +0.000000001
+ 0.000000002 + -0.000000002 = +0.000000000
+ 0.000000002 + -1.000000000 = -0.999999998
+ 0.000000002 + -1.000000001 = -0.999999999
+ 0.000000002 + -1.000000002 = -1.000000000
+ 0.000000002 + -2.000000000 = -1.999999998
+ 0.000000002 + -2.000000001 = -1.999999999
+ 0.000000002 + -2.000000002 = -2.000000000
+========
+ 1.000000000 + 0.000000000 = +1.000000000
+ 1.000000000 + 0.000000001 = +1.000000001
+ 1.000000000 + 0.000000002 = +1.000000002
+ 1.000000000 + 1.000000000 = +2.000000000
+ 1.000000000 + 1.000000001 = +2.000000001
+ 1.000000000 + 1.000000002 = +2.000000002
+ 1.000000000 + 2.000000000 = +3.000000000
+ 1.000000000 + 2.000000001 = +3.000000001
+ 1.000000000 + 2.000000002 = +3.000000002
+====
+ 1.000000000 + -0.000000001 = +0.999999999
+ 1.000000000 + -0.000000002 = +0.999999998
+ 1.000000000 + -1.000000000 = +0.000000000
+ 1.000000000 + -1.000000001 = -0.000000001
+ 1.000000000 + -1.000000002 = -0.000000002
+ 1.000000000 + -2.000000000 = -1.000000000
+ 1.000000000 + -2.000000001 = -1.000000001
+ 1.000000000 + -2.000000002 = -1.000000002
+========
+ 1.000000001 + 0.000000000 = +1.000000001
+ 1.000000001 + 0.000000001 = +1.000000002
+ 1.000000001 + 0.000000002 = +1.000000003
+ 1.000000001 + 1.000000000 = +2.000000001
+ 1.000000001 + 1.000000001 = +2.000000002
+ 1.000000001 + 1.000000002 = +2.000000003
+ 1.000000001 + 2.000000000 = +3.000000001
+ 1.000000001 + 2.000000001 = +3.000000002
+ 1.000000001 + 2.000000002 = +3.000000003
+====
+ 1.000000001 + -0.000000001 = +1.000000000
+ 1.000000001 + -0.000000002 = +0.999999999
+ 1.000000001 + -1.000000000 = +0.000000001
+ 1.000000001 + -1.000000001 = +0.000000000
+ 1.000000001 + -1.000000002 = -0.000000001
+ 1.000000001 + -2.000000000 = -0.999999999
+ 1.000000001 + -2.000000001 = -1.000000000
+ 1.000000001 + -2.000000002 = -1.000000001
+========
+ 1.000000002 + 0.000000000 = +1.000000002
+ 1.000000002 + 0.000000001 = +1.000000003
+ 1.000000002 + 0.000000002 = +1.000000004
+ 1.000000002 + 1.000000000 = +2.000000002
+ 1.000000002 + 1.000000001 = +2.000000003
+ 1.000000002 + 1.000000002 = +2.000000004
+ 1.000000002 + 2.000000000 = +3.000000002
+ 1.000000002 + 2.000000001 = +3.000000003
+ 1.000000002 + 2.000000002 = +3.000000004
+====
+ 1.000000002 + -0.000000001 = +1.000000001
+ 1.000000002 + -0.000000002 = +1.000000000
+ 1.000000002 + -1.000000000 = +0.000000002
+ 1.000000002 + -1.000000001 = +0.000000001
+ 1.000000002 + -1.000000002 = +0.000000000
+ 1.000000002 + -2.000000000 = -0.999999998
+ 1.000000002 + -2.000000001 = -0.999999999
+ 1.000000002 + -2.000000002 = -1.000000000
+========
+ 2.000000000 + 0.000000000 = +2.000000000
+ 2.000000000 + 0.000000001 = +2.000000001
+ 2.000000000 + 0.000000002 = +2.000000002
+ 2.000000000 + 1.000000000 = +3.000000000
+ 2.000000000 + 1.000000001 = +3.000000001
+ 2.000000000 + 1.000000002 = +3.000000002
+ 2.000000000 + 2.000000000 = +4.000000000
+ 2.000000000 + 2.000000001 = +4.000000001
+ 2.000000000 + 2.000000002 = +4.000000002
+====
+ 2.000000000 + -0.000000001 = +1.999999999
+ 2.000000000 + -0.000000002 = +1.999999998
+ 2.000000000 + -1.000000000 = +1.000000000
+ 2.000000000 + -1.000000001 = +0.999999999
+ 2.000000000 + -1.000000002 = +0.999999998
+ 2.000000000 + -2.000000000 = +0.000000000
+ 2.000000000 + -2.000000001 = -0.000000001
+ 2.000000000 + -2.000000002 = -0.000000002
+========
+ 2.000000001 + 0.000000000 = +2.000000001
+ 2.000000001 + 0.000000001 = +2.000000002
+ 2.000000001 + 0.000000002 = +2.000000003
+ 2.000000001 + 1.000000000 = +3.000000001
+ 2.000000001 + 1.000000001 = +3.000000002
+ 2.000000001 + 1.000000002 = +3.000000003
+ 2.000000001 + 2.000000000 = +4.000000001
+ 2.000000001 + 2.000000001 = +4.000000002
+ 2.000000001 + 2.000000002 = +4.000000003
+====
+ 2.000000001 + -0.000000001 = +2.000000000
+ 2.000000001 + -0.000000002 = +1.999999999
+ 2.000000001 + -1.000000000 = +1.000000001
+ 2.000000001 + -1.000000001 = +1.000000000
+ 2.000000001 + -1.000000002 = +0.999999999
+ 2.000000001 + -2.000000000 = +0.000000001
+ 2.000000001 + -2.000000001 = +0.000000000
+ 2.000000001 + -2.000000002 = -0.000000001
+========
+ 2.000000002 + 0.000000000 = +2.000000002
+ 2.000000002 + 0.000000001 = +2.000000003
+ 2.000000002 + 0.000000002 = +2.000000004
+ 2.000000002 + 1.000000000 = +3.000000002
+ 2.000000002 + 1.000000001 = +3.000000003
+ 2.000000002 + 1.000000002 = +3.000000004
+ 2.000000002 + 2.000000000 = +4.000000002
+ 2.000000002 + 2.000000001 = +4.000000003
+ 2.000000002 + 2.000000002 = +4.000000004
+====
+ 2.000000002 + -0.000000001 = +2.000000001
+ 2.000000002 + -0.000000002 = +2.000000000
+ 2.000000002 + -1.000000000 = +1.000000002
+ 2.000000002 + -1.000000001 = +1.000000001
+ 2.000000002 + -1.000000002 = +1.000000000
+ 2.000000002 + -2.000000000 = +0.000000002
+ 2.000000002 + -2.000000001 = +0.000000001
+ 2.000000002 + -2.000000002 = +0.000000000
+========
+-0.000000001 + 0.000000000 = -0.000000001
+-0.000000001 + 0.000000001 = +0.000000000
+-0.000000001 + 0.000000002 = +0.000000001
+-0.000000001 + 1.000000000 = +0.999999999
+-0.000000001 + 1.000000001 = +1.000000000
+-0.000000001 + 1.000000002 = +1.000000001
+-0.000000001 + 2.000000000 = +1.999999999
+-0.000000001 + 2.000000001 = +2.000000000
+-0.000000001 + 2.000000002 = +2.000000001
+====
+-0.000000001 + -0.000000001 = -0.000000002
+-0.000000001 + -0.000000002 = -0.000000003
+-0.000000001 + -1.000000000 = -1.000000001
+-0.000000001 + -1.000000001 = -1.000000002
+-0.000000001 + -1.000000002 = -1.000000003
+-0.000000001 + -2.000000000 = -2.000000001
+-0.000000001 + -2.000000001 = -2.000000002
+-0.000000001 + -2.000000002 = -2.000000003
+========
+-0.000000002 + 0.000000000 = -0.000000002
+-0.000000002 + 0.000000001 = -0.000000001
+-0.000000002 + 0.000000002 = +0.000000000
+-0.000000002 + 1.000000000 = +0.999999998
+-0.000000002 + 1.000000001 = +0.999999999
+-0.000000002 + 1.000000002 = +1.000000000
+-0.000000002 + 2.000000000 = +1.999999998
+-0.000000002 + 2.000000001 = +1.999999999
+-0.000000002 + 2.000000002 = +2.000000000
+====
+-0.000000002 + -0.000000001 = -0.000000003
+-0.000000002 + -0.000000002 = -0.000000004
+-0.000000002 + -1.000000000 = -1.000000002
+-0.000000002 + -1.000000001 = -1.000000003
+-0.000000002 + -1.000000002 = -1.000000004
+-0.000000002 + -2.000000000 = -2.000000002
+-0.000000002 + -2.000000001 = -2.000000003
+-0.000000002 + -2.000000002 = -2.000000004
+========
+-1.000000000 + 0.000000000 = -1.000000000
+-1.000000000 + 0.000000001 = -0.999999999
+-1.000000000 + 0.000000002 = -0.999999998
+-1.000000000 + 1.000000000 = +0.000000000
+-1.000000000 + 1.000000001 = +0.000000001
+-1.000000000 + 1.000000002 = +0.000000002
+-1.000000000 + 2.000000000 = +1.000000000
+-1.000000000 + 2.000000001 = +1.000000001
+-1.000000000 + 2.000000002 = +1.000000002
+====
+-1.000000000 + -0.000000001 = -1.000000001
+-1.000000000 + -0.000000002 = -1.000000002
+-1.000000000 + -1.000000000 = -2.000000000
+-1.000000000 + -1.000000001 = -2.000000001
+-1.000000000 + -1.000000002 = -2.000000002
+-1.000000000 + -2.000000000 = -3.000000000
+-1.000000000 + -2.000000001 = -3.000000001
+-1.000000000 + -2.000000002 = -3.000000002
+========
+-1.000000001 + 0.000000000 = -1.000000001
+-1.000000001 + 0.000000001 = -1.000000000
+-1.000000001 + 0.000000002 = -0.999999999
+-1.000000001 + 1.000000000 = -0.000000001
+-1.000000001 + 1.000000001 = +0.000000000
+-1.000000001 + 1.000000002 = +0.000000001
+-1.000000001 + 2.000000000 = +0.999999999
+-1.000000001 + 2.000000001 = +1.000000000
+-1.000000001 + 2.000000002 = +1.000000001
+====
+-1.000000001 + -0.000000001 = -1.000000002
+-1.000000001 + -0.000000002 = -1.000000003
+-1.000000001 + -1.000000000 = -2.000000001
+-1.000000001 + -1.000000001 = -2.000000002
+-1.000000001 + -1.000000002 = -2.000000003
+-1.000000001 + -2.000000000 = -3.000000001
+-1.000000001 + -2.000000001 = -3.000000002
+-1.000000001 + -2.000000002 = -3.000000003
+========
+-1.000000002 + 0.000000000 = -1.000000002
+-1.000000002 + 0.000000001 = -1.000000001
+-1.000000002 + 0.000000002 = -1.000000000
+-1.000000002 + 1.000000000 = -0.000000002
+-1.000000002 + 1.000000001 = -0.000000001
+-1.000000002 + 1.000000002 = +0.000000000
+-1.000000002 + 2.000000000 = +0.999999998
+-1.000000002 + 2.000000001 = +0.999999999
+-1.000000002 + 2.000000002 = +1.000000000
+====
+-1.000000002 + -0.000000001 = -1.000000003
+-1.000000002 + -0.000000002 = -1.000000004
+-1.000000002 + -1.000000000 = -2.000000002
+-1.000000002 + -1.000000001 = -2.000000003
+-1.000000002 + -1.000000002 = -2.000000004
+-1.000000002 + -2.000000000 = -3.000000002
+-1.000000002 + -2.000000001 = -3.000000003
+-1.000000002 + -2.000000002 = -3.000000004
+========
+-2.000000000 + 0.000000000 = -2.000000000
+-2.000000000 + 0.000000001 = -1.999999999
+-2.000000000 + 0.000000002 = -1.999999998
+-2.000000000 + 1.000000000 = -1.000000000
+-2.000000000 + 1.000000001 = -0.999999999
+-2.000000000 + 1.000000002 = -0.999999998
+-2.000000000 + 2.000000000 = +0.000000000
+-2.000000000 + 2.000000001 = +0.000000001
+-2.000000000 + 2.000000002 = +0.000000002
+====
+-2.000000000 + -0.000000001 = -2.000000001
+-2.000000000 + -0.000000002 = -2.000000002
+-2.000000000 + -1.000000000 = -3.000000000
+-2.000000000 + -1.000000001 = -3.000000001
+-2.000000000 + -1.000000002 = -3.000000002
+-2.000000000 + -2.000000000 = -4.000000000
+-2.000000000 + -2.000000001 = -4.000000001
+-2.000000000 + -2.000000002 = -4.000000002
+========
+-2.000000001 + 0.000000000 = -2.000000001
+-2.000000001 + 0.000000001 = -2.000000000
+-2.000000001 + 0.000000002 = -1.999999999
+-2.000000001 + 1.000000000 = -1.000000001
+-2.000000001 + 1.000000001 = -1.000000000
+-2.000000001 + 1.000000002 = -0.999999999
+-2.000000001 + 2.000000000 = -0.000000001
+-2.000000001 + 2.000000001 = +0.000000000
+-2.000000001 + 2.000000002 = +0.000000001
+====
+-2.000000001 + -0.000000001 = -2.000000002
+-2.000000001 + -0.000000002 = -2.000000003
+-2.000000001 + -1.000000000 = -3.000000001
+-2.000000001 + -1.000000001 = -3.000000002
+-2.000000001 + -1.000000002 = -3.000000003
+-2.000000001 + -2.000000000 = -4.000000001
+-2.000000001 + -2.000000001 = -4.000000002
+-2.000000001 + -2.000000002 = -4.000000003
+========
+-2.000000002 + 0.000000000 = -2.000000002
+-2.000000002 + 0.000000001 = -2.000000001
+-2.000000002 + 0.000000002 = -2.000000000
+-2.000000002 + 1.000000000 = -1.000000002
+-2.000000002 + 1.000000001 = -1.000000001
+-2.000000002 + 1.000000002 = -1.000000000
+-2.000000002 + 2.000000000 = -0.000000002
+-2.000000002 + 2.000000001 = -0.000000001
+-2.000000002 + 2.000000002 = +0.000000000
+====
+-2.000000002 + -0.000000001 = -2.000000003
+-2.000000002 + -0.000000002 = -2.000000004
+-2.000000002 + -1.000000000 = -3.000000002
+-2.000000002 + -1.000000001 = -3.000000003
+-2.000000002 + -1.000000002 = -3.000000004
+-2.000000002 + -2.000000000 = -4.000000002
+-2.000000002 + -2.000000001 = -4.000000003
+-2.000000002 + -2.000000002 = -4.000000004
diff --git a/ext/date/tests/time/duration/methods/add_32.phpt b/ext/date/tests/time/duration/methods/add_32.phpt
new file mode 100644
index 000000000000..f436d0a63ffa
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/add_32.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::add() (32 bit variation)
+--SKIPIF--
+
+--FILE--
+add($b);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+Time\TimeException: The maximum representable range is 2_147_483_647 seconds (roughly 68 years)
diff --git a/ext/date/tests/time/duration/methods/add_64.phpt b/ext/date/tests/time/duration/methods/add_64.phpt
new file mode 100644
index 000000000000..98448409bf19
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/add_64.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::add() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+add($b);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
diff --git a/ext/date/tests/time/duration/methods/compare.phpt b/ext/date/tests/time/duration/methods/compare.phpt
new file mode 100644
index 000000000000..488a39c2fc16
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/compare.phpt
@@ -0,0 +1,369 @@
+--TEST--
+Time\Duration::absolute()
+--FILE--
+')), " ", f($b, pad: false), PHP_EOL;
+ }
+}
+
+?>
+--EXPECT--
+========
++0.000000000 = +0.000000000
++0.000000000 < +0.000000001
++0.000000000 < +0.000000002
++0.000000000 < +1.000000000
++0.000000000 < +1.000000001
++0.000000000 < +1.000000002
++0.000000000 < +2.000000000
++0.000000000 < +2.000000001
++0.000000000 < +2.000000002
+====
++0.000000000 > -0.000000001
++0.000000000 > -0.000000002
++0.000000000 > -1.000000000
++0.000000000 > -1.000000001
++0.000000000 > -1.000000002
++0.000000000 > -2.000000000
++0.000000000 > -2.000000001
++0.000000000 > -2.000000002
+========
++0.000000001 > +0.000000000
++0.000000001 = +0.000000001
++0.000000001 < +0.000000002
++0.000000001 < +1.000000000
++0.000000001 < +1.000000001
++0.000000001 < +1.000000002
++0.000000001 < +2.000000000
++0.000000001 < +2.000000001
++0.000000001 < +2.000000002
+====
++0.000000001 > -0.000000001
++0.000000001 > -0.000000002
++0.000000001 > -1.000000000
++0.000000001 > -1.000000001
++0.000000001 > -1.000000002
++0.000000001 > -2.000000000
++0.000000001 > -2.000000001
++0.000000001 > -2.000000002
+========
++0.000000002 > +0.000000000
++0.000000002 > +0.000000001
++0.000000002 = +0.000000002
++0.000000002 < +1.000000000
++0.000000002 < +1.000000001
++0.000000002 < +1.000000002
++0.000000002 < +2.000000000
++0.000000002 < +2.000000001
++0.000000002 < +2.000000002
+====
++0.000000002 > -0.000000001
++0.000000002 > -0.000000002
++0.000000002 > -1.000000000
++0.000000002 > -1.000000001
++0.000000002 > -1.000000002
++0.000000002 > -2.000000000
++0.000000002 > -2.000000001
++0.000000002 > -2.000000002
+========
++1.000000000 > +0.000000000
++1.000000000 > +0.000000001
++1.000000000 > +0.000000002
++1.000000000 = +1.000000000
++1.000000000 < +1.000000001
++1.000000000 < +1.000000002
++1.000000000 < +2.000000000
++1.000000000 < +2.000000001
++1.000000000 < +2.000000002
+====
++1.000000000 > -0.000000001
++1.000000000 > -0.000000002
++1.000000000 > -1.000000000
++1.000000000 > -1.000000001
++1.000000000 > -1.000000002
++1.000000000 > -2.000000000
++1.000000000 > -2.000000001
++1.000000000 > -2.000000002
+========
++1.000000001 > +0.000000000
++1.000000001 > +0.000000001
++1.000000001 > +0.000000002
++1.000000001 > +1.000000000
++1.000000001 = +1.000000001
++1.000000001 < +1.000000002
++1.000000001 < +2.000000000
++1.000000001 < +2.000000001
++1.000000001 < +2.000000002
+====
++1.000000001 > -0.000000001
++1.000000001 > -0.000000002
++1.000000001 > -1.000000000
++1.000000001 > -1.000000001
++1.000000001 > -1.000000002
++1.000000001 > -2.000000000
++1.000000001 > -2.000000001
++1.000000001 > -2.000000002
+========
++1.000000002 > +0.000000000
++1.000000002 > +0.000000001
++1.000000002 > +0.000000002
++1.000000002 > +1.000000000
++1.000000002 > +1.000000001
++1.000000002 = +1.000000002
++1.000000002 < +2.000000000
++1.000000002 < +2.000000001
++1.000000002 < +2.000000002
+====
++1.000000002 > -0.000000001
++1.000000002 > -0.000000002
++1.000000002 > -1.000000000
++1.000000002 > -1.000000001
++1.000000002 > -1.000000002
++1.000000002 > -2.000000000
++1.000000002 > -2.000000001
++1.000000002 > -2.000000002
+========
++2.000000000 > +0.000000000
++2.000000000 > +0.000000001
++2.000000000 > +0.000000002
++2.000000000 > +1.000000000
++2.000000000 > +1.000000001
++2.000000000 > +1.000000002
++2.000000000 = +2.000000000
++2.000000000 < +2.000000001
++2.000000000 < +2.000000002
+====
++2.000000000 > -0.000000001
++2.000000000 > -0.000000002
++2.000000000 > -1.000000000
++2.000000000 > -1.000000001
++2.000000000 > -1.000000002
++2.000000000 > -2.000000000
++2.000000000 > -2.000000001
++2.000000000 > -2.000000002
+========
++2.000000001 > +0.000000000
++2.000000001 > +0.000000001
++2.000000001 > +0.000000002
++2.000000001 > +1.000000000
++2.000000001 > +1.000000001
++2.000000001 > +1.000000002
++2.000000001 > +2.000000000
++2.000000001 = +2.000000001
++2.000000001 < +2.000000002
+====
++2.000000001 > -0.000000001
++2.000000001 > -0.000000002
++2.000000001 > -1.000000000
++2.000000001 > -1.000000001
++2.000000001 > -1.000000002
++2.000000001 > -2.000000000
++2.000000001 > -2.000000001
++2.000000001 > -2.000000002
+========
++2.000000002 > +0.000000000
++2.000000002 > +0.000000001
++2.000000002 > +0.000000002
++2.000000002 > +1.000000000
++2.000000002 > +1.000000001
++2.000000002 > +1.000000002
++2.000000002 > +2.000000000
++2.000000002 > +2.000000001
++2.000000002 = +2.000000002
+====
++2.000000002 > -0.000000001
++2.000000002 > -0.000000002
++2.000000002 > -1.000000000
++2.000000002 > -1.000000001
++2.000000002 > -1.000000002
++2.000000002 > -2.000000000
++2.000000002 > -2.000000001
++2.000000002 > -2.000000002
+========
+-0.000000001 < +0.000000000
+-0.000000001 < +0.000000001
+-0.000000001 < +0.000000002
+-0.000000001 < +1.000000000
+-0.000000001 < +1.000000001
+-0.000000001 < +1.000000002
+-0.000000001 < +2.000000000
+-0.000000001 < +2.000000001
+-0.000000001 < +2.000000002
+====
+-0.000000001 = -0.000000001
+-0.000000001 > -0.000000002
+-0.000000001 > -1.000000000
+-0.000000001 > -1.000000001
+-0.000000001 > -1.000000002
+-0.000000001 > -2.000000000
+-0.000000001 > -2.000000001
+-0.000000001 > -2.000000002
+========
+-0.000000002 < +0.000000000
+-0.000000002 < +0.000000001
+-0.000000002 < +0.000000002
+-0.000000002 < +1.000000000
+-0.000000002 < +1.000000001
+-0.000000002 < +1.000000002
+-0.000000002 < +2.000000000
+-0.000000002 < +2.000000001
+-0.000000002 < +2.000000002
+====
+-0.000000002 < -0.000000001
+-0.000000002 = -0.000000002
+-0.000000002 > -1.000000000
+-0.000000002 > -1.000000001
+-0.000000002 > -1.000000002
+-0.000000002 > -2.000000000
+-0.000000002 > -2.000000001
+-0.000000002 > -2.000000002
+========
+-1.000000000 < +0.000000000
+-1.000000000 < +0.000000001
+-1.000000000 < +0.000000002
+-1.000000000 < +1.000000000
+-1.000000000 < +1.000000001
+-1.000000000 < +1.000000002
+-1.000000000 < +2.000000000
+-1.000000000 < +2.000000001
+-1.000000000 < +2.000000002
+====
+-1.000000000 < -0.000000001
+-1.000000000 < -0.000000002
+-1.000000000 = -1.000000000
+-1.000000000 > -1.000000001
+-1.000000000 > -1.000000002
+-1.000000000 > -2.000000000
+-1.000000000 > -2.000000001
+-1.000000000 > -2.000000002
+========
+-1.000000001 < +0.000000000
+-1.000000001 < +0.000000001
+-1.000000001 < +0.000000002
+-1.000000001 < +1.000000000
+-1.000000001 < +1.000000001
+-1.000000001 < +1.000000002
+-1.000000001 < +2.000000000
+-1.000000001 < +2.000000001
+-1.000000001 < +2.000000002
+====
+-1.000000001 < -0.000000001
+-1.000000001 < -0.000000002
+-1.000000001 < -1.000000000
+-1.000000001 = -1.000000001
+-1.000000001 > -1.000000002
+-1.000000001 > -2.000000000
+-1.000000001 > -2.000000001
+-1.000000001 > -2.000000002
+========
+-1.000000002 < +0.000000000
+-1.000000002 < +0.000000001
+-1.000000002 < +0.000000002
+-1.000000002 < +1.000000000
+-1.000000002 < +1.000000001
+-1.000000002 < +1.000000002
+-1.000000002 < +2.000000000
+-1.000000002 < +2.000000001
+-1.000000002 < +2.000000002
+====
+-1.000000002 < -0.000000001
+-1.000000002 < -0.000000002
+-1.000000002 < -1.000000000
+-1.000000002 < -1.000000001
+-1.000000002 = -1.000000002
+-1.000000002 > -2.000000000
+-1.000000002 > -2.000000001
+-1.000000002 > -2.000000002
+========
+-2.000000000 < +0.000000000
+-2.000000000 < +0.000000001
+-2.000000000 < +0.000000002
+-2.000000000 < +1.000000000
+-2.000000000 < +1.000000001
+-2.000000000 < +1.000000002
+-2.000000000 < +2.000000000
+-2.000000000 < +2.000000001
+-2.000000000 < +2.000000002
+====
+-2.000000000 < -0.000000001
+-2.000000000 < -0.000000002
+-2.000000000 < -1.000000000
+-2.000000000 < -1.000000001
+-2.000000000 < -1.000000002
+-2.000000000 = -2.000000000
+-2.000000000 > -2.000000001
+-2.000000000 > -2.000000002
+========
+-2.000000001 < +0.000000000
+-2.000000001 < +0.000000001
+-2.000000001 < +0.000000002
+-2.000000001 < +1.000000000
+-2.000000001 < +1.000000001
+-2.000000001 < +1.000000002
+-2.000000001 < +2.000000000
+-2.000000001 < +2.000000001
+-2.000000001 < +2.000000002
+====
+-2.000000001 < -0.000000001
+-2.000000001 < -0.000000002
+-2.000000001 < -1.000000000
+-2.000000001 < -1.000000001
+-2.000000001 < -1.000000002
+-2.000000001 < -2.000000000
+-2.000000001 = -2.000000001
+-2.000000001 > -2.000000002
+========
+-2.000000002 < +0.000000000
+-2.000000002 < +0.000000001
+-2.000000002 < +0.000000002
+-2.000000002 < +1.000000000
+-2.000000002 < +1.000000001
+-2.000000002 < +1.000000002
+-2.000000002 < +2.000000000
+-2.000000002 < +2.000000001
+-2.000000002 < +2.000000002
+====
+-2.000000002 < -0.000000001
+-2.000000002 < -0.000000002
+-2.000000002 < -1.000000000
+-2.000000002 < -1.000000001
+-2.000000002 < -1.000000002
+-2.000000002 < -2.000000000
+-2.000000002 < -2.000000001
+-2.000000002 = -2.000000002
diff --git a/ext/date/tests/time/duration/methods/divideBy.phpt b/ext/date/tests/time/duration/methods/divideBy.phpt
new file mode 100644
index 000000000000..440107d33ed4
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/divideBy.phpt
@@ -0,0 +1,133 @@
+--TEST--
+Time\Duration::divideBy()
+--FILE--
+divideBy($divisor);
+ echo f($d), " / ", sprintf("%10d", $divisor), " = ", f($result), PHP_EOL;
+
+ if (PHP_INT_SIZE != 4 && (intdiv(as_int($d), $divisor) !== as_int($result))) {
+ throw new \Exception('Verification failed');
+ }
+ }
+}
+
+echo "========", PHP_EOL;
+
+$d = Time\Duration::fromSeconds(1, 0);
+try {
+ $d->divideBy(0);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+========
+ +0.000000000 / 1 = +0.000000000
+ +0.000000000 / 2 = +0.000000000
+ +0.000000000 / 3 = +0.000000000
+ +0.000000000 / 4 = +0.000000000
+ +0.000000000 / 999999999 = +0.000000000
+ +0.000000000 / 1000000000 = +0.000000000
+ +0.000000000 / 2147483647 = +0.000000000
+========
+ +0.000000001 / 1 = +0.000000001
+ +0.000000001 / 2 = +0.000000000
+ +0.000000001 / 3 = +0.000000000
+ +0.000000001 / 4 = +0.000000000
+ +0.000000001 / 999999999 = +0.000000000
+ +0.000000001 / 1000000000 = +0.000000000
+ +0.000000001 / 2147483647 = +0.000000000
+========
+ +0.999999999 / 1 = +0.999999999
+ +0.999999999 / 2 = +0.499999999
+ +0.999999999 / 3 = +0.333333333
+ +0.999999999 / 4 = +0.249999999
+ +0.999999999 / 999999999 = +0.000000001
+ +0.999999999 / 1000000000 = +0.000000000
+ +0.999999999 / 2147483647 = +0.000000000
+========
+ +1.000000000 / 1 = +1.000000000
+ +1.000000000 / 2 = +0.500000000
+ +1.000000000 / 3 = +0.333333333
+ +1.000000000 / 4 = +0.250000000
+ +1.000000000 / 999999999 = +0.000000001
+ +1.000000000 / 1000000000 = +0.000000001
+ +1.000000000 / 2147483647 = +0.000000000
+========
++2147483647.999999999 / 1 = +2147483647.999999999
++2147483647.999999999 / 2 = +1073741823.999999999
++2147483647.999999999 / 3 = +715827882.666666666
++2147483647.999999999 / 4 = +536870911.999999999
++2147483647.999999999 / 999999999 = +2.147483650
++2147483647.999999999 / 1000000000 = +2.147483647
++2147483647.999999999 / 2147483647 = +1.000000000
+========
+ -0.000000001 / 1 = -0.000000001
+ -0.000000001 / 2 = +0.000000000
+ -0.000000001 / 3 = +0.000000000
+ -0.000000001 / 4 = +0.000000000
+ -0.000000001 / 999999999 = +0.000000000
+ -0.000000001 / 1000000000 = +0.000000000
+ -0.000000001 / 2147483647 = +0.000000000
+========
+ -0.999999999 / 1 = -0.999999999
+ -0.999999999 / 2 = -0.499999999
+ -0.999999999 / 3 = -0.333333333
+ -0.999999999 / 4 = -0.249999999
+ -0.999999999 / 999999999 = -0.000000001
+ -0.999999999 / 1000000000 = +0.000000000
+ -0.999999999 / 2147483647 = +0.000000000
+========
+ -1.000000000 / 1 = -1.000000000
+ -1.000000000 / 2 = -0.500000000
+ -1.000000000 / 3 = -0.333333333
+ -1.000000000 / 4 = -0.250000000
+ -1.000000000 / 999999999 = -0.000000001
+ -1.000000000 / 1000000000 = -0.000000001
+ -1.000000000 / 2147483647 = +0.000000000
+========
+-2147483647.999999999 / 1 = -2147483647.999999999
+-2147483647.999999999 / 2 = -1073741823.999999999
+-2147483647.999999999 / 3 = -715827882.666666666
+-2147483647.999999999 / 4 = -536870911.999999999
+-2147483647.999999999 / 999999999 = -2.147483650
+-2147483647.999999999 / 1000000000 = -2.147483647
+-2147483647.999999999 / 2147483647 = -1.000000000
+========
+DivisionByZeroError: Division by zero
diff --git a/ext/date/tests/time/duration/methods/divideBy_64.phpt b/ext/date/tests/time/duration/methods/divideBy_64.phpt
new file mode 100644
index 000000000000..21c54538f40b
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/divideBy_64.phpt
@@ -0,0 +1,78 @@
+--TEST--
+Time\Duration::divideBy() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+divideBy($factor)), PHP_EOL;
+ }
+}
+
+?>
+--EXPECT--
+========
++2147483648.000000000 / 1 = +2147483648.000000000
++2147483648.000000000 / 2 = +1073741824.000000000
++2147483648.000000000 / 3 = +715827882.666666666
++2147483648.000000000 / 4 = +536870912.000000000
++2147483648.000000000 / 999999999 = +2.147483650
++2147483648.000000000 / 1000000000 = +2.147483648
++2147483648.000000000 / 9223372035999999999 = +0.000000000
+========
++9223372035.999999999 / 1 = +9223372035.999999999
++9223372035.999999999 / 2 = +4611686017.999999999
++9223372035.999999999 / 3 = +3074457345.333333333
++9223372035.999999999 / 4 = +2305843008.999999999
++9223372035.999999999 / 999999999 = +9.223372045
++9223372035.999999999 / 1000000000 = +9.223372035
++9223372035.999999999 / 9223372035999999999 = +0.000000001
+========
+-2147483648.000000000 / 1 = -2147483648.000000000
+-2147483648.000000000 / 2 = -1073741824.000000000
+-2147483648.000000000 / 3 = -715827882.666666666
+-2147483648.000000000 / 4 = -536870912.000000000
+-2147483648.000000000 / 999999999 = -2.147483650
+-2147483648.000000000 / 1000000000 = -2.147483648
+-2147483648.000000000 / 9223372035999999999 = +0.000000000
+========
+-9223372035.999999999 / 1 = -9223372035.999999999
+-9223372035.999999999 / 2 = -4611686017.999999999
+-9223372035.999999999 / 3 = -3074457345.333333333
+-9223372035.999999999 / 4 = -2305843008.999999999
+-9223372035.999999999 / 999999999 = -9.223372045
+-9223372035.999999999 / 1000000000 = -9.223372035
+-9223372035.999999999 / 9223372035999999999 = -0.000000001
diff --git a/ext/date/tests/time/duration/methods/fromHours.phpt b/ext/date/tests/time/duration/methods/fromHours.phpt
new file mode 100644
index 000000000000..658288036433
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromHours.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::fromHours()
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+ +0.000000000
+ +3600.000000000
++2147482800.000000000
+ValueError: Time\Duration::fromHours(): Argument #1 ($hours) must be greater than or equal to 0
diff --git a/ext/date/tests/time/duration/methods/fromHours_32.phpt b/ext/date/tests/time/duration/methods/fromHours_32.phpt
new file mode 100644
index 000000000000..998ab5d9beaf
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromHours_32.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::fromHours() (32 bit variation)
+--SKIPIF--
+
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECTF--
++2147482800.000000000
+Time\TimeException: The maximum representable range is 2_147_483_647 seconds (roughly 68 years)
diff --git a/ext/date/tests/time/duration/methods/fromHours_64.phpt b/ext/date/tests/time/duration/methods/fromHours_64.phpt
new file mode 100644
index 000000000000..719da0e88e20
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromHours_64.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::fromHours() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
++9223369200.000000000
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
diff --git a/ext/date/tests/time/duration/methods/fromIso8601DurationString.phpt b/ext/date/tests/time/duration/methods/fromIso8601DurationString.phpt
new file mode 100644
index 000000000000..109a1dd1307a
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromIso8601DurationString.phpt
@@ -0,0 +1,74 @@
+--TEST--
+Time\Duration::fromIso8601DurationString()
+--FILE--
+getMessage(), PHP_EOL;
+ }
+}
+
+?>
+--EXPECT--
+PT0S : +0.000000000
+PT1S : +1.000000000
+PT60S : +60.000000000
+PT2147483647S : +2147483647.000000000
+PT0.1S : Time\TimeException: The ISO 8601 duration string could not be parsed
+PT0M : +0.000000000
+PT1M : +60.000000000
+PT1M1S : +61.000000000
+PT1M60S : +120.000000000
+PT0H : +0.000000000
+PT1H : +3600.000000000
+PT1H1M : +3660.000000000
+PT1H1M1S : +3661.000000000
+PT1H60M : +7200.000000000
+PT1H60M60S : +7260.000000000
+ : Time\TimeException: The ISO 8601 duration string could not be parsed
+P : Time\TimeException: The ISO 8601 duration string could not be parsed
+PT : Time\TimeException: The ISO 8601 duration string could not be parsed
+P1D : Time\TimeException: The ISO 8601 duration string may only contain the time (T) aspect
+P1W : Time\TimeException: The ISO 8601 duration string may only contain the time (T) aspect
+P1M : Time\TimeException: The ISO 8601 duration string may only contain the time (T) aspect
+P1DT0S : Time\TimeException: The ISO 8601 duration string may only contain the time (T) aspect
+2000-01-01T00:00:00Z : Time\TimeException: The ISO 8601 duration string is missing the period (P) aspect
+2000-01-01T00:00:00Z/PT1H: Time\TimeException: The ISO 8601 duration string may only contain the period (P) aspect
diff --git a/ext/date/tests/time/duration/methods/fromIso8601DurationString_64.phpt b/ext/date/tests/time/duration/methods/fromIso8601DurationString_64.phpt
new file mode 100644
index 000000000000..04ee27db4660
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromIso8601DurationString_64.phpt
@@ -0,0 +1,32 @@
+--TEST--
+Time\Duration::fromIso8601DurationString() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+getMessage(), PHP_EOL;
+ }
+}
+
+?>
+--EXPECT--
+PT2147483648S : +2147483648.000000000
+PT9223372035S : +9223372035.000000000
+PT9223372036S : Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
diff --git a/ext/date/tests/time/duration/methods/fromMicroseconds.phpt b/ext/date/tests/time/duration/methods/fromMicroseconds.phpt
new file mode 100644
index 000000000000..aef4092b9094
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromMicroseconds.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Time\Duration::fromMicroseconds()
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+ +0.000000000
+ +0.000001000
+ +0.999999000
+ +1.000000000
+ +2147.483647000
+ValueError: Time\Duration::fromMicroseconds(): Argument #1 ($microseconds) must be greater than or equal to 0
diff --git a/ext/date/tests/time/duration/methods/fromMicroseconds_64.phpt b/ext/date/tests/time/duration/methods/fromMicroseconds_64.phpt
new file mode 100644
index 000000000000..84f317425a44
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromMicroseconds_64.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::fromMicroseconds() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
++9223372035.999999000
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
diff --git a/ext/date/tests/time/duration/methods/fromMilliseconds.phpt b/ext/date/tests/time/duration/methods/fromMilliseconds.phpt
new file mode 100644
index 000000000000..d63f20535b4b
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromMilliseconds.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Time\Duration::fromMilliseconds()
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+ +0.000000000
+ +0.001000000
+ +0.999000000
+ +1.000000000
+ +2147483.647000000
+ValueError: Time\Duration::fromMilliseconds(): Argument #1 ($milliseconds) must be greater than or equal to 0
diff --git a/ext/date/tests/time/duration/methods/fromMilliseconds_64.phpt b/ext/date/tests/time/duration/methods/fromMilliseconds_64.phpt
new file mode 100644
index 000000000000..4ed7250fb38a
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromMilliseconds_64.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::fromMilliseconds() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
++9223372035.999000000
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
diff --git a/ext/date/tests/time/duration/methods/fromMinutes.phpt b/ext/date/tests/time/duration/methods/fromMinutes.phpt
new file mode 100644
index 000000000000..7674ea95f54c
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromMinutes.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::fromMinutes()
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+ +0.000000000
+ +60.000000000
++2147483640.000000000
+ValueError: Time\Duration::fromMinutes(): Argument #1 ($minutes) must be greater than or equal to 0
diff --git a/ext/date/tests/time/duration/methods/fromMinutes_32.phpt b/ext/date/tests/time/duration/methods/fromMinutes_32.phpt
new file mode 100644
index 000000000000..705823165df6
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromMinutes_32.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::fromMinutes() (32 bit variation)
+--SKIPIF--
+
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECTF--
++2147483640.000000000
+Time\TimeException: The maximum representable range is 2_147_483_647 seconds (roughly 68 years)
diff --git a/ext/date/tests/time/duration/methods/fromMinutes_64.phpt b/ext/date/tests/time/duration/methods/fromMinutes_64.phpt
new file mode 100644
index 000000000000..4b3eaf4ad26c
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromMinutes_64.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::fromMinutes() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
++9223372020.000000000
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
diff --git a/ext/date/tests/time/duration/methods/fromNanoseconds.phpt b/ext/date/tests/time/duration/methods/fromNanoseconds.phpt
new file mode 100644
index 000000000000..7b425d2eb562
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromNanoseconds.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Time\Duration::fromNanoseconds()
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+ +0.000000000
+ +0.000000001
+ +0.999999999
+ +1.000000000
+ +2.147483647
+ValueError: Time\Duration::fromNanoseconds(): Argument #1 ($nanoseconds) must be greater than or equal to 0
diff --git a/ext/date/tests/time/duration/methods/fromNanoseconds_64.phpt b/ext/date/tests/time/duration/methods/fromNanoseconds_64.phpt
new file mode 100644
index 000000000000..e68adc28e4a3
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromNanoseconds_64.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::fromNanoseconds() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
++9223372035.999999999
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
diff --git a/ext/date/tests/time/duration/methods/fromSeconds.phpt b/ext/date/tests/time/duration/methods/fromSeconds.phpt
new file mode 100644
index 000000000000..8cd26ce4c725
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromSeconds.phpt
@@ -0,0 +1,46 @@
+--TEST--
+Time\Duration::fromSeconds()
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+try {
+ Time\Duration::fromSeconds(0, -1);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+try {
+ Time\Duration::fromSeconds(0, 1000000000);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+ +0.000000000
+ +1.000000000
++2147483647.000000000
+ +0.000000000
+ +0.000000001
+ +1.000000001
++2147483647.999999999
+ValueError: Time\Duration::fromSeconds(): Argument #1 ($seconds) must be greater than or equal to 0
+ValueError: Time\Duration::fromSeconds(): Argument #2 ($nanoseconds) must be greater than or equal to 0
+ValueError: Time\Duration::fromSeconds(): Argument #2 ($nanoseconds) must be less than 1_000_000_000
diff --git a/ext/date/tests/time/duration/methods/fromSeconds_64.phpt b/ext/date/tests/time/duration/methods/fromSeconds_64.phpt
new file mode 100644
index 000000000000..2deed85ec0e8
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/fromSeconds_64.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Time\Duration::fromSeconds() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
++9223372035.000000000
++9223372035.999999999
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
diff --git a/ext/date/tests/time/duration/methods/multiplyBy.phpt b/ext/date/tests/time/duration/methods/multiplyBy.phpt
new file mode 100644
index 000000000000..70b374d28c2b
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/multiplyBy.phpt
@@ -0,0 +1,206 @@
+--TEST--
+Time\Duration::multiplyBy()
+--FILE--
+multiplyBy($factor);
+ echo f($d), " * ", sprintf("%10d", $factor), " = ", f($result), PHP_EOL;
+
+ if (PHP_INT_SIZE != 4 && (as_int($d) * $factor !== as_int($result))) {
+ throw new \Exception('Verification failed');
+ }
+ }
+}
+
+echo "========", PHP_EOL;
+$d = Time\Duration::fromSeconds(0, 1);
+$factor = 2_147_483_647;
+$result = $d->multiplyBy($factor);
+echo f($d), " * ", sprintf("%10d", $factor), " = ", f($result), PHP_EOL;
+
+echo "========", PHP_EOL;
+$d = Time\Duration::fromSeconds(1, 0);
+$factor = 2_147_483_647;
+$result = $d->multiplyBy($factor);
+echo f($d), " * ", sprintf("%10d", $factor), " = ", f($result), PHP_EOL;
+
+?>
+--EXPECT--
+========
+ +0.000000000 * 0 = +0.000000000
+ +0.000000000 * 1 = +0.000000000
+ +0.000000000 * 2 = +0.000000000
+ +0.000000000 * 3 = +0.000000000
+ +0.000000000 * 4 = +0.000000000
+ +0.000000000 * 999999999 = +0.000000000
+ +0.000000000 * 1000000000 = +0.000000000
+========
+ +0.000000001 * 0 = +0.000000000
+ +0.000000001 * 1 = +0.000000001
+ +0.000000001 * 2 = +0.000000002
+ +0.000000001 * 3 = +0.000000003
+ +0.000000001 * 4 = +0.000000004
+ +0.000000001 * 999999999 = +0.999999999
+ +0.000000001 * 1000000000 = +1.000000000
+========
+ +0.000000002 * 0 = +0.000000000
+ +0.000000002 * 1 = +0.000000002
+ +0.000000002 * 2 = +0.000000004
+ +0.000000002 * 3 = +0.000000006
+ +0.000000002 * 4 = +0.000000008
+ +0.000000002 * 999999999 = +1.999999998
+ +0.000000002 * 1000000000 = +2.000000000
+========
+ +1.000000000 * 0 = +0.000000000
+ +1.000000000 * 1 = +1.000000000
+ +1.000000000 * 2 = +2.000000000
+ +1.000000000 * 3 = +3.000000000
+ +1.000000000 * 4 = +4.000000000
+ +1.000000000 * 999999999 = +999999999.000000000
+ +1.000000000 * 1000000000 = +1000000000.000000000
+========
+ +1.000000001 * 0 = +0.000000000
+ +1.000000001 * 1 = +1.000000001
+ +1.000000001 * 2 = +2.000000002
+ +1.000000001 * 3 = +3.000000003
+ +1.000000001 * 4 = +4.000000004
+ +1.000000001 * 999999999 = +999999999.999999999
+ +1.000000001 * 1000000000 = +1000000001.000000000
+========
+ +1.000000002 * 0 = +0.000000000
+ +1.000000002 * 1 = +1.000000002
+ +1.000000002 * 2 = +2.000000004
+ +1.000000002 * 3 = +3.000000006
+ +1.000000002 * 4 = +4.000000008
+ +1.000000002 * 999999999 = +1000000000.999999998
+ +1.000000002 * 1000000000 = +1000000002.000000000
+========
+ +2.000000000 * 0 = +0.000000000
+ +2.000000000 * 1 = +2.000000000
+ +2.000000000 * 2 = +4.000000000
+ +2.000000000 * 3 = +6.000000000
+ +2.000000000 * 4 = +8.000000000
+ +2.000000000 * 999999999 = +1999999998.000000000
+ +2.000000000 * 1000000000 = +2000000000.000000000
+========
+ +2.000000001 * 0 = +0.000000000
+ +2.000000001 * 1 = +2.000000001
+ +2.000000001 * 2 = +4.000000002
+ +2.000000001 * 3 = +6.000000003
+ +2.000000001 * 4 = +8.000000004
+ +2.000000001 * 999999999 = +1999999998.999999999
+ +2.000000001 * 1000000000 = +2000000001.000000000
+========
+ +2.000000002 * 0 = +0.000000000
+ +2.000000002 * 1 = +2.000000002
+ +2.000000002 * 2 = +4.000000004
+ +2.000000002 * 3 = +6.000000006
+ +2.000000002 * 4 = +8.000000008
+ +2.000000002 * 999999999 = +1999999999.999999998
+ +2.000000002 * 1000000000 = +2000000002.000000000
+========
+ -0.000000001 * 0 = +0.000000000
+ -0.000000001 * 1 = -0.000000001
+ -0.000000001 * 2 = -0.000000002
+ -0.000000001 * 3 = -0.000000003
+ -0.000000001 * 4 = -0.000000004
+ -0.000000001 * 999999999 = -0.999999999
+ -0.000000001 * 1000000000 = -1.000000000
+========
+ -0.000000002 * 0 = +0.000000000
+ -0.000000002 * 1 = -0.000000002
+ -0.000000002 * 2 = -0.000000004
+ -0.000000002 * 3 = -0.000000006
+ -0.000000002 * 4 = -0.000000008
+ -0.000000002 * 999999999 = -1.999999998
+ -0.000000002 * 1000000000 = -2.000000000
+========
+ -1.000000000 * 0 = +0.000000000
+ -1.000000000 * 1 = -1.000000000
+ -1.000000000 * 2 = -2.000000000
+ -1.000000000 * 3 = -3.000000000
+ -1.000000000 * 4 = -4.000000000
+ -1.000000000 * 999999999 = -999999999.000000000
+ -1.000000000 * 1000000000 = -1000000000.000000000
+========
+ -1.000000001 * 0 = +0.000000000
+ -1.000000001 * 1 = -1.000000001
+ -1.000000001 * 2 = -2.000000002
+ -1.000000001 * 3 = -3.000000003
+ -1.000000001 * 4 = -4.000000004
+ -1.000000001 * 999999999 = -999999999.999999999
+ -1.000000001 * 1000000000 = -1000000001.000000000
+========
+ -1.000000002 * 0 = +0.000000000
+ -1.000000002 * 1 = -1.000000002
+ -1.000000002 * 2 = -2.000000004
+ -1.000000002 * 3 = -3.000000006
+ -1.000000002 * 4 = -4.000000008
+ -1.000000002 * 999999999 = -1000000000.999999998
+ -1.000000002 * 1000000000 = -1000000002.000000000
+========
+ -2.000000000 * 0 = +0.000000000
+ -2.000000000 * 1 = -2.000000000
+ -2.000000000 * 2 = -4.000000000
+ -2.000000000 * 3 = -6.000000000
+ -2.000000000 * 4 = -8.000000000
+ -2.000000000 * 999999999 = -1999999998.000000000
+ -2.000000000 * 1000000000 = -2000000000.000000000
+========
+ -2.000000001 * 0 = +0.000000000
+ -2.000000001 * 1 = -2.000000001
+ -2.000000001 * 2 = -4.000000002
+ -2.000000001 * 3 = -6.000000003
+ -2.000000001 * 4 = -8.000000004
+ -2.000000001 * 999999999 = -1999999998.999999999
+ -2.000000001 * 1000000000 = -2000000001.000000000
+========
+ -2.000000002 * 0 = +0.000000000
+ -2.000000002 * 1 = -2.000000002
+ -2.000000002 * 2 = -4.000000004
+ -2.000000002 * 3 = -6.000000006
+ -2.000000002 * 4 = -8.000000008
+ -2.000000002 * 999999999 = -1999999999.999999998
+ -2.000000002 * 1000000000 = -2000000002.000000000
+========
+ +0.000000001 * 2147483647 = +2.147483647
+========
+ +1.000000000 * 2147483647 = +2147483647.000000000
diff --git a/ext/date/tests/time/duration/methods/multiplyBy_32.phpt b/ext/date/tests/time/duration/methods/multiplyBy_32.phpt
new file mode 100644
index 000000000000..7a1cbcb56065
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/multiplyBy_32.phpt
@@ -0,0 +1,55 @@
+--TEST--
+Time\Duration::multiplyBy() (32 bit variation)
+--SKIPIF--
+
+--FILE--
+multiplyBy(1)), PHP_EOL;
+
+try {
+ $d->multiplyBy(2);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo "====", PHP_EOL;
+
+$d = Time\Duration::fromSeconds(1_073_741_823, 999999999);
+
+echo f($d->multiplyBy(2)), PHP_EOL;
+
+try {
+ $d->multiplyBy(3);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo "====", PHP_EOL;
+
+$d = Time\Duration::fromSeconds(715_827_882, 666666666);
+
+echo f($d->multiplyBy(3)), PHP_EOL;
+
+try {
+ $d->multiplyBy(4);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
++2147483647.999999999
+Time\TimeException: The maximum representable range is 2_147_483_647 seconds (roughly 68 years)
+====
++2147483647.999999998
+Time\TimeException: The maximum representable range is 2_147_483_647 seconds (roughly 68 years)
+====
++2147483647.999999998
+Time\TimeException: The maximum representable range is 2_147_483_647 seconds (roughly 68 years)
diff --git a/ext/date/tests/time/duration/methods/multiplyBy_64.phpt b/ext/date/tests/time/duration/methods/multiplyBy_64.phpt
new file mode 100644
index 000000000000..04b220fe2dbc
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/multiplyBy_64.phpt
@@ -0,0 +1,70 @@
+--TEST--
+Time\Duration::multiplyBy() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+multiplyBy(1)), PHP_EOL;
+
+try {
+ $d->multiplyBy(2);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo "====", PHP_EOL;
+
+$d = Time\Duration::fromSeconds(4_611_686_017, 999999999);
+
+echo f($d->multiplyBy(2)), PHP_EOL;
+
+try {
+ $d->multiplyBy(3);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo "====", PHP_EOL;
+
+$d = Time\Duration::fromSeconds(3_074_457_345, 333333333);
+
+echo f($d->multiplyBy(3)), PHP_EOL;
+
+try {
+ $d->multiplyBy(4);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo "====", PHP_EOL;
+
+$d = Time\Duration::fromSeconds(0, 1);
+
+echo f($d->multiplyBy(9_223_372_035_999999999)), PHP_EOL;
+
+try {
+ $d->multiplyBy(9_223_372_036_000000000);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
++9223372035.999999999
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
+====
++9223372035.999999998
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
+====
++9223372035.999999999
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
+====
++9223372035.999999999
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
diff --git a/ext/date/tests/time/duration/methods/negate.phpt b/ext/date/tests/time/duration/methods/negate.phpt
new file mode 100644
index 000000000000..ce156cd20374
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/negate.phpt
@@ -0,0 +1,29 @@
+--TEST--
+Time\Duration::negate()
+--FILE--
+negate()), PHP_EOL;
+echo f(Time\Duration::fromSeconds(0, 0)->negate()->negate()), PHP_EOL;
+
+echo f(Time\Duration::fromSeconds(1, 0)->negate()), PHP_EOL;
+echo f(Time\Duration::fromSeconds(1, 0)->negate()->negate()), PHP_EOL;
+
+echo f(Time\Duration::fromSeconds(0, 1)->negate()), PHP_EOL;
+echo f(Time\Duration::fromSeconds(0, 1)->negate()->negate()), PHP_EOL;
+
+echo f(Time\Duration::fromSeconds(1, 1)->negate()), PHP_EOL;
+echo f(Time\Duration::fromSeconds(1, 1)->negate()->negate()), PHP_EOL;
+
+?>
+--EXPECT--
+ +0.000000000
+ +0.000000000
+ -1.000000000
+ +1.000000000
+ -0.000000001
+ +0.000000001
+ -1.000000001
+ +1.000000001
diff --git a/ext/date/tests/time/duration/methods/sub.phpt b/ext/date/tests/time/duration/methods/sub.phpt
new file mode 100644
index 000000000000..5552a249d9bf
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/sub.phpt
@@ -0,0 +1,371 @@
+--TEST--
+Time\Duration::sub()
+--FILE--
+sub($b);
+ echo f($a, pad: false, plus_sign: false), " - ", f($b, pad: false, plus_sign: false), " = ", f($result, pad: false), PHP_EOL;
+ if (PHP_INT_SIZE != 4 && (as_int($a) - as_int($b) !== as_int($result))) {
+ throw new \Exception('Verification failed');
+ }
+ }
+}
+
+?>
+--EXPECT--
+========
+ 0.000000000 - 0.000000000 = +0.000000000
+ 0.000000000 - 0.000000001 = -0.000000001
+ 0.000000000 - 0.000000002 = -0.000000002
+ 0.000000000 - 1.000000000 = -1.000000000
+ 0.000000000 - 1.000000001 = -1.000000001
+ 0.000000000 - 1.000000002 = -1.000000002
+ 0.000000000 - 2.000000000 = -2.000000000
+ 0.000000000 - 2.000000001 = -2.000000001
+ 0.000000000 - 2.000000002 = -2.000000002
+====
+ 0.000000000 - -0.000000001 = +0.000000001
+ 0.000000000 - -0.000000002 = +0.000000002
+ 0.000000000 - -1.000000000 = +1.000000000
+ 0.000000000 - -1.000000001 = +1.000000001
+ 0.000000000 - -1.000000002 = +1.000000002
+ 0.000000000 - -2.000000000 = +2.000000000
+ 0.000000000 - -2.000000001 = +2.000000001
+ 0.000000000 - -2.000000002 = +2.000000002
+========
+ 0.000000001 - 0.000000000 = +0.000000001
+ 0.000000001 - 0.000000001 = +0.000000000
+ 0.000000001 - 0.000000002 = -0.000000001
+ 0.000000001 - 1.000000000 = -0.999999999
+ 0.000000001 - 1.000000001 = -1.000000000
+ 0.000000001 - 1.000000002 = -1.000000001
+ 0.000000001 - 2.000000000 = -1.999999999
+ 0.000000001 - 2.000000001 = -2.000000000
+ 0.000000001 - 2.000000002 = -2.000000001
+====
+ 0.000000001 - -0.000000001 = +0.000000002
+ 0.000000001 - -0.000000002 = +0.000000003
+ 0.000000001 - -1.000000000 = +1.000000001
+ 0.000000001 - -1.000000001 = +1.000000002
+ 0.000000001 - -1.000000002 = +1.000000003
+ 0.000000001 - -2.000000000 = +2.000000001
+ 0.000000001 - -2.000000001 = +2.000000002
+ 0.000000001 - -2.000000002 = +2.000000003
+========
+ 0.000000002 - 0.000000000 = +0.000000002
+ 0.000000002 - 0.000000001 = +0.000000001
+ 0.000000002 - 0.000000002 = +0.000000000
+ 0.000000002 - 1.000000000 = -0.999999998
+ 0.000000002 - 1.000000001 = -0.999999999
+ 0.000000002 - 1.000000002 = -1.000000000
+ 0.000000002 - 2.000000000 = -1.999999998
+ 0.000000002 - 2.000000001 = -1.999999999
+ 0.000000002 - 2.000000002 = -2.000000000
+====
+ 0.000000002 - -0.000000001 = +0.000000003
+ 0.000000002 - -0.000000002 = +0.000000004
+ 0.000000002 - -1.000000000 = +1.000000002
+ 0.000000002 - -1.000000001 = +1.000000003
+ 0.000000002 - -1.000000002 = +1.000000004
+ 0.000000002 - -2.000000000 = +2.000000002
+ 0.000000002 - -2.000000001 = +2.000000003
+ 0.000000002 - -2.000000002 = +2.000000004
+========
+ 1.000000000 - 0.000000000 = +1.000000000
+ 1.000000000 - 0.000000001 = +0.999999999
+ 1.000000000 - 0.000000002 = +0.999999998
+ 1.000000000 - 1.000000000 = +0.000000000
+ 1.000000000 - 1.000000001 = -0.000000001
+ 1.000000000 - 1.000000002 = -0.000000002
+ 1.000000000 - 2.000000000 = -1.000000000
+ 1.000000000 - 2.000000001 = -1.000000001
+ 1.000000000 - 2.000000002 = -1.000000002
+====
+ 1.000000000 - -0.000000001 = +1.000000001
+ 1.000000000 - -0.000000002 = +1.000000002
+ 1.000000000 - -1.000000000 = +2.000000000
+ 1.000000000 - -1.000000001 = +2.000000001
+ 1.000000000 - -1.000000002 = +2.000000002
+ 1.000000000 - -2.000000000 = +3.000000000
+ 1.000000000 - -2.000000001 = +3.000000001
+ 1.000000000 - -2.000000002 = +3.000000002
+========
+ 1.000000001 - 0.000000000 = +1.000000001
+ 1.000000001 - 0.000000001 = +1.000000000
+ 1.000000001 - 0.000000002 = +0.999999999
+ 1.000000001 - 1.000000000 = +0.000000001
+ 1.000000001 - 1.000000001 = +0.000000000
+ 1.000000001 - 1.000000002 = -0.000000001
+ 1.000000001 - 2.000000000 = -0.999999999
+ 1.000000001 - 2.000000001 = -1.000000000
+ 1.000000001 - 2.000000002 = -1.000000001
+====
+ 1.000000001 - -0.000000001 = +1.000000002
+ 1.000000001 - -0.000000002 = +1.000000003
+ 1.000000001 - -1.000000000 = +2.000000001
+ 1.000000001 - -1.000000001 = +2.000000002
+ 1.000000001 - -1.000000002 = +2.000000003
+ 1.000000001 - -2.000000000 = +3.000000001
+ 1.000000001 - -2.000000001 = +3.000000002
+ 1.000000001 - -2.000000002 = +3.000000003
+========
+ 1.000000002 - 0.000000000 = +1.000000002
+ 1.000000002 - 0.000000001 = +1.000000001
+ 1.000000002 - 0.000000002 = +1.000000000
+ 1.000000002 - 1.000000000 = +0.000000002
+ 1.000000002 - 1.000000001 = +0.000000001
+ 1.000000002 - 1.000000002 = +0.000000000
+ 1.000000002 - 2.000000000 = -0.999999998
+ 1.000000002 - 2.000000001 = -0.999999999
+ 1.000000002 - 2.000000002 = -1.000000000
+====
+ 1.000000002 - -0.000000001 = +1.000000003
+ 1.000000002 - -0.000000002 = +1.000000004
+ 1.000000002 - -1.000000000 = +2.000000002
+ 1.000000002 - -1.000000001 = +2.000000003
+ 1.000000002 - -1.000000002 = +2.000000004
+ 1.000000002 - -2.000000000 = +3.000000002
+ 1.000000002 - -2.000000001 = +3.000000003
+ 1.000000002 - -2.000000002 = +3.000000004
+========
+ 2.000000000 - 0.000000000 = +2.000000000
+ 2.000000000 - 0.000000001 = +1.999999999
+ 2.000000000 - 0.000000002 = +1.999999998
+ 2.000000000 - 1.000000000 = +1.000000000
+ 2.000000000 - 1.000000001 = +0.999999999
+ 2.000000000 - 1.000000002 = +0.999999998
+ 2.000000000 - 2.000000000 = +0.000000000
+ 2.000000000 - 2.000000001 = -0.000000001
+ 2.000000000 - 2.000000002 = -0.000000002
+====
+ 2.000000000 - -0.000000001 = +2.000000001
+ 2.000000000 - -0.000000002 = +2.000000002
+ 2.000000000 - -1.000000000 = +3.000000000
+ 2.000000000 - -1.000000001 = +3.000000001
+ 2.000000000 - -1.000000002 = +3.000000002
+ 2.000000000 - -2.000000000 = +4.000000000
+ 2.000000000 - -2.000000001 = +4.000000001
+ 2.000000000 - -2.000000002 = +4.000000002
+========
+ 2.000000001 - 0.000000000 = +2.000000001
+ 2.000000001 - 0.000000001 = +2.000000000
+ 2.000000001 - 0.000000002 = +1.999999999
+ 2.000000001 - 1.000000000 = +1.000000001
+ 2.000000001 - 1.000000001 = +1.000000000
+ 2.000000001 - 1.000000002 = +0.999999999
+ 2.000000001 - 2.000000000 = +0.000000001
+ 2.000000001 - 2.000000001 = +0.000000000
+ 2.000000001 - 2.000000002 = -0.000000001
+====
+ 2.000000001 - -0.000000001 = +2.000000002
+ 2.000000001 - -0.000000002 = +2.000000003
+ 2.000000001 - -1.000000000 = +3.000000001
+ 2.000000001 - -1.000000001 = +3.000000002
+ 2.000000001 - -1.000000002 = +3.000000003
+ 2.000000001 - -2.000000000 = +4.000000001
+ 2.000000001 - -2.000000001 = +4.000000002
+ 2.000000001 - -2.000000002 = +4.000000003
+========
+ 2.000000002 - 0.000000000 = +2.000000002
+ 2.000000002 - 0.000000001 = +2.000000001
+ 2.000000002 - 0.000000002 = +2.000000000
+ 2.000000002 - 1.000000000 = +1.000000002
+ 2.000000002 - 1.000000001 = +1.000000001
+ 2.000000002 - 1.000000002 = +1.000000000
+ 2.000000002 - 2.000000000 = +0.000000002
+ 2.000000002 - 2.000000001 = +0.000000001
+ 2.000000002 - 2.000000002 = +0.000000000
+====
+ 2.000000002 - -0.000000001 = +2.000000003
+ 2.000000002 - -0.000000002 = +2.000000004
+ 2.000000002 - -1.000000000 = +3.000000002
+ 2.000000002 - -1.000000001 = +3.000000003
+ 2.000000002 - -1.000000002 = +3.000000004
+ 2.000000002 - -2.000000000 = +4.000000002
+ 2.000000002 - -2.000000001 = +4.000000003
+ 2.000000002 - -2.000000002 = +4.000000004
+========
+-0.000000001 - 0.000000000 = -0.000000001
+-0.000000001 - 0.000000001 = -0.000000002
+-0.000000001 - 0.000000002 = -0.000000003
+-0.000000001 - 1.000000000 = -1.000000001
+-0.000000001 - 1.000000001 = -1.000000002
+-0.000000001 - 1.000000002 = -1.000000003
+-0.000000001 - 2.000000000 = -2.000000001
+-0.000000001 - 2.000000001 = -2.000000002
+-0.000000001 - 2.000000002 = -2.000000003
+====
+-0.000000001 - -0.000000001 = +0.000000000
+-0.000000001 - -0.000000002 = +0.000000001
+-0.000000001 - -1.000000000 = +0.999999999
+-0.000000001 - -1.000000001 = +1.000000000
+-0.000000001 - -1.000000002 = +1.000000001
+-0.000000001 - -2.000000000 = +1.999999999
+-0.000000001 - -2.000000001 = +2.000000000
+-0.000000001 - -2.000000002 = +2.000000001
+========
+-0.000000002 - 0.000000000 = -0.000000002
+-0.000000002 - 0.000000001 = -0.000000003
+-0.000000002 - 0.000000002 = -0.000000004
+-0.000000002 - 1.000000000 = -1.000000002
+-0.000000002 - 1.000000001 = -1.000000003
+-0.000000002 - 1.000000002 = -1.000000004
+-0.000000002 - 2.000000000 = -2.000000002
+-0.000000002 - 2.000000001 = -2.000000003
+-0.000000002 - 2.000000002 = -2.000000004
+====
+-0.000000002 - -0.000000001 = -0.000000001
+-0.000000002 - -0.000000002 = +0.000000000
+-0.000000002 - -1.000000000 = +0.999999998
+-0.000000002 - -1.000000001 = +0.999999999
+-0.000000002 - -1.000000002 = +1.000000000
+-0.000000002 - -2.000000000 = +1.999999998
+-0.000000002 - -2.000000001 = +1.999999999
+-0.000000002 - -2.000000002 = +2.000000000
+========
+-1.000000000 - 0.000000000 = -1.000000000
+-1.000000000 - 0.000000001 = -1.000000001
+-1.000000000 - 0.000000002 = -1.000000002
+-1.000000000 - 1.000000000 = -2.000000000
+-1.000000000 - 1.000000001 = -2.000000001
+-1.000000000 - 1.000000002 = -2.000000002
+-1.000000000 - 2.000000000 = -3.000000000
+-1.000000000 - 2.000000001 = -3.000000001
+-1.000000000 - 2.000000002 = -3.000000002
+====
+-1.000000000 - -0.000000001 = -0.999999999
+-1.000000000 - -0.000000002 = -0.999999998
+-1.000000000 - -1.000000000 = +0.000000000
+-1.000000000 - -1.000000001 = +0.000000001
+-1.000000000 - -1.000000002 = +0.000000002
+-1.000000000 - -2.000000000 = +1.000000000
+-1.000000000 - -2.000000001 = +1.000000001
+-1.000000000 - -2.000000002 = +1.000000002
+========
+-1.000000001 - 0.000000000 = -1.000000001
+-1.000000001 - 0.000000001 = -1.000000002
+-1.000000001 - 0.000000002 = -1.000000003
+-1.000000001 - 1.000000000 = -2.000000001
+-1.000000001 - 1.000000001 = -2.000000002
+-1.000000001 - 1.000000002 = -2.000000003
+-1.000000001 - 2.000000000 = -3.000000001
+-1.000000001 - 2.000000001 = -3.000000002
+-1.000000001 - 2.000000002 = -3.000000003
+====
+-1.000000001 - -0.000000001 = -1.000000000
+-1.000000001 - -0.000000002 = -0.999999999
+-1.000000001 - -1.000000000 = -0.000000001
+-1.000000001 - -1.000000001 = +0.000000000
+-1.000000001 - -1.000000002 = +0.000000001
+-1.000000001 - -2.000000000 = +0.999999999
+-1.000000001 - -2.000000001 = +1.000000000
+-1.000000001 - -2.000000002 = +1.000000001
+========
+-1.000000002 - 0.000000000 = -1.000000002
+-1.000000002 - 0.000000001 = -1.000000003
+-1.000000002 - 0.000000002 = -1.000000004
+-1.000000002 - 1.000000000 = -2.000000002
+-1.000000002 - 1.000000001 = -2.000000003
+-1.000000002 - 1.000000002 = -2.000000004
+-1.000000002 - 2.000000000 = -3.000000002
+-1.000000002 - 2.000000001 = -3.000000003
+-1.000000002 - 2.000000002 = -3.000000004
+====
+-1.000000002 - -0.000000001 = -1.000000001
+-1.000000002 - -0.000000002 = -1.000000000
+-1.000000002 - -1.000000000 = -0.000000002
+-1.000000002 - -1.000000001 = -0.000000001
+-1.000000002 - -1.000000002 = +0.000000000
+-1.000000002 - -2.000000000 = +0.999999998
+-1.000000002 - -2.000000001 = +0.999999999
+-1.000000002 - -2.000000002 = +1.000000000
+========
+-2.000000000 - 0.000000000 = -2.000000000
+-2.000000000 - 0.000000001 = -2.000000001
+-2.000000000 - 0.000000002 = -2.000000002
+-2.000000000 - 1.000000000 = -3.000000000
+-2.000000000 - 1.000000001 = -3.000000001
+-2.000000000 - 1.000000002 = -3.000000002
+-2.000000000 - 2.000000000 = -4.000000000
+-2.000000000 - 2.000000001 = -4.000000001
+-2.000000000 - 2.000000002 = -4.000000002
+====
+-2.000000000 - -0.000000001 = -1.999999999
+-2.000000000 - -0.000000002 = -1.999999998
+-2.000000000 - -1.000000000 = -1.000000000
+-2.000000000 - -1.000000001 = -0.999999999
+-2.000000000 - -1.000000002 = -0.999999998
+-2.000000000 - -2.000000000 = +0.000000000
+-2.000000000 - -2.000000001 = +0.000000001
+-2.000000000 - -2.000000002 = +0.000000002
+========
+-2.000000001 - 0.000000000 = -2.000000001
+-2.000000001 - 0.000000001 = -2.000000002
+-2.000000001 - 0.000000002 = -2.000000003
+-2.000000001 - 1.000000000 = -3.000000001
+-2.000000001 - 1.000000001 = -3.000000002
+-2.000000001 - 1.000000002 = -3.000000003
+-2.000000001 - 2.000000000 = -4.000000001
+-2.000000001 - 2.000000001 = -4.000000002
+-2.000000001 - 2.000000002 = -4.000000003
+====
+-2.000000001 - -0.000000001 = -2.000000000
+-2.000000001 - -0.000000002 = -1.999999999
+-2.000000001 - -1.000000000 = -1.000000001
+-2.000000001 - -1.000000001 = -1.000000000
+-2.000000001 - -1.000000002 = -0.999999999
+-2.000000001 - -2.000000000 = -0.000000001
+-2.000000001 - -2.000000001 = +0.000000000
+-2.000000001 - -2.000000002 = +0.000000001
+========
+-2.000000002 - 0.000000000 = -2.000000002
+-2.000000002 - 0.000000001 = -2.000000003
+-2.000000002 - 0.000000002 = -2.000000004
+-2.000000002 - 1.000000000 = -3.000000002
+-2.000000002 - 1.000000001 = -3.000000003
+-2.000000002 - 1.000000002 = -3.000000004
+-2.000000002 - 2.000000000 = -4.000000002
+-2.000000002 - 2.000000001 = -4.000000003
+-2.000000002 - 2.000000002 = -4.000000004
+====
+-2.000000002 - -0.000000001 = -2.000000001
+-2.000000002 - -0.000000002 = -2.000000000
+-2.000000002 - -1.000000000 = -1.000000002
+-2.000000002 - -1.000000001 = -1.000000001
+-2.000000002 - -1.000000002 = -1.000000000
+-2.000000002 - -2.000000000 = -0.000000002
+-2.000000002 - -2.000000001 = -0.000000001
+-2.000000002 - -2.000000002 = +0.000000000
diff --git a/ext/date/tests/time/duration/methods/sub_32.phpt b/ext/date/tests/time/duration/methods/sub_32.phpt
new file mode 100644
index 000000000000..298b2bfe4953
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/sub_32.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::sub() (32 bit variation)
+--SKIPIF--
+
+--FILE--
+negate();
+$b = Time\Duration::fromSeconds(2_147_483_647, 999999999);
+
+try {
+ $a->sub($b);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+Time\TimeException: The maximum representable range is 2_147_483_647 seconds (roughly 68 years)
diff --git a/ext/date/tests/time/duration/methods/sub_64.phpt b/ext/date/tests/time/duration/methods/sub_64.phpt
new file mode 100644
index 000000000000..c8f8fac503bf
--- /dev/null
+++ b/ext/date/tests/time/duration/methods/sub_64.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Time\Duration::sub() (64 bit variation)
+--SKIPIF--
+
+--FILE--
+negate();
+$b = Time\Duration::fromSeconds(9_223_372_035, 999999999);
+
+try {
+ $a->sub($b);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+Time\TimeException: The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
diff --git a/ext/date/tests/time/duration/new.phpt b/ext/date/tests/time/duration/new.phpt
new file mode 100644
index 000000000000..312752374e73
--- /dev/null
+++ b/ext/date/tests/time/duration/new.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Time\Duration: new
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+try {
+ (new ReflectionClass(Time\Duration::class))->newInstance();
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+try {
+ (new ReflectionClass(Time\Duration::class))->newInstanceWithoutConstructor();
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+Error: Call to private Time\Duration::__construct() from global scope
+ReflectionException: Access to non-public constructor of class Time\Duration
+ReflectionException: Class Time\Duration is an internal class marked as final that cannot be instantiated without invoking its constructor
diff --git a/ext/date/tests/time/duration/readonly.phpt b/ext/date/tests/time/duration/readonly.phpt
new file mode 100644
index 000000000000..ca527fe43c59
--- /dev/null
+++ b/ext/date/tests/time/duration/readonly.phpt
@@ -0,0 +1,127 @@
+--TEST--
+Time\Duration: readonly
+--FILE--
+seconds = 2;
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo f($d), PHP_EOL;
+
+try {
+ (new ReflectionProperty($d, 'seconds'))->setValue($d, 2);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo f($d), PHP_EOL;
+
+try {
+ (new ReflectionProperty($d, 'seconds'))->setRawValue($d, 2);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo f($d), PHP_EOL;
+
+try {
+ (new ReflectionProperty($d, 'seconds'))->setRawValueWithoutLazyInitialization($d, 2);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo f($d), PHP_EOL;
+
+echo "====", PHP_EOL;
+
+/* Recheck after cloning to verify that "modification allowed during cloning" has no lasting effect. */
+
+$d = clone($d);
+
+try {
+ $d->seconds = 2;
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo f($d), PHP_EOL;
+
+try {
+ (new ReflectionProperty($d, 'seconds'))->setValue($d, 2);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo f($d), PHP_EOL;
+
+try {
+ (new ReflectionProperty($d, 'seconds'))->setRawValue($d, 2);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo f($d), PHP_EOL;
+
+try {
+ (new ReflectionProperty($d, 'seconds'))->setRawValueWithoutLazyInitialization($d, 2);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo f($d), PHP_EOL;
+
+echo "====", PHP_EOL;
+
+try {
+ clone($d, ['seconds' => 2]);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo "====", PHP_EOL;
+
+var_dump((new ReflectionProperty($d, 'seconds'))->isWritable(null, $d));
+
+echo "====", PHP_EOL;
+
+try {
+ (new ReflectionMethod($d, '__construct'))->invoke($d);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+echo f($d), PHP_EOL;
+
+?>
+--EXPECT--
+Error: Cannot modify readonly property Time\Duration::$seconds
+ +1.000000000
+Error: Cannot modify readonly property Time\Duration::$seconds
+ +1.000000000
+Error: Cannot modify readonly property Time\Duration::$seconds
+ +1.000000000
+Error: Cannot modify readonly property Time\Duration::$seconds
+ +1.000000000
+====
+Error: Cannot modify readonly property Time\Duration::$seconds
+ +1.000000000
+Error: Cannot modify readonly property Time\Duration::$seconds
+ +1.000000000
+Error: Cannot modify readonly property Time\Duration::$seconds
+ +1.000000000
+Error: Cannot modify readonly property Time\Duration::$seconds
+ +1.000000000
+====
+Error: Cannot modify protected(set) readonly property Time\Duration::$seconds from global scope
+====
+bool(false)
+====
+Error: Cannot directly construct Time\Duration, use Time\Duration::from*() methods instead
+ +1.000000000
diff --git a/ext/date/tests/time/duration/z_param_date_time_duration.phpt b/ext/date/tests/time/duration/z_param_date_time_duration.phpt
new file mode 100644
index 000000000000..23c2fe080aae
--- /dev/null
+++ b/ext/date/tests/time/duration/z_param_date_time_duration.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Time\Duration: Z_PARAM_DATE_TIME_DURATION() correctly aborts parameter parsing
+--FILE--
+getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+TypeError: Time\Duration::compare(): Argument #1 ($a) must be of type Time\Duration, int given
diff --git a/ext/date/time.stub.php b/ext/date/time.stub.php
new file mode 100644
index 000000000000..b9d0a01b39d6
--- /dev/null
+++ b/ext/date/time.stub.php
@@ -0,0 +1,80 @@
+. |
+ | |
+ | SPDX-License-Identifier: BSD-3-Clause |
+ +----------------------------------------------------------------------+
+ | Authors: Derick Rethans |
+ | Tim Düsterhus |
+ +----------------------------------------------------------------------+
+ */
+
+#include "php.h"
+#include "Zend/zend_exceptions.h"
+
+#include "php_date.h"
+#include "php_time.h"
+
+#define NANOS_IN_SEC 1000000000
+#define NANOS_IN_MICRO 1000
+#define MICROS_IN_SEC 1000000
+#define NANOS_IN_MILLI 1000000
+#define MILLIS_IN_SEC 1000
+
+ZEND_STATIC_ASSERT(NANOS_IN_MICRO * MICROS_IN_SEC == NANOS_IN_SEC, "");
+ZEND_STATIC_ASSERT(NANOS_IN_MILLI * MILLIS_IN_SEC == NANOS_IN_SEC, "");
+
+#define Z_PARAM_ULONG(l) { \
+ zend_long __##l; \
+ Z_PARAM_LONG(__##l); \
+ if (__##l < 0) { \
+ zend_argument_value_error(_i, "must be greater than or equal to 0"); \
+ _error_code = ZPP_ERROR_FAILURE; \
+ break; \
+ } \
+ l = __##l; \
+ }
+
+ZEND_COLD static void throw_out_of_range_exception(void)
+{
+#if SIZEOF_ZEND_LONG != 4
+ zend_throw_exception(php_date_ce_time_timeexception, "The maximum representable range is 9_223_372_035 seconds (roughly 292 years)", 0);
+#else
+ zend_throw_exception(php_date_ce_time_timeexception, "The maximum representable range is 2_147_483_647 seconds (roughly 68 years)", 0);
+#endif
+}
+
+ZEND_COLD static void throw_timelib_error(int error)
+{
+ switch (error) {
+ case TIMELIB_ERROR_SECONDS_OUT_OF_RANGE:
+ throw_out_of_range_exception();
+ break;
+ case TIMELIB_ERROR_DIVISION_BY_ZERO:
+ zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Division by zero");
+ break;
+ case TIMELIB_ERROR_ISO8601_DURATION_PARSE_FAILURE:
+ case TIMELIB_ERROR_DURATION_MISSING_PERIOD:
+ case TIMELIB_ERROR_DURATION_ONLY_PERIOD_ALLOWED:
+ case TIMELIB_ERROR_DURATION_DAYS_FOUND:
+ zend_throw_exception(php_date_ce_time_timeexception, timelib_get_error_message(error), 0);
+ break;
+ default:
+ /* This should be unreachable in practice. */
+ zend_throw_exception_ex(php_date_ce_time_timeexception, 0, "Failed to create a Time\\Duration: %s", timelib_get_error_message(error));
+ break;
+ }
+}
+
+static inline php_date_time_duration *create_duration_shell(zval *target)
+{
+ object_init_ex(target, php_date_ce_time_duration);
+
+ return Z_DATE_TIME_DURATION_P(target);
+}
+
+ZEND_ATTRIBUTE_NODISCARD static inline zend_result sync_properties(php_date_time_duration *object)
+{
+ if (
+ /* Check if the duration would overflow the $seconds property. */
+ object->duration.seconds > ((uint64_t)ZEND_LONG_MAX)
+ /* This constraint is an explicit part of PHP's API: It is the maximum $seconds
+ * value that allows storing the entire duration as a single int64_t counting
+ * nanoseconds, which might be desirable in the future when userland `int` is
+ * consistently 64 bits.
+ *
+ * While it is currently also enforced by timelib, this might change
+ * in a future version of timelib, thus we also enforce it manually. */
+ || object->duration.seconds > UINT64_C(9223372035)
+ ) {
+ throw_out_of_range_exception();
+ return FAILURE;
+ }
+
+ ZEND_ASSERT(Z_ISUNDEF_P(OBJ_PROP_NUM(&object->std, 0)));
+ ZEND_ASSERT(Z_ISUNDEF_P(OBJ_PROP_NUM(&object->std, 1)));
+ ZEND_ASSERT(Z_ISUNDEF_P(OBJ_PROP_NUM(&object->std, 2)));
+
+ ZVAL_LONG(OBJ_PROP_NUM(&object->std, 0), object->duration.seconds);
+ Z_PROP_FLAG_P(OBJ_PROP_NUM(&object->std, 0)) &= ~(IS_PROP_UNINIT|IS_PROP_REINITABLE);
+ ZVAL_LONG(OBJ_PROP_NUM(&object->std, 1), object->duration.nanoseconds);
+ Z_PROP_FLAG_P(OBJ_PROP_NUM(&object->std, 1)) &= ~(IS_PROP_UNINIT|IS_PROP_REINITABLE);
+ ZVAL_BOOL(OBJ_PROP_NUM(&object->std, 2), object->duration.negative);
+ Z_PROP_FLAG_P(OBJ_PROP_NUM(&object->std, 2)) &= ~(IS_PROP_UNINIT|IS_PROP_REINITABLE);
+
+ return SUCCESS;
+}
+
+ZEND_ATTRIBUTE_NODISCARD static zend_result create_duration(zval *target, zend_ulong seconds, zend_ulong nanoseconds)
+{
+ ZEND_ASSERT(nanoseconds < NANOS_IN_SEC);
+
+ if (EXPECTED(DATEG(duration_cache))) {
+ php_date_time_duration *cached = php_date_time_duration_from_obj(DATEG(duration_cache));
+ ZEND_ASSERT(!cached->duration.negative);
+
+ if (cached->duration.seconds == seconds && cached->duration.nanoseconds == nanoseconds) {
+ ZVAL_OBJ_COPY(target, &cached->std);
+ return SUCCESS;
+ }
+ }
+
+ php_date_time_duration *obj = create_duration_shell(target);
+
+ int error = timelib_duration_ctor_static(&obj->duration, seconds, nanoseconds, /* negative */ false);
+ if (error != TIMELIB_ERROR_NO_ERROR) {
+ throw_timelib_error(error);
+ return FAILURE;
+ }
+
+ if (sync_properties(obj) == FAILURE) {
+ return FAILURE;
+ }
+
+ if (DATEG(duration_cache)) {
+ zend_object_release(DATEG(duration_cache));
+ }
+ GC_ADDREF(&obj->std);
+ DATEG(duration_cache) = &obj->std;
+
+ return SUCCESS;
+}
+
+PHP_METHOD(Time_Duration, __construct)
+{
+ zend_throw_error(NULL, "Cannot directly construct Time\\Duration, use Time\\Duration::from*() methods instead");
+}
+
+PHP_METHOD(Time_Duration, fromSeconds)
+{
+ zend_ulong seconds;
+ zend_ulong nanoseconds = 0;
+
+ ZEND_PARSE_PARAMETERS_START(1, 2)
+ Z_PARAM_ULONG(seconds);
+ Z_PARAM_OPTIONAL;
+ Z_PARAM_ULONG(nanoseconds);
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (nanoseconds >= NANOS_IN_SEC) {
+ zend_argument_value_error(2, "must be less than 1_000_000_000");
+ RETURN_THROWS();
+ }
+
+ if (create_duration(return_value, seconds, nanoseconds) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, fromNanoseconds)
+{
+ zend_ulong nanoseconds;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_ULONG(nanoseconds);
+ ZEND_PARSE_PARAMETERS_END();
+
+ zend_ulong seconds = nanoseconds / NANOS_IN_SEC;
+ nanoseconds %= NANOS_IN_SEC;
+
+ if (create_duration(return_value, seconds, nanoseconds) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, fromMicroseconds)
+{
+ zend_ulong microseconds;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_ULONG(microseconds);
+ ZEND_PARSE_PARAMETERS_END();
+
+ zend_ulong seconds = microseconds / MICROS_IN_SEC;
+ zend_ulong nanoseconds = (microseconds % MICROS_IN_SEC) * NANOS_IN_MICRO;
+
+ if (create_duration(return_value, seconds, nanoseconds) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, fromMilliseconds)
+{
+ zend_ulong milliseconds;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_ULONG(milliseconds);
+ ZEND_PARSE_PARAMETERS_END();
+
+ zend_ulong seconds = milliseconds / MILLIS_IN_SEC;
+ zend_ulong nanoseconds = (milliseconds % MILLIS_IN_SEC) * NANOS_IN_MILLI;
+
+ if (create_duration(return_value, seconds, nanoseconds) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, fromMinutes)
+{
+ zend_ulong minutes;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_ULONG(minutes);
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (minutes > (ZEND_ULONG_MAX / 60)) {
+ throw_out_of_range_exception();
+ RETURN_THROWS();
+ }
+
+ if (create_duration(return_value, minutes * 60, /* nanoseconds */ 0) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, fromHours)
+{
+ zend_ulong hours;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_ULONG(hours);
+ ZEND_PARSE_PARAMETERS_END();
+
+ if (hours > (ZEND_ULONG_MAX / 3600)) {
+ throw_out_of_range_exception();
+ RETURN_THROWS();
+ }
+
+ if (create_duration(return_value, hours * 3600, /* nanoseconds */ 0) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, fromIso8601DurationString)
+{
+ zend_string *specification;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_STR(specification);
+ ZEND_PARSE_PARAMETERS_END();
+
+ int error;
+ timelib_duration *d = timelib_duration_create_from_iso8601string(ZSTR_VAL(specification), &error);
+ if (error != TIMELIB_ERROR_NO_ERROR) {
+ throw_timelib_error(error);
+ RETURN_THROWS();
+ }
+
+ php_date_time_duration *new = create_duration_shell(return_value);
+ new->duration = *d;
+ timelib_duration_dtor(d);
+
+ if (sync_properties(new) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, negate)
+{
+ const php_date_time_duration *original = Z_DATE_TIME_DURATION_P(ZEND_THIS);
+
+ ZEND_PARSE_PARAMETERS_NONE();
+
+ php_date_time_duration *new = create_duration_shell(return_value);
+
+ int error = timelib_duration_negate_static(&new->duration, &original->duration);
+ if (error != TIMELIB_ERROR_NO_ERROR) {
+ throw_timelib_error(error);
+ RETURN_THROWS();
+ }
+
+ if (sync_properties(new) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, absolute)
+{
+ const php_date_time_duration *original = Z_DATE_TIME_DURATION_P(ZEND_THIS);
+
+ ZEND_PARSE_PARAMETERS_NONE();
+
+ if (!original->duration.negative) {
+ RETURN_COPY(ZEND_THIS);
+ }
+
+ if (create_duration(return_value, original->duration.seconds, original->duration.nanoseconds) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, add)
+{
+ const php_date_time_duration *original = Z_DATE_TIME_DURATION_P(ZEND_THIS);
+
+ const php_date_time_duration *additional;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_DATE_TIME_DURATION(additional);
+ ZEND_PARSE_PARAMETERS_END();
+
+ php_date_time_duration *new = create_duration_shell(return_value);
+
+ int error = timelib_duration_add_static(&new->duration, &original->duration, &additional->duration);
+ if (error != TIMELIB_ERROR_NO_ERROR) {
+ throw_timelib_error(error);
+ RETURN_THROWS();
+ }
+
+ if (sync_properties(new) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, sub)
+{
+ const php_date_time_duration *original = Z_DATE_TIME_DURATION_P(ZEND_THIS);
+
+ const php_date_time_duration *minus;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_DATE_TIME_DURATION(minus);
+ ZEND_PARSE_PARAMETERS_END();
+
+ php_date_time_duration *new = create_duration_shell(return_value);
+
+ int error = timelib_duration_sub_static(&new->duration, &original->duration, &minus->duration);
+ if (error != TIMELIB_ERROR_NO_ERROR) {
+ throw_timelib_error(error);
+ RETURN_THROWS();
+ }
+
+ if (sync_properties(new) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, multiplyBy)
+{
+ const php_date_time_duration *original = Z_DATE_TIME_DURATION_P(ZEND_THIS);
+
+ zend_ulong factor;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_ULONG(factor);
+ ZEND_PARSE_PARAMETERS_END();
+
+ php_date_time_duration *new = create_duration_shell(return_value);
+
+ int error = timelib_duration_mul_static(&new->duration, &original->duration, factor);
+ if (error != TIMELIB_ERROR_NO_ERROR) {
+ throw_timelib_error(error);
+ RETURN_THROWS();
+ }
+
+ if (sync_properties(new) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, divideBy)
+{
+ const php_date_time_duration *original = Z_DATE_TIME_DURATION_P(ZEND_THIS);
+
+ zend_ulong divisor;
+
+ ZEND_PARSE_PARAMETERS_START(1, 1)
+ Z_PARAM_ULONG(divisor);
+ ZEND_PARSE_PARAMETERS_END();
+
+ php_date_time_duration *new = create_duration_shell(return_value);
+
+ int error = timelib_duration_div_static(&new->duration, &original->duration, divisor);
+ if (error != TIMELIB_ERROR_NO_ERROR) {
+ throw_timelib_error(error);
+ RETURN_THROWS();
+ }
+
+ if (sync_properties(new) == FAILURE) {
+ RETURN_THROWS();
+ }
+}
+
+PHP_METHOD(Time_Duration, compare)
+{
+ const php_date_time_duration *a;
+ const php_date_time_duration *b;
+
+ ZEND_PARSE_PARAMETERS_START(2, 2)
+ Z_PARAM_DATE_TIME_DURATION(a);
+ Z_PARAM_DATE_TIME_DURATION(b);
+ ZEND_PARSE_PARAMETERS_END();
+
+ RETURN_LONG(timelib_duration_compare(&a->duration, &b->duration));
+}
diff --git a/ext/hash/tests/hash_serialize_003.phpt b/ext/hash/tests/hash_serialize_003.phpt
index 541a3169e53e..a01c100644a1 100644
--- a/ext/hash/tests/hash_serialize_003.phpt
+++ b/ext/hash/tests/hash_serialize_003.phpt
@@ -237,7 +237,7 @@ function test_serialization($serial, $hash, $algo) {
}
} catch (Throwable $e) {
echo "$algo: problem with serialization {$serial}\n";
- echo ' ', $e::class . ': ' . $e->getMessage(), "\n", $e->getTraceAsString();
+ echo $e::class, ': ', $e->getMessage(), "\n", $e->getTraceAsString();
}
}
diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c
index 2c904edd4cfc..2bbd7b0e3f4d 100644
--- a/ext/opcache/jit/zend_jit_ir.c
+++ b/ext/opcache/jit/zend_jit_ir.c
@@ -360,6 +360,11 @@ static int zend_jit_assign_to_variable(zend_jit_ctx *jit,
static ir_ref jit_CONST_FUNC(zend_jit_ctx *jit, uintptr_t addr, uint16_t flags);
+static void zend_jit_preserve_parent_regs(zend_jit_ctx *jit,
+ zend_ssa *ssa,
+ zend_jit_trace_info *parent,
+ uint32_t exit_num);
+
typedef struct _zend_jit_stub {
const char *name;
int (*stub)(zend_jit_ctx *jit);
@@ -17351,6 +17356,7 @@ static int zend_jit_trace_handler(zend_jit_ctx *jit, const zend_op_array *op_arr
static int zend_jit_deoptimizer_start(zend_jit_ctx *jit,
zend_string *name,
uint32_t trace_num,
+ zend_jit_trace_info *parent,
uint32_t exit_num)
{
zend_jit_init_ctx(jit, (ZEND_VM_KIND == ZEND_VM_KIND_CALL || ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL) ? 0 : IR_START_BR_TARGET);
@@ -17363,6 +17369,8 @@ static int zend_jit_deoptimizer_start(zend_jit_ctx *jit,
jit->ctx.flags |= IR_SKIP_PROLOGUE;
+ zend_jit_preserve_parent_regs(jit, NULL, parent, exit_num);
+
return 1;
}
@@ -17399,6 +17407,21 @@ static int zend_jit_trace_start(zend_jit_ctx *jit,
jit->ctx.flags |= IR_SKIP_PROLOGUE;
}
+ zend_jit_preserve_parent_regs(jit, ssa, parent, exit_num);
+
+ ir_STORE(jit_EG(jit_trace_num), ir_CONST_U32(trace_num));
+
+ return 1;
+}
+
+static void zend_jit_preserve_parent_regs(zend_jit_ctx *jit,
+ zend_ssa *ssa,
+ zend_jit_trace_info *parent,
+ uint32_t exit_num)
+{
+ /* Emit early RLOADs of registers used for deoptimization to prevent
+ * clobbering. zend_jit_deopt_rload() will reference these. */
+
if (parent) {
int i;
int parent_vars_count = parent->exit_info[exit_num].stack_size;
@@ -17406,7 +17429,6 @@ static int zend_jit_trace_start(zend_jit_ctx *jit,
parent->stack_map +
parent->exit_info[exit_num].stack_offset;
- /* prevent clobbering of registers used for deoptimization */
for (i = 0; i < parent_vars_count; i++) {
if (STACK_FLAGS(parent_stack, i) != ZREG_CONST
&& STACK_REG(parent_stack, i) != ZREG_NONE) {
@@ -17450,10 +17472,6 @@ static int zend_jit_trace_start(zend_jit_ctx *jit,
ir_RLOAD_A(parent->exit_info[exit_num].poly_this.reg);
}
}
-
- ir_STORE(jit_EG(jit_trace_num), ir_CONST_U32(trace_num));
-
- return 1;
}
static int zend_jit_trace_begin_loop(zend_jit_ctx *jit)
diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c
index 505427890129..a47ef18db337 100644
--- a/ext/opcache/jit/zend_jit_trace.c
+++ b/ext/opcache/jit/zend_jit_trace.c
@@ -7455,7 +7455,7 @@ static zend_vm_opcode_handler_t zend_jit_trace_exit_to_vm(uint32_t trace_num, ui
name = zend_jit_trace_escape_name(trace_num, exit_num);
- if (!zend_jit_deoptimizer_start(&ctx, name, trace_num, exit_num)) {
+ if (!zend_jit_deoptimizer_start(&ctx, name, trace_num, &zend_jit_traces[trace_num], exit_num)) {
zend_string_release(name);
return NULL;
}
diff --git a/ext/opcache/tests/jit/gh22915.phpt b/ext/opcache/tests/jit/gh22915.phpt
new file mode 100644
index 000000000000..cea291d311b1
--- /dev/null
+++ b/ext/opcache/tests/jit/gh22915.phpt
@@ -0,0 +1,75 @@
+--TEST--
+GH-22915: compiled exit clobbers registers before saving
+--EXTENSIONS--
+opcache
+--INI--
+opcache.jit_max_side_traces=0
+opcache.jit_blacklist_side_trace=0
+--ENV--
+F=iter
+--FILE--
+values = $values;
+ }
+
+ public function rewind(): void {}
+
+ public function valid(): bool {
+ return $this->position === 0;
+ }
+
+ public function current(): mixed {
+ if (!isset($this->values[$this->position])) {
+ throw new Exception();
+ }
+
+ return $this->values[$this->position];
+ }
+
+ public function key(): mixed {
+ return $this->position;
+ }
+
+ public function next(): void {
+ $this->position++;
+ }
+}
+
+function iter(It $it) {
+ foreach ($it as $value) {
+ var_dump($value);
+ if (!$value instanceof stdClass) {
+ continue;
+ }
+ }
+}
+
+echo "# First run\n";
+for ($i = 0; $i < 5; $i++) {
+ getenv('F')(new It([getenv('F')])); // non-immutable, packed array
+}
+
+echo "# Second run\n";
+for ($i = 0; $i < 5; $i++) {
+ getenv('F')(new It([getenv('F'), 'map' => true])); // non-immutable, map, triggers exit
+}
+
+?>
+--EXPECT--
+# First run
+string(4) "iter"
+string(4) "iter"
+string(4) "iter"
+string(4) "iter"
+string(4) "iter"
+# Second run
+string(4) "iter"
+string(4) "iter"
+string(4) "iter"
+string(4) "iter"
+string(4) "iter"
diff --git a/ext/spl/tests/ArrayObject/ArrayObject_exchange_array_during_sorting.phpt b/ext/spl/tests/ArrayObject/ArrayObject_exchange_array_during_sorting.phpt
index b563c2c84d08..e385ef4922cf 100644
--- a/ext/spl/tests/ArrayObject/ArrayObject_exchange_array_during_sorting.phpt
+++ b/ext/spl/tests/ArrayObject/ArrayObject_exchange_array_during_sorting.phpt
@@ -10,7 +10,7 @@ $ao->uasort(function($a, $b) use ($ao, &$i) {
try {
$ao->exchangeArray([4, 5, 6]);
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($ao);
}
@@ -19,7 +19,7 @@ $ao->uasort(function($a, $b) use ($ao, &$i) {
?>
--EXPECT--
-Modification of ArrayObject during sorting is prohibited
+Error: Modification of ArrayObject during sorting is prohibited
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(3) {
diff --git a/ext/spl/tests/ArrayObject/ArrayObject_illegal_offset.phpt b/ext/spl/tests/ArrayObject/ArrayObject_illegal_offset.phpt
index a2803e472966..c97e10ed2582 100644
--- a/ext/spl/tests/ArrayObject/ArrayObject_illegal_offset.phpt
+++ b/ext/spl/tests/ArrayObject/ArrayObject_illegal_offset.phpt
@@ -7,33 +7,33 @@ $ao = new ArrayObject([1, 2, 3]);
try {
var_dump($ao[[]]);
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$ao[[]] = new stdClass;
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$ref =& $ao[[]];
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(isset($ao[[]]));
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unset($ao[[]]);
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-Cannot access offset of type array on ArrayObject
-Cannot access offset of type array on ArrayObject
-Cannot access offset of type array on ArrayObject
-Cannot access offset of type array in isset or empty
-Cannot unset offset of type array on ArrayObject
+TypeError: Cannot access offset of type array on ArrayObject
+TypeError: Cannot access offset of type array on ArrayObject
+TypeError: Cannot access offset of type array on ArrayObject
+TypeError: Cannot access offset of type array in isset or empty
+TypeError: Cannot unset offset of type array on ArrayObject
diff --git a/ext/spl/tests/ArrayObject/ArrayObject_overloaded_SplFixedArray.phpt b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_SplFixedArray.phpt
index 13065b4ac38a..8ff0b93e79dd 100644
--- a/ext/spl/tests/ArrayObject/ArrayObject_overloaded_SplFixedArray.phpt
+++ b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_SplFixedArray.phpt
@@ -9,9 +9,9 @@ try {
// See GH-15918: this *should* fail to not break invariants
$ao->exchangeArray($fixedArray);
} catch (InvalidArgumentException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECTF--
Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d
-Overloaded object of type SplFixedArray is not compatible with ArrayObject
+InvalidArgumentException: Overloaded object of type SplFixedArray is not compatible with ArrayObject
diff --git a/ext/spl/tests/ArrayObject/ArrayObject_overloaded_object_incompatible.phpt b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_object_incompatible.phpt
index 8cc66facc005..2d8d566f7e5e 100644
--- a/ext/spl/tests/ArrayObject/ArrayObject_overloaded_object_incompatible.phpt
+++ b/ext/spl/tests/ArrayObject/ArrayObject_overloaded_object_incompatible.phpt
@@ -7,14 +7,14 @@ $ao = new ArrayObject([1, 2, 3]);
try {
$ao->exchangeArray(new DateInterval('P1D'));
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($ao);
?>
--EXPECTF--
Deprecated: ArrayObject::exchangeArray(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d
-Overloaded object of type DateInterval is not compatible with ArrayObject
+InvalidArgumentException: Overloaded object of type DateInterval is not compatible with ArrayObject
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(3) {
diff --git a/ext/spl/tests/ArrayObject/arrayObject___construct_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_error1.phpt
index a9fbc9d3b030..78660694d530 100644
--- a/ext/spl/tests/ArrayObject/arrayObject___construct_error1.phpt
+++ b/ext/spl/tests/ArrayObject/arrayObject___construct_error1.phpt
@@ -8,18 +8,18 @@ $a->p = 1;
try {
var_dump(new ArrayObject($a, 0, "Exception"));
} catch (TypeError $e) {
- echo $e->getMessage() . "(" . $e->getLine() . ")\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "Non-existent class:\n";
try {
var_dump(new ArrayObject(new stdClass, 0, "nonExistentClassName"));
} catch (TypeError $e) {
- echo $e->getMessage() . "(" . $e->getLine() . ")\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
Bad iterator type:
-ArrayObject::__construct(): Argument #3 ($iteratorClass) must be a class name derived from ArrayIterator, Exception given(6)
+TypeError: ArrayObject::__construct(): Argument #3 ($iteratorClass) must be a class name derived from ArrayIterator, Exception given
Non-existent class:
-ArrayObject::__construct(): Argument #3 ($iteratorClass) must be a class name derived from ArrayIterator, nonExistentClassName given(13)
+TypeError: ArrayObject::__construct(): Argument #3 ($iteratorClass) must be a class name derived from ArrayIterator, nonExistentClassName given
diff --git a/ext/spl/tests/ArrayObject/arrayObject___construct_error2.phpt b/ext/spl/tests/ArrayObject/arrayObject___construct_error2.phpt
index c3804f0d0afd..4624d0d3b1d8 100644
--- a/ext/spl/tests/ArrayObject/arrayObject___construct_error2.phpt
+++ b/ext/spl/tests/ArrayObject/arrayObject___construct_error2.phpt
@@ -14,9 +14,9 @@ Class C implements Iterator {
try {
var_dump(new ArrayObject(new stdClass, 0, "C", "extra"));
} catch (TypeError $e) {
- echo $e->getMessage() . "(" . $e->getLine() . ")\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
Too many arguments:
-ArrayObject::__construct() expects at most 3 arguments, 4 given(12)
+ArgumentCountError: ArrayObject::__construct() expects at most 3 arguments, 4 given
diff --git a/ext/spl/tests/ArrayObject/arrayObject_asort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_asort_basic1.phpt
index efce55d4d587..22f69324fae0 100644
--- a/ext/spl/tests/ArrayObject/arrayObject_asort_basic1.phpt
+++ b/ext/spl/tests/ArrayObject/arrayObject_asort_basic1.phpt
@@ -16,7 +16,7 @@ var_dump($ao1);
try {
var_dump($ao2->asort('blah'));
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($ao2);
var_dump($ao2->asort(SORT_NUMERIC));
@@ -36,7 +36,7 @@ object(ArrayObject)#%d (1) {
int(4)
}
}
-ArrayObject::asort(): Argument #1 ($flags) must be of type int, string given
+TypeError: ArrayObject::asort(): Argument #1 ($flags) must be of type int, string given
object(ArrayObject)#%d (1) {
["storage":"ArrayObject":private]=>
array(3) {
diff --git a/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic2.phpt b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic2.phpt
index 4ba09cd388f2..8a7cbe5d9abb 100644
--- a/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic2.phpt
+++ b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic2.phpt
@@ -104,4 +104,4 @@ object(ArrayObject)#%d (1) {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic3.phpt b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic3.phpt
index 8db9b016fda8..08569a7194fc 100644
--- a/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic3.phpt
+++ b/ext/spl/tests/ArrayObject/arrayObject_exchangeArray_basic3.phpt
@@ -16,7 +16,7 @@ try {
$copy = $ao->exchangeArray($swapIn);
$copy['addedToCopy'] = 'added To Copy';
} catch (Exception $e) {
- echo "Exception:" . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$swapIn->addedToSwapIn = 'added To Swap-In';
$original->addedToOriginal = 'added To Original';
@@ -31,7 +31,7 @@ try {
$copy = $ao->exchangeArray();
$copy['addedToCopy'] = 'added To Copy';
} catch (TypeError $e) {
- echo "Exception: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$original->addedToOriginal = 'added To Original';
var_dump($ao, $original, $copy);
@@ -44,7 +44,7 @@ try {
$copy = $ao->exchangeArray(null);
$copy['addedToCopy'] = 'added To Copy';
} catch (TypeError $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$original->addedToOriginal = 'added To Original';
var_dump($ao, $original, $copy);
@@ -92,7 +92,7 @@ array(2) {
--> exchangeArray() with no arg:
Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d
-Exception: ArrayObject::exchangeArray() expects exactly 1 argument, 0 given
+ArgumentCountError: ArrayObject::exchangeArray() expects exactly 1 argument, 0 given
Deprecated: Creation of dynamic property C::$addedToOriginal is deprecated in %s on line %d
@@ -118,7 +118,7 @@ NULL
--> exchangeArray() with bad arg type:
Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d
-ArrayObject::exchangeArray(): Argument #1 ($array) must be of type array, null given
+TypeError: ArrayObject::exchangeArray(): Argument #1 ($array) must be of type array, null given
Deprecated: Creation of dynamic property C::$addedToOriginal is deprecated in %s on line %d
diff --git a/ext/spl/tests/ArrayObject/arrayObject_ksort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_ksort_basic1.phpt
index 27605461cbeb..8f8bd605ba3b 100644
--- a/ext/spl/tests/ArrayObject/arrayObject_ksort_basic1.phpt
+++ b/ext/spl/tests/ArrayObject/arrayObject_ksort_basic1.phpt
@@ -15,7 +15,7 @@ var_dump($ao1);
try {
var_dump($ao2->ksort('blah'));
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($ao2);
var_dump($ao2->ksort(SORT_STRING));
@@ -35,7 +35,7 @@ object(ArrayObject)#%d (1) {
int(3)
}
}
-ArrayObject::ksort(): Argument #1 ($flags) must be of type int, string given
+TypeError: ArrayObject::ksort(): Argument #1 ($flags) must be of type int, string given
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(4) {
diff --git a/ext/spl/tests/ArrayObject/arrayObject_natcasesort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_natcasesort_basic1.phpt
index 9949fbda06aa..31ebae0e8112 100644
--- a/ext/spl/tests/ArrayObject/arrayObject_natcasesort_basic1.phpt
+++ b/ext/spl/tests/ArrayObject/arrayObject_natcasesort_basic1.phpt
@@ -16,7 +16,7 @@ var_dump($ao1);
try {
var_dump($ao2->natcasesort('blah'));
} catch (ArgumentCountError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($ao2);
?>
@@ -38,7 +38,7 @@ object(ArrayObject)#1 (1) {
string(5) "boo22"
}
}
-ArrayObject::natcasesort() expects exactly 0 arguments, 1 given
+ArgumentCountError: ArrayObject::natcasesort() expects exactly 0 arguments, 1 given
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(5) {
diff --git a/ext/spl/tests/ArrayObject/arrayObject_natsort_basic1.phpt b/ext/spl/tests/ArrayObject/arrayObject_natsort_basic1.phpt
index 474c142de0a4..6b45a4edd86b 100644
--- a/ext/spl/tests/ArrayObject/arrayObject_natsort_basic1.phpt
+++ b/ext/spl/tests/ArrayObject/arrayObject_natsort_basic1.phpt
@@ -16,7 +16,7 @@ var_dump($ao1);
try {
var_dump($ao2->natsort('blah'));
} catch (ArgumentCountError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($ao2);
?>
@@ -38,7 +38,7 @@ object(ArrayObject)#1 (1) {
string(5) "boo22"
}
}
-ArrayObject::natsort() expects exactly 0 arguments, 1 given
+ArgumentCountError: ArrayObject::natsort() expects exactly 0 arguments, 1 given
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(5) {
diff --git a/ext/spl/tests/ArrayObject/arrayObject_setIteratorClass_error1.phpt b/ext/spl/tests/ArrayObject/arrayObject_setIteratorClass_error1.phpt
index 9a0e67b6052f..1eb8d17ca66c 100644
--- a/ext/spl/tests/ArrayObject/arrayObject_setIteratorClass_error1.phpt
+++ b/ext/spl/tests/ArrayObject/arrayObject_setIteratorClass_error1.phpt
@@ -9,7 +9,7 @@ try {
echo " $key=>$value\n";
}
} catch (TypeError $e) {
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
@@ -19,7 +19,7 @@ try {
echo " $key=>$value\n";
}
} catch (TypeError $e) {
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
@@ -29,7 +29,7 @@ try {
echo " $key=>$value\n";
}
} catch (TypeError $e) {
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
@@ -38,12 +38,12 @@ try {
echo " $key=>$value\n";
}
} catch (TypeError $e) {
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-string(133) "ArrayObject::setIteratorClass(): Argument #1 ($iteratorClass) must be a class name derived from ArrayIterator, nonExistentClass given"
-string(125) "ArrayObject::setIteratorClass(): Argument #1 ($iteratorClass) must be a class name derived from ArrayIterator, stdClass given"
-string(128) "ArrayObject::__construct(): Argument #3 ($iteratorClass) must be a class name derived from ArrayIterator, nonExistentClass given"
-string(120) "ArrayObject::__construct(): Argument #3 ($iteratorClass) must be a class name derived from ArrayIterator, stdClass given"
+TypeError: ArrayObject::setIteratorClass(): Argument #1 ($iteratorClass) must be a class name derived from ArrayIterator, nonExistentClass given
+TypeError: ArrayObject::setIteratorClass(): Argument #1 ($iteratorClass) must be a class name derived from ArrayIterator, stdClass given
+TypeError: ArrayObject::__construct(): Argument #3 ($iteratorClass) must be a class name derived from ArrayIterator, nonExistentClass given
+TypeError: ArrayObject::__construct(): Argument #3 ($iteratorClass) must be a class name derived from ArrayIterator, stdClass given
diff --git a/ext/spl/tests/ArrayObject/array_014.phpt b/ext/spl/tests/ArrayObject/array_014.phpt
index 37ed9abad507..ec061ca135aa 100644
--- a/ext/spl/tests/ArrayObject/array_014.phpt
+++ b/ext/spl/tests/ArrayObject/array_014.phpt
@@ -16,7 +16,7 @@ try
}
catch(Exception $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try
@@ -26,7 +26,7 @@ try
}
catch(Exception $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$pos = 0;
@@ -41,8 +41,8 @@ foreach($it as $v)
int(11)
int(5)
int(4)
-Seek position -1 is out of range
-Seek position 12 is out of range
+OutOfBoundsException: Seek position -1 is out of range
+OutOfBoundsException: Seek position 12 is out of range
int(0)
int(1)
int(2)
diff --git a/ext/spl/tests/ArrayObject/array_018.phpt b/ext/spl/tests/ArrayObject/array_018.phpt
index 948e0dca4e53..b6ee252820bc 100644
--- a/ext/spl/tests/ArrayObject/array_018.phpt
+++ b/ext/spl/tests/ArrayObject/array_018.phpt
@@ -10,7 +10,7 @@ try
}
catch (Exception $e)
{
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($foo);
@@ -23,7 +23,7 @@ try
}
catch (Exception $e)
{
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($foo);
diff --git a/ext/spl/tests/ArrayObject/gh15833_2.phpt b/ext/spl/tests/ArrayObject/gh15833_2.phpt
index 5d7721e25dd2..1b21535aed30 100644
--- a/ext/spl/tests/ArrayObject/gh15833_2.phpt
+++ b/ext/spl/tests/ArrayObject/gh15833_2.phpt
@@ -16,27 +16,27 @@ $recursiveArrayIterator = new RecursiveArrayIterator($obj);
try {
var_dump($recursiveArrayIterator->current());
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($recursiveArrayIterator->current());
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$recursiveArrayIterator->next();
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($recursiveArrayIterator->current());
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECTF--
Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d
-nope 0
-nope 1
-nope 2
-nope 3
+Error: nope 0
+Error: nope 1
+Error: nope 2
+Error: nope 3
diff --git a/ext/spl/tests/ArrayObject/gh15918.phpt b/ext/spl/tests/ArrayObject/gh15918.phpt
index 5efdb887f9b5..f16d25d54ad1 100644
--- a/ext/spl/tests/ArrayObject/gh15918.phpt
+++ b/ext/spl/tests/ArrayObject/gh15918.phpt
@@ -6,9 +6,9 @@ $foo = new SplFixedArray(5);
try {
$arrayObject = new ArrayObject($foo);
} catch (InvalidArgumentException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECTF--
Deprecated: ArrayObject::__construct(): Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants in %s on line %d
-Overloaded object of type SplFixedArray is not compatible with ArrayObject
+InvalidArgumentException: Overloaded object of type SplFixedArray is not compatible with ArrayObject
diff --git a/ext/spl/tests/ArrayObject_construct_during_sorting.phpt b/ext/spl/tests/ArrayObject_construct_during_sorting.phpt
index cec41dc92cd0..6638c8f55227 100644
--- a/ext/spl/tests/ArrayObject_construct_during_sorting.phpt
+++ b/ext/spl/tests/ArrayObject_construct_during_sorting.phpt
@@ -11,7 +11,7 @@ $ao->uasort(function($a, $b) use ($ao, $other, &$i) {
try {
$ao->__construct($other);
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
}
return $a <=> $b;
@@ -20,7 +20,7 @@ var_dump($ao);
?>
--EXPECT--
-Modification of ArrayObject during sorting is prohibited
+Error: Modification of ArrayObject during sorting is prohibited
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(3) {
diff --git a/ext/spl/tests/CallbackFilterIteratorTest-002.phpt b/ext/spl/tests/CallbackFilterIteratorTest-002.phpt
index bba7e0f8a9ad..a939b739cdff 100644
--- a/ext/spl/tests/CallbackFilterIteratorTest-002.phpt
+++ b/ext/spl/tests/CallbackFilterIteratorTest-002.phpt
@@ -11,25 +11,25 @@ set_error_handler(function($errno, $errstr){
try {
new CallbackFilterIterator();
} catch (TypeError $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
new CallbackFilterIterator(null);
} catch (TypeError $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
new CallbackFilterIterator(new ArrayIterator(array()), null);
} catch (TypeError $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
new CallbackFilterIterator(new ArrayIterator(array()), array());
} catch (TypeError $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$it = new CallbackFilterIterator(new ArrayIterator(array(1)), function() {
@@ -38,12 +38,12 @@ $it = new CallbackFilterIterator(new ArrayIterator(array(1)), function() {
try {
foreach($it as $e);
} catch(Exception $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-CallbackFilterIterator::__construct() expects exactly 2 arguments, 0 given
-CallbackFilterIterator::__construct() expects exactly 2 arguments, 1 given
-CallbackFilterIterator::__construct(): Argument #2 ($callback) must be a valid callback, no array or string given
-CallbackFilterIterator::__construct(): Argument #2 ($callback) must be a valid callback, array callback must have exactly two members
-some message
+ArgumentCountError: CallbackFilterIterator::__construct() expects exactly 2 arguments, 0 given
+ArgumentCountError: CallbackFilterIterator::__construct() expects exactly 2 arguments, 1 given
+TypeError: CallbackFilterIterator::__construct(): Argument #2 ($callback) must be a valid callback, no array or string given
+TypeError: CallbackFilterIterator::__construct(): Argument #2 ($callback) must be a valid callback, array callback must have exactly two members
+Exception: some message
diff --git a/ext/spl/tests/DirectoryIterator_empty_constructor.phpt b/ext/spl/tests/DirectoryIterator_empty_constructor.phpt
index 3db6700d2e94..23d3168c155a 100644
--- a/ext/spl/tests/DirectoryIterator_empty_constructor.phpt
+++ b/ext/spl/tests/DirectoryIterator_empty_constructor.phpt
@@ -8,8 +8,8 @@ Havard Eide
try {
$it = new DirectoryIterator("");
} catch (\ValueError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-DirectoryIterator::__construct(): Argument #1 ($directory) must not be empty
+ValueError: DirectoryIterator::__construct(): Argument #1 ($directory) must not be empty
diff --git a/ext/spl/tests/DirectoryIterator_uninitialized.phpt b/ext/spl/tests/DirectoryIterator_uninitialized.phpt
index cb63b555aab9..ea393f5da02d 100644
--- a/ext/spl/tests/DirectoryIterator_uninitialized.phpt
+++ b/ext/spl/tests/DirectoryIterator_uninitialized.phpt
@@ -11,9 +11,9 @@ $it = new MyDirectoryIterator;
try {
$it->key();
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-Object not initialized
+Error: Object not initialized
diff --git a/ext/spl/tests/GH-22047.phpt b/ext/spl/tests/GH-22047.phpt
index b01fbfd633c0..0a7d66ba52ed 100644
--- a/ext/spl/tests/GH-22047.phpt
+++ b/ext/spl/tests/GH-22047.phpt
@@ -13,9 +13,9 @@ try {
echo "should not reach here\n";
}
} catch (UnexpectedValueException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECTF--
-Cannot deserialize ArrayObject with iterator class 'GlobIterator'; this class is not derived from ArrayIterator
+UnexpectedValueException: Cannot deserialize ArrayObject with iterator class 'GlobIterator'; this class is not derived from ArrayIterator
diff --git a/ext/spl/tests/GlobIterator_constructor_count.phpt b/ext/spl/tests/GlobIterator_constructor_count.phpt
index 5f96be6219d6..5a5dd7845604 100644
--- a/ext/spl/tests/GlobIterator_constructor_count.phpt
+++ b/ext/spl/tests/GlobIterator_constructor_count.phpt
@@ -7,8 +7,8 @@ $in = $rc->newInstanceWithoutConstructor();
try {
count($in);
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-GlobIterator is not initialized
+Error: GlobIterator is not initialized
diff --git a/ext/spl/tests/RecursiveIteratorIterator_invalid_aggregate.phpt b/ext/spl/tests/RecursiveIteratorIterator_invalid_aggregate.phpt
index e877de6ae024..4e9264739c9c 100644
--- a/ext/spl/tests/RecursiveIteratorIterator_invalid_aggregate.phpt
+++ b/ext/spl/tests/RecursiveIteratorIterator_invalid_aggregate.phpt
@@ -13,9 +13,9 @@ class MyIteratorAggregate implements IteratorAggregate {
try {
new RecursiveIteratorIterator(new MyIteratorAggregate);
} catch (LogicException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-MyIteratorAggregate::getIterator() must return an object that implements Traversable
+LogicException: MyIteratorAggregate::getIterator() must return an object that implements Traversable
diff --git a/ext/spl/tests/RecursiveIteratorIterator_not_initialized.phpt b/ext/spl/tests/RecursiveIteratorIterator_not_initialized.phpt
index 4e90692843d6..c34122c11ac9 100644
--- a/ext/spl/tests/RecursiveIteratorIterator_not_initialized.phpt
+++ b/ext/spl/tests/RecursiveIteratorIterator_not_initialized.phpt
@@ -8,9 +8,9 @@ $it = $rc->newInstanceWithoutConstructor();
try {
foreach ($it as $v) {}
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-Object is not initialized
+Error: Object is not initialized
diff --git a/ext/spl/tests/SPLDoublyLinkedList_iterate_by_reference.phpt b/ext/spl/tests/SPLDoublyLinkedList_iterate_by_reference.phpt
index 769136c4064f..385d9590485a 100644
--- a/ext/spl/tests/SPLDoublyLinkedList_iterate_by_reference.phpt
+++ b/ext/spl/tests/SPLDoublyLinkedList_iterate_by_reference.phpt
@@ -18,9 +18,9 @@ try {
echo $value, PHP_EOL;
}
} catch (\Error $e) {
- echo $e->getMessage(), PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-An iterator cannot be used with foreach by reference
+Error: An iterator cannot be used with foreach by reference
diff --git a/ext/spl/tests/SplArray_fromArray.phpt b/ext/spl/tests/SplArray_fromArray.phpt
index 143d2755a81d..01d2875d272c 100644
--- a/ext/spl/tests/SplArray_fromArray.phpt
+++ b/ext/spl/tests/SplArray_fromArray.phpt
@@ -10,8 +10,8 @@ $splArray = new SplFixedArray();
try {
$splArray->fromArray($array);
} catch (Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-integer overflow detected
+InvalidArgumentException: integer overflow detected
diff --git a/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt b/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt
index 347450fbe4b5..1c496aeffc0f 100644
--- a/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt
+++ b/ext/spl/tests/SplDoublyLinkedList_add_invalid_offset.phpt
@@ -6,8 +6,8 @@ try {
$dll = new SplDoublyLinkedList();
var_dump($dll->add(12,'Offset 12 should not exist'));
} catch (OutOfRangeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-Exception: SplDoublyLinkedList::add(): Argument #1 ($index) is out of range
+OutOfRangeException: SplDoublyLinkedList::add(): Argument #1 ($index) is out of range
diff --git a/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt b/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt
index 1872436cea63..493265428180 100644
--- a/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt
+++ b/ext/spl/tests/SplDoublyLinkedList_add_null_offset.phpt
@@ -6,8 +6,8 @@ try {
$dll = new SplDoublyLinkedList();
var_dump($dll->add([],2));
} catch (TypeError $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-Exception: SplDoublyLinkedList::add(): Argument #1 ($index) must be of type int, array given
+TypeError: SplDoublyLinkedList::add(): Argument #1 ($index) must be of type int, array given
diff --git a/ext/spl/tests/SplDoublyLinkedList_bottom_empty.phpt b/ext/spl/tests/SplDoublyLinkedList_bottom_empty.phpt
index 65f0b3d404eb..fd85e6aebeab 100644
--- a/ext/spl/tests/SplDoublyLinkedList_bottom_empty.phpt
+++ b/ext/spl/tests/SplDoublyLinkedList_bottom_empty.phpt
@@ -7,8 +7,8 @@ Gabriel Caruso (carusogabriel34@gmail.com)
try {
(new SplDoublyLinkedList)->bottom();
} catch (RuntimeException $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Can't peek at an empty datastructure
+RuntimeException: Can't peek at an empty datastructure
diff --git a/ext/spl/tests/SplDoublyLinkedList_offsetUnset_greater_than_elements.phpt b/ext/spl/tests/SplDoublyLinkedList_offsetUnset_greater_than_elements.phpt
index 4fa65b3a53ad..234628cd2758 100644
--- a/ext/spl/tests/SplDoublyLinkedList_offsetUnset_greater_than_elements.phpt
+++ b/ext/spl/tests/SplDoublyLinkedList_offsetUnset_greater_than_elements.phpt
@@ -17,9 +17,9 @@ $ll->offsetUnset($ll->count() + 1);
var_dump($ll);
} catch(Exception $e) {
-echo $e->getMessage();
+echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-SplDoublyLinkedList::offsetUnset(): Argument #1 ($index) is out of range
+OutOfRangeException: SplDoublyLinkedList::offsetUnset(): Argument #1 ($index) is out of range
diff --git a/ext/spl/tests/SplDoublyLinkedList_offsetUnset_negative-parameter.phpt b/ext/spl/tests/SplDoublyLinkedList_offsetUnset_negative-parameter.phpt
index 614ebdf01bbb..f378de684b15 100644
--- a/ext/spl/tests/SplDoublyLinkedList_offsetUnset_negative-parameter.phpt
+++ b/ext/spl/tests/SplDoublyLinkedList_offsetUnset_negative-parameter.phpt
@@ -16,8 +16,8 @@ PHPNW Testfest 2009 - Paul Court ( g@rgoyle.com )
$dll->offsetUnset(-1);
}
catch (Exception $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-SplDoublyLinkedList::offsetUnset(): Argument #1 ($index) is out of range
+OutOfRangeException: SplDoublyLinkedList::offsetUnset(): Argument #1 ($index) is out of range
diff --git a/ext/spl/tests/SplDoublyLinkedList_offsetUnset_parameter-larger-num-elements.phpt b/ext/spl/tests/SplDoublyLinkedList_offsetUnset_parameter-larger-num-elements.phpt
index 6782bd948983..894f80766374 100644
--- a/ext/spl/tests/SplDoublyLinkedList_offsetUnset_parameter-larger-num-elements.phpt
+++ b/ext/spl/tests/SplDoublyLinkedList_offsetUnset_parameter-larger-num-elements.phpt
@@ -16,8 +16,8 @@ PHPNW Testfest 2009 - Paul Court ( g@rgoyle.com )
$dll->offsetUnset(3);
}
catch (Exception $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-SplDoublyLinkedList::offsetUnset(): Argument #1 ($index) is out of range
+OutOfRangeException: SplDoublyLinkedList::offsetUnset(): Argument #1 ($index) is out of range
diff --git a/ext/spl/tests/SplDoublyLinkedList_top_empty.phpt b/ext/spl/tests/SplDoublyLinkedList_top_empty.phpt
index 644e54bb9a1d..ddcd20b23519 100644
--- a/ext/spl/tests/SplDoublyLinkedList_top_empty.phpt
+++ b/ext/spl/tests/SplDoublyLinkedList_top_empty.phpt
@@ -7,8 +7,8 @@ Gabriel Caruso (carusogabriel34@gmail.com)
try {
(new SplDoublyLinkedList)->top();
} catch (RuntimeException $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Can't peek at an empty datastructure
+RuntimeException: Can't peek at an empty datastructure
diff --git a/ext/spl/tests/SplFileInfo_setFileClass_error.phpt b/ext/spl/tests/SplFileInfo_setFileClass_error.phpt
index 4ace511e26b0..96d4e5eddefa 100644
--- a/ext/spl/tests/SplFileInfo_setFileClass_error.phpt
+++ b/ext/spl/tests/SplFileInfo_setFileClass_error.phpt
@@ -8,9 +8,9 @@ $info = new SplFileInfo(__FILE__);
try {
$info->setFileClass('stdClass');
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-SplFileInfo::setFileClass(): Argument #1 ($class) must be a class name derived from SplFileObject, stdClass given
+TypeError: SplFileInfo::setFileClass(): Argument #1 ($class) must be a class name derived from SplFileObject, stdClass given
diff --git a/ext/spl/tests/SplFileInfo_setInfoClass_error.phpt b/ext/spl/tests/SplFileInfo_setInfoClass_error.phpt
index 1f64c353d328..10b568bc027f 100644
--- a/ext/spl/tests/SplFileInfo_setInfoClass_error.phpt
+++ b/ext/spl/tests/SplFileInfo_setInfoClass_error.phpt
@@ -8,9 +8,9 @@ $info = new SplFileInfo(__FILE__);
try {
$info->setInfoClass('stdClass');
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-SplFileInfo::setInfoClass(): Argument #1 ($class) must be a class name derived from SplFileInfo, stdClass given
+TypeError: SplFileInfo::setInfoClass(): Argument #1 ($class) must be a class name derived from SplFileInfo, stdClass given
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_delimiter_error.phpt b/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_delimiter_error.phpt
index 7bfd61bbc188..99ce5203edf0 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_delimiter_error.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_delimiter_error.phpt
@@ -20,7 +20,7 @@ $fo->setCsvControl(escape: '');
try {
var_dump($fo->fgetcsv('invalid'));
} catch (ValueError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--CLEAN--
@@ -28,4 +28,4 @@ try {
unlink('SplFileObject__fgetcsv3.csv');
?>
--EXPECT--
-SplFileObject::fgetcsv(): Argument #1 ($separator) must be a single character
+ValueError: SplFileObject::fgetcsv(): Argument #1 ($separator) must be a single character
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_enclosure_error.phpt b/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_enclosure_error.phpt
index 8ad609efab10..a13ac8d62a53 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_enclosure_error.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_enclosure_error.phpt
@@ -20,7 +20,7 @@ $fo->setCsvControl(escape: '');
try {
var_dump($fo->fgetcsv(enclosure: 'invalid'));
} catch (ValueError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--CLEAN--
@@ -28,4 +28,4 @@ try {
unlink('SplFileObject__fgetcsv5.csv');
?>
--EXPECT--
-SplFileObject::fgetcsv(): Argument #2 ($enclosure) must be a single character
+ValueError: SplFileObject::fgetcsv(): Argument #2 ($enclosure) must be a single character
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_escape_error.phpt b/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_escape_error.phpt
index eb6fc4916111..d2421e23271f 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_escape_error.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_fgetcsv_escape_error.phpt
@@ -10,7 +10,7 @@ $fo = new SplFileObject('SplFileObject__fgetcsv8.csv');
try {
var_dump($fo->fgetcsv(',', '"', 'invalid'));
} catch (ValueError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--CLEAN--
@@ -18,4 +18,4 @@ try {
unlink('SplFileObject__fgetcsv8.csv');
?>
--EXPECT--
-SplFileObject::fgetcsv(): Argument #3 ($escape) must be empty or a single character
+ValueError: SplFileObject::fgetcsv(): Argument #3 ($escape) must be empty or a single character
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_fputcsv_variation13.phpt b/ext/spl/tests/SplFileObject/SplFileObject_fputcsv_variation13.phpt
index b21379994269..136491f915eb 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_fputcsv_variation13.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_fputcsv_variation13.phpt
@@ -13,7 +13,7 @@ $fo = new SplFileObject(__DIR__ . '/SplFileObject_fputcsv_variation13.csv', 'w')
try {
var_dump($fo->fputcsv(array('water', 'fruit'), ',,', '"'));
} catch (ValueError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
unset($fo);
@@ -27,5 +27,5 @@ unlink($file);
?>
--EXPECT--
*** Testing fputcsv() : with default enclosure & delimiter of two chars ***
-SplFileObject::fputcsv(): Argument #2 ($separator) must be a single character
+ValueError: SplFileObject::fputcsv(): Argument #2 ($separator) must be a single character
Done
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_fputcsv_variation14.phpt b/ext/spl/tests/SplFileObject/SplFileObject_fputcsv_variation14.phpt
index c660d217acb5..8a8cb968b0af 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_fputcsv_variation14.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_fputcsv_variation14.phpt
@@ -13,12 +13,12 @@ $fo = new SplFileObject(__DIR__ . '/SplFileObject_fputcsv_variation14.csv', 'w')
try {
var_dump($fo->fputcsv(array('water', 'fruit'), ',,', '""'));
} catch (ValueError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($fo->fputcsv(array('water', 'fruit'), ',', '""'));
} catch (ValueError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
unset($fo);
@@ -32,6 +32,6 @@ unlink($file);
?>
--EXPECT--
*** Testing fputcsv() : with enclosure & delimiter of two chars and file opened in read mode ***
-SplFileObject::fputcsv(): Argument #2 ($separator) must be a single character
-SplFileObject::fputcsv(): Argument #3 ($enclosure) must be a single character
+ValueError: SplFileObject::fputcsv(): Argument #2 ($separator) must be a single character
+ValueError: SplFileObject::fputcsv(): Argument #3 ($enclosure) must be a single character
Done
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_ftruncate_error_001.phpt b/ext/spl/tests/SplFileObject/SplFileObject_ftruncate_error_001.phpt
index a77257cc5754..4fae0a83b23c 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_ftruncate_error_001.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_ftruncate_error_001.phpt
@@ -26,8 +26,8 @@ $obj = New SplFileObject("SPLtest://ftruncate_test");
try {
$obj->ftruncate(1);
} catch (LogicException $e) {
- echo($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECTF--
-Can't truncate file %s
+LogicException: Can't truncate file %s
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_getCurrentLine_invalid_override.phpt b/ext/spl/tests/SplFileObject/SplFileObject_getCurrentLine_invalid_override.phpt
index 3501816366f8..ee9930b7c8ea 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_getCurrentLine_invalid_override.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_getCurrentLine_invalid_override.phpt
@@ -14,9 +14,9 @@ $obj = new MySplFileObject(__FILE__);
try {
var_dump($obj->current());
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-MySplFileObject::getCurrentLine(): Return value must be of type string, array returned
+TypeError: MySplFileObject::getCurrentLine(): Return value must be of type string, array returned
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_seek_error_001.phpt b/ext/spl/tests/SplFileObject/SplFileObject_seek_error_001.phpt
index d29e86b955db..a590f49a5f20 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_seek_error_001.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_seek_error_001.phpt
@@ -6,8 +6,8 @@ $obj = new SplFileObject(__FILE__);
try {
$obj->seek(-1);
} catch (\ValueError $e) {
- echo($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-SplFileObject::seek(): Argument #1 ($line) must be greater than or equal to 0
+ValueError: SplFileObject::seek(): Argument #1 ($line) must be greater than or equal to 0
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error001.phpt b/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error001.phpt
index a2fea52d5a00..3ff6478ca1df 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error001.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error001.phpt
@@ -16,7 +16,7 @@ $s->setFlags(SplFileObject::READ_CSV);
try {
$s->setCsvControl('||');
} catch (ValueError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--CLEAN--
@@ -24,4 +24,4 @@ try {
unlink('csv_control_data_error001.csv');
?>
--EXPECT--
-SplFileObject::setCsvControl(): Argument #1 ($separator) must be a single character
+ValueError: SplFileObject::setCsvControl(): Argument #1 ($separator) must be a single character
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error002.phpt b/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error002.phpt
index 3e4c206fe0ab..3a33c479fa06 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error002.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error002.phpt
@@ -16,7 +16,7 @@ $s->setFlags(SplFileObject::READ_CSV);
try {
$s->setCsvControl('|', 'two');
} catch (ValueError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--CLEAN--
@@ -24,4 +24,4 @@ try {
unlink('csv_control_data_error002.csv');
?>
--EXPECT--
-SplFileObject::setCsvControl(): Argument #2 ($enclosure) must be a single character
+ValueError: SplFileObject::setCsvControl(): Argument #2 ($enclosure) must be a single character
diff --git a/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error003.phpt b/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error003.phpt
index 35934f5e5cb0..a68d0ad29780 100644
--- a/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error003.phpt
+++ b/ext/spl/tests/SplFileObject/SplFileObject_setCsvControl_error003.phpt
@@ -18,7 +18,7 @@ $s->setFlags(SplFileObject::READ_CSV);
try {
$s->setCsvControl('|', '\'', 'three');
} catch (ValueError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--CLEAN--
@@ -26,4 +26,4 @@ try {
unlink('csv_control_data_error003.csv');
?>
--EXPECT--
-SplFileObject::setCsvControl(): Argument #3 ($escape) must be empty or a single character
+ValueError: SplFileObject::setCsvControl(): Argument #3 ($escape) must be empty or a single character
diff --git a/ext/spl/tests/SplFileObject/bug54292.phpt b/ext/spl/tests/SplFileObject/bug54292.phpt
index 39bfb6f4dd63..53e8eedc8c11 100644
--- a/ext/spl/tests/SplFileObject/bug54292.phpt
+++ b/ext/spl/tests/SplFileObject/bug54292.phpt
@@ -6,9 +6,9 @@ Bug #54292 (Wrong parameter causes crash in SplFileObject::__construct())
try {
new SplFileObject('foo', array());
} catch (TypeError $e) {
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-string(85) "SplFileObject::__construct(): Argument #2 ($mode) must be of type string, array given"
+TypeError: SplFileObject::__construct(): Argument #2 ($mode) must be of type string, array given
diff --git a/ext/spl/tests/SplFileObject/bug65545.phpt b/ext/spl/tests/SplFileObject/bug65545.phpt
index 8ebbf648c97c..afac7c0f2684 100644
--- a/ext/spl/tests/SplFileObject/bug65545.phpt
+++ b/ext/spl/tests/SplFileObject/bug65545.phpt
@@ -10,7 +10,7 @@ try {
$data = $obj->fread(0);
var_dump($data);
} catch (\ValueError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
// read more data than is available
@@ -20,5 +20,5 @@ var_dump(strlen($data) === filesize(__FILE__) - 5);
?>
--EXPECT--
string(5) "getPath(), -1);
var_dump($l != '/' && $l != '\\' && $l == $lp);
} catch (LogicException $e) {
- echo "LogicException: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$fo = $o->openFile();
var_dump($fo->getPathName(), $fo->getFileName(), $fo->getPath());
} catch (LogicException $e) {
- echo "LogicException: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
}
diff --git a/ext/spl/tests/SplFileObject/fileobject_setmaxlinelen_error001.phpt b/ext/spl/tests/SplFileObject/fileobject_setmaxlinelen_error001.phpt
index 018ecd47b42a..ea64231d04cb 100644
--- a/ext/spl/tests/SplFileObject/fileobject_setmaxlinelen_error001.phpt
+++ b/ext/spl/tests/SplFileObject/fileobject_setmaxlinelen_error001.phpt
@@ -9,9 +9,9 @@ try {
$s->setMaxLineLen(-1);
}
catch (\ValueError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-SplFileObject::setMaxLineLen(): Argument #1 ($maxLength) must be greater than or equal to 0
+ValueError: SplFileObject::setMaxLineLen(): Argument #1 ($maxLength) must be greater than or equal to 0
diff --git a/ext/spl/tests/SplFixedArray__construct_param_array.phpt b/ext/spl/tests/SplFixedArray__construct_param_array.phpt
index 76f32855b2a2..5fa62c86a543 100644
--- a/ext/spl/tests/SplFixedArray__construct_param_array.phpt
+++ b/ext/spl/tests/SplFixedArray__construct_param_array.phpt
@@ -8,9 +8,9 @@ PHPNW Test Fest 2009 - Jordan Hatch
try {
$array = new SplFixedArray( array("string", 1) );
} catch (TypeError $iae) {
- echo "Ok - ".$iae->getMessage().PHP_EOL;
+ echo $iae::class, ': ', $iae->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Ok - SplFixedArray::__construct(): Argument #1 ($size) must be of type int, array given
+TypeError: SplFixedArray::__construct(): Argument #1 ($size) must be of type int, array given
diff --git a/ext/spl/tests/SplFixedArray__construct_param_string.phpt b/ext/spl/tests/SplFixedArray__construct_param_string.phpt
index 1c9a681e82a1..d9a49092287d 100644
--- a/ext/spl/tests/SplFixedArray__construct_param_string.phpt
+++ b/ext/spl/tests/SplFixedArray__construct_param_string.phpt
@@ -7,10 +7,10 @@ PHPNW Test Fest 2009 - Jordan Hatch
try {
$array = new SplFixedArray( "string" );
} catch (TypeError $iae) {
- echo "Ok - ".$iae->getMessage().PHP_EOL;
+ echo $iae::class, ': ', $iae->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Ok - SplFixedArray::__construct(): Argument #1 ($size) must be of type int, string given
+TypeError: SplFixedArray::__construct(): Argument #1 ($size) must be of type int, string given
diff --git a/ext/spl/tests/SplFixedArray_construct_param_SplFixedArray.phpt b/ext/spl/tests/SplFixedArray_construct_param_SplFixedArray.phpt
index ab9b430d2a7e..0d2723c60e6d 100644
--- a/ext/spl/tests/SplFixedArray_construct_param_SplFixedArray.phpt
+++ b/ext/spl/tests/SplFixedArray_construct_param_SplFixedArray.phpt
@@ -7,9 +7,9 @@ Philip Norton philipnorton42@gmail.com
try {
$array = new SplFixedArray(new SplFixedArray(3));
} catch (TypeError $iae) {
- echo "Ok - ".$iae->getMessage().PHP_EOL;
+ echo $iae::class, ': ', $iae->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Ok - SplFixedArray::__construct(): Argument #1 ($size) must be of type int, SplFixedArray given
+TypeError: SplFixedArray::__construct(): Argument #1 ($size) must be of type int, SplFixedArray given
diff --git a/ext/spl/tests/SplHeap_serialize_corrupted.phpt b/ext/spl/tests/SplHeap_serialize_corrupted.phpt
index 8763a4c08293..4abf239d04cc 100644
--- a/ext/spl/tests/SplHeap_serialize_corrupted.phpt
+++ b/ext/spl/tests/SplHeap_serialize_corrupted.phpt
@@ -28,7 +28,7 @@ try {
serialize($heap);
echo "FAIL: Serialization should have thrown\n";
} catch (Exception $e) {
- echo "Serialization failed: " . $e->getMessage() . "\n";
+ echo 'Serialization failed: ', $e::class, ': ', $e->getMessage(), "\n";
}
class ThrowingPQ extends SplPriorityQueue {
@@ -56,12 +56,12 @@ try {
serialize($pq);
echo "FAIL: PQ Serialization should have thrown\n";
} catch (Exception $e) {
- echo "PQ Serialization failed: " . $e->getMessage() . "\n";
+ echo 'PQ Serialization failed: ', $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
Heap is corrupted: YES
-Serialization failed: Heap is corrupted, heap properties are no longer ensured.
+Serialization failed: RuntimeException: Heap is corrupted, heap properties are no longer ensured.
PriorityQueue is corrupted: YES
-PQ Serialization failed: Heap is corrupted, heap properties are no longer ensured.
+PQ Serialization failed: RuntimeException: Heap is corrupted, heap properties are no longer ensured.
diff --git a/ext/spl/tests/SplHeap_serialize_error_handling.phpt b/ext/spl/tests/SplHeap_serialize_error_handling.phpt
index 458f27db5ce0..bbcbe48515f1 100644
--- a/ext/spl/tests/SplHeap_serialize_error_handling.phpt
+++ b/ext/spl/tests/SplHeap_serialize_error_handling.phpt
@@ -37,7 +37,7 @@ foreach ($invalid_cases as $i => $case) {
$heap->__unserialize($case);
echo "Case $i: UNEXPECTED SUCCESS\n";
} catch (Exception $e) {
- echo "Case $i: " . $e->getMessage() . "\n";
+ echo "Case $i: ", $e::class, ': ', $e->getMessage(), "\n";
}
}
@@ -60,25 +60,25 @@ foreach ($pq_invalid_cases as $i => $case) {
$pq->__unserialize($case);
echo "PQ Case $i: UNEXPECTED SUCCESS\n";
} catch (Exception $e) {
- echo "PQ Case $i: " . $e->getMessage() . "\n";
+ echo "PQ Case $i: ", $e::class, ': ', $e->getMessage(), "\n";
}
}
?>
--EXPECT--
-Case 0: Invalid serialization data for SplMaxHeap object
-Case 1: Invalid serialization data for SplMaxHeap object
-Case 2: Invalid serialization data for SplMaxHeap object
-Case 3: Invalid serialization data for SplMaxHeap object
-Case 4: Invalid serialization data for SplMaxHeap object
-Case 5: Invalid serialization data for SplMaxHeap object
-Case 6: Invalid serialization data for SplMaxHeap object
-Case 7: Invalid serialization data for SplMaxHeap object
-Case 8: Invalid serialization data for SplMaxHeap object
-Case 9: Invalid serialization data for SplMaxHeap object
-Case 10: Invalid serialization data for SplMaxHeap object
-PQ Case 0: Invalid serialization data for SplPriorityQueue object
-PQ Case 1: Invalid serialization data for SplPriorityQueue object
-PQ Case 2: Invalid serialization data for SplPriorityQueue object
-PQ Case 3: Invalid serialization data for SplPriorityQueue object
-PQ Case 4: Invalid serialization data for SplPriorityQueue object
+Case 0: Exception: Invalid serialization data for SplMaxHeap object
+Case 1: Exception: Invalid serialization data for SplMaxHeap object
+Case 2: Exception: Invalid serialization data for SplMaxHeap object
+Case 3: Exception: Invalid serialization data for SplMaxHeap object
+Case 4: Exception: Invalid serialization data for SplMaxHeap object
+Case 5: Exception: Invalid serialization data for SplMaxHeap object
+Case 6: Exception: Invalid serialization data for SplMaxHeap object
+Case 7: Exception: Invalid serialization data for SplMaxHeap object
+Case 8: Exception: Invalid serialization data for SplMaxHeap object
+Case 9: Exception: Invalid serialization data for SplMaxHeap object
+Case 10: Exception: Invalid serialization data for SplMaxHeap object
+PQ Case 0: Exception: Invalid serialization data for SplPriorityQueue object
+PQ Case 1: Exception: Invalid serialization data for SplPriorityQueue object
+PQ Case 2: Exception: Invalid serialization data for SplPriorityQueue object
+PQ Case 3: Exception: Invalid serialization data for SplPriorityQueue object
+PQ Case 4: Exception: Invalid serialization data for SplPriorityQueue object
diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt
index d4075018d341..91d80b3d7de8 100644
--- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt
+++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_coalesce.phpt
@@ -96,4 +96,4 @@ object(SplObjectStorage)#1 (1) {
bool(false)
}
}
-}
\ No newline at end of file
+}
diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_current_empty_storage.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_current_empty_storage.phpt
index 096cd511128b..fed9330c3fc7 100644
--- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_current_empty_storage.phpt
+++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_current_empty_storage.phpt
@@ -11,10 +11,10 @@ var_dump($s->valid());
try {
var_dump($s->current());
} catch (RuntimeException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
bool(false)
-Called current() on invalid iterator
+RuntimeException: Called current() on invalid iterator
diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_offsetGet_missing_object.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_offsetGet_missing_object.phpt
index 54fcc23d4dcf..772d8a09e307 100644
--- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_offsetGet_missing_object.phpt
+++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_offsetGet_missing_object.phpt
@@ -11,9 +11,9 @@ $o1 = new stdClass();
try {
$s->offsetGet($o1);
} catch (UnexpectedValueException $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Object not found
+UnexpectedValueException: Object not found
diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_seek.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_seek.phpt
index ce21b2a621fe..cc0b9d3ce0cc 100644
--- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_seek.phpt
+++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_seek.phpt
@@ -25,12 +25,12 @@ echo "--- Error cases ---\n";
try {
$storage->seek(-1);
} catch (OutOfBoundsException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$storage->seek(5);
} catch (OutOfBoundsException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($storage->key());
@@ -76,14 +76,14 @@ foreach (range(0, 2) as $index) {
try {
$storage->seek(3);
} catch (OutOfBoundsException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
--- Error cases ---
-Seek position -1 is out of range
-Seek position 5 is out of range
+OutOfBoundsException: Seek position -1 is out of range
+OutOfBoundsException: Seek position 5 is out of range
int(0)
object(Test)#1 (1) {
["marker"]=>
@@ -136,4 +136,4 @@ object(Test)#5 (1) {
["marker"]=>
string(1) "e"
}
-Seek position 3 is out of range
+OutOfBoundsException: Seek position 3 is out of range
diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_bad.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_bad.phpt
index b2fbf264286b..03ad16f57fd3 100644
--- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_bad.phpt
+++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_bad.phpt
@@ -15,14 +15,14 @@ try {
$so->unserialize($blob);
var_dump($so);
} catch(UnexpectedValueException $e) {
- echo $e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
}
echo "DONE\n";
?>
--EXPECT--
-Error at offset 6 of 34 bytes
-Error at offset 46 of 89 bytes
+UnexpectedValueException: Error at offset 6 of 34 bytes
+UnexpectedValueException: Error at offset 46 of 89 bytes
object(SplObjectStorage)#2 (1) {
["storage":"SplObjectStorage":private]=>
array(2) {
@@ -45,5 +45,5 @@ object(SplObjectStorage)#2 (1) {
}
}
}
-Error at offset 78 of 78 bytes
+UnexpectedValueException: Error at offset 78 of 78 bytes
DONE
diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_invalid_parameter2.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_invalid_parameter2.phpt
index 0ff158c85c57..9d1afe16ef27 100644
--- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_invalid_parameter2.phpt
+++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_invalid_parameter2.phpt
@@ -20,14 +20,14 @@ foreach($data_provider as $input) {
try {
$s->unserialize($input);
} catch(UnexpectedValueException $e) {
- echo $e->getMessage() . PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
}
?>
--EXPECTF--
-Error at offset %d of %d bytes
-Error at offset %d of %d bytes
-Error at offset %d of %d bytes
-Error at offset %d of %d bytes
-Error at offset %d of %d bytes
+UnexpectedValueException: Error at offset %d of %d bytes
+UnexpectedValueException: Error at offset %d of %d bytes
+UnexpectedValueException: Error at offset %d of %d bytes
+UnexpectedValueException: Error at offset %d of %d bytes
+UnexpectedValueException: Error at offset %d of %d bytes
diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_invalid_parameter3.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_invalid_parameter3.phpt
index 6934c3af1bf8..a82242dfb451 100644
--- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_invalid_parameter3.phpt
+++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_unserialize_invalid_parameter3.phpt
@@ -10,7 +10,7 @@ $s = new SplObjectStorage();
try {
$s->unserialize('');
} catch(UnexpectedValueException $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
diff --git a/ext/spl/tests/SplObjectStorage/SplObjectStorage_unset.phpt b/ext/spl/tests/SplObjectStorage/SplObjectStorage_unset.phpt
index 2e3e58c837cb..3c69760642ba 100644
--- a/ext/spl/tests/SplObjectStorage/SplObjectStorage_unset.phpt
+++ b/ext/spl/tests/SplObjectStorage/SplObjectStorage_unset.phpt
@@ -16,14 +16,14 @@ $s[$o] = new HasDestructor();
try {
unset($s[$o]);
} catch (Exception $e) {
- echo "Caught: {$e->getMessage()}\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($s);
$s[$o] = new HasDestructor();
try {
$s->offsetUnset($o);
} catch (Exception $e) {
- echo "Caught: {$e->getMessage()}\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($s);
@@ -35,7 +35,7 @@ object(SplObjectStorage)#2 (1) {
array(0) {
}
}
-Caught: thrown from destructor
+RuntimeException: thrown from destructor
object(SplObjectStorage)#2 (1) {
["storage":"SplObjectStorage":private]=>
array(0) {
@@ -47,9 +47,9 @@ object(SplObjectStorage)#2 (1) {
array(0) {
}
}
-Caught: thrown from destructor
+RuntimeException: thrown from destructor
object(SplObjectStorage)#2 (1) {
["storage":"SplObjectStorage":private]=>
array(0) {
}
-}
\ No newline at end of file
+}
diff --git a/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt b/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt
index 9da6270b6d7d..a4b4e7d3a986 100644
--- a/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt
+++ b/ext/spl/tests/SplObjectStorage/concurrent_deletion.phpt
@@ -33,7 +33,7 @@ $other->mutate = true;
try {
$victim->removeAllExcept($other);
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump(count($victim), count($other));
@@ -48,15 +48,15 @@ $other->mutate = true;
try {
$other->addAll($victim);
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump(count($victim), count($other));
?>
--EXPECT--
-Modification of SplObjectStorage during getHash() is prohibited
+Error: Modification of SplObjectStorage during getHash() is prohibited
int(1024)
int(1024)
-Modification of SplObjectStorage during getHash() is prohibited
+Error: Modification of SplObjectStorage during getHash() is prohibited
int(1024)
int(1024)
diff --git a/ext/spl/tests/SplObjectStorage/concurrent_deletion_addall.phpt b/ext/spl/tests/SplObjectStorage/concurrent_deletion_addall.phpt
index aadbe2acba27..6c940869915e 100644
--- a/ext/spl/tests/SplObjectStorage/concurrent_deletion_addall.phpt
+++ b/ext/spl/tests/SplObjectStorage/concurrent_deletion_addall.phpt
@@ -20,13 +20,13 @@ $evil = new EvilStorage();
try {
$evil->addAll($storage);
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump(count($evil), count($storage));
?>
--EXPECT--
-Modification of SplObjectStorage during getHash() is prohibited
+Error: Modification of SplObjectStorage during getHash() is prohibited
int(0)
int(1)
diff --git a/ext/spl/tests/SplObjectStorage/concurrent_deletion_removeexcept.phpt b/ext/spl/tests/SplObjectStorage/concurrent_deletion_removeexcept.phpt
index 2602bc9e1f03..27bf06c347cf 100644
--- a/ext/spl/tests/SplObjectStorage/concurrent_deletion_removeexcept.phpt
+++ b/ext/spl/tests/SplObjectStorage/concurrent_deletion_removeexcept.phpt
@@ -20,13 +20,13 @@ $evil = new EvilStorage();
try {
$storage->removeAllExcept($evil);
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump(count($evil), count($storage));
?>
--EXPECT--
-Modification of SplObjectStorage during getHash() is prohibited
+Error: Modification of SplObjectStorage during getHash() is prohibited
int(0)
int(1)
diff --git a/ext/spl/tests/SplObjectStorage/gh21831.phpt b/ext/spl/tests/SplObjectStorage/gh21831.phpt
index 581012d86a4f..2eb514445590 100644
--- a/ext/spl/tests/SplObjectStorage/gh21831.phpt
+++ b/ext/spl/tests/SplObjectStorage/gh21831.phpt
@@ -25,12 +25,12 @@ $filter->other = $storage;
try {
$storage->removeAllExcept($filter);
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump(count($storage));
?>
--EXPECT--
-Modification of SplObjectStorage during getHash() is prohibited
+Error: Modification of SplObjectStorage during getHash() is prohibited
int(1)
diff --git a/ext/spl/tests/SplPriorityQueue_unserialize_invalid_flags.phpt b/ext/spl/tests/SplPriorityQueue_unserialize_invalid_flags.phpt
index 8c785606c7fe..916c32edae06 100644
--- a/ext/spl/tests/SplPriorityQueue_unserialize_invalid_flags.phpt
+++ b/ext/spl/tests/SplPriorityQueue_unserialize_invalid_flags.phpt
@@ -16,7 +16,7 @@ try {
$queue->__unserialize($data);
echo "Should have thrown exception for invalid flags\n";
} catch (Exception $e) {
- echo "Exception thrown for invalid flags: " . $e->getMessage() . "\n";
+ echo 'invalid flags: ', $e::class, ': ', $e->getMessage(), "\n";
}
try {
@@ -32,7 +32,7 @@ try {
$queue->__unserialize($data);
echo "Should have thrown exception for zero flags\n";
} catch (Exception $e) {
- echo "Exception thrown for zero flags: " . $e->getMessage() . "\n";
+ echo 'zero flags: ', $e::class, ': ', $e->getMessage(), "\n";
}
try {
@@ -48,7 +48,7 @@ try {
$queue->__unserialize($data);
echo "Valid flags accepted\n";
} catch (Exception $e) {
- echo "Valid flags rejected: " . $e->getMessage() . "\n";
+ echo 'Valid flags rejected: ', $e::class, ': ', $e->getMessage(), "\n";
}
try {
@@ -69,12 +69,12 @@ try {
echo "Flags not properly masked, got: " . $queue->getExtractFlags() . "\n";
}
} catch (Exception $e) {
- echo "Flags with extra bits should be masked: " . $e->getMessage() . "\n";
+ echo 'Flags with extra bits should be masked: ', $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-Exception thrown for invalid flags: Invalid serialization data for SplPriorityQueue object
-Exception thrown for zero flags: Invalid serialization data for SplPriorityQueue object
+invalid flags: Exception: Invalid serialization data for SplPriorityQueue object
+zero flags: Exception: Invalid serialization data for SplPriorityQueue object
Valid flags accepted
Flags properly masked
diff --git a/ext/spl/tests/SplQueue_setIteratorMode.phpt b/ext/spl/tests/SplQueue_setIteratorMode.phpt
index 5ad1d9258a7d..0e291b355437 100644
--- a/ext/spl/tests/SplQueue_setIteratorMode.phpt
+++ b/ext/spl/tests/SplQueue_setIteratorMode.phpt
@@ -8,8 +8,8 @@ $queue = new SplQueue();
try {
$queue->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO);
} catch (Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen
+RuntimeException: Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen
diff --git a/ext/spl/tests/SplQueue_setIteratorMode_param_lifo.phpt b/ext/spl/tests/SplQueue_setIteratorMode_param_lifo.phpt
index 255f0cd2e4d2..3d58d09a75fa 100644
--- a/ext/spl/tests/SplQueue_setIteratorMode_param_lifo.phpt
+++ b/ext/spl/tests/SplQueue_setIteratorMode_param_lifo.phpt
@@ -11,9 +11,9 @@ try {
$dll->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO);
} catch (Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen
+RuntimeException: Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen
diff --git a/ext/spl/tests/SplStack_setIteratorMode.phpt b/ext/spl/tests/SplStack_setIteratorMode.phpt
index 342a6b8bb24a..e059a35cfca9 100644
--- a/ext/spl/tests/SplStack_setIteratorMode.phpt
+++ b/ext/spl/tests/SplStack_setIteratorMode.phpt
@@ -8,8 +8,8 @@ $stack = new SplStack();
try {
$stack->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO);
} catch (Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen
+RuntimeException: Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen
diff --git a/ext/spl/tests/SplTempFileObject_constructor_error.phpt b/ext/spl/tests/SplTempFileObject_constructor_error.phpt
index 212a4df2ff8a..de520b1922fa 100644
--- a/ext/spl/tests/SplTempFileObject_constructor_error.phpt
+++ b/ext/spl/tests/SplTempFileObject_constructor_error.phpt
@@ -5,8 +5,8 @@ SPL SplTempFileObject constructor sets correct defaults when pass 0 arguments
try {
new SplTempFileObject('invalid');
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-SplTempFileObject::__construct(): Argument #1 ($maxMemory) must be of type int, string given
+TypeError: SplTempFileObject::__construct(): Argument #1 ($maxMemory) must be of type int, string given
diff --git a/ext/spl/tests/autoloading/bug73896.phpt b/ext/spl/tests/autoloading/bug73896.phpt
index 657f30c50dbe..c31d3285803d 100644
--- a/ext/spl/tests/autoloading/bug73896.phpt
+++ b/ext/spl/tests/autoloading/bug73896.phpt
@@ -31,8 +31,8 @@ $teLoader = new teLoader();
try {
new teChild();
} catch (Throwable $e) {
- echo "Exception: ", $e->getMessage() , "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-Exception: Class "teException" not found
+Error: Class "teException" not found
diff --git a/ext/spl/tests/autoloading/spl_autoload_001.phpt b/ext/spl/tests/autoloading/spl_autoload_001.phpt
index befb96570950..761699bd8e74 100644
--- a/ext/spl/tests/autoloading/spl_autoload_001.phpt
+++ b/ext/spl/tests/autoloading/spl_autoload_001.phpt
@@ -67,7 +67,7 @@ echo "===NOFUNCTION===\n";
try {
spl_autoload_register("unavailable_autoload_function");
} catch(\TypeError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
@@ -100,4 +100,4 @@ TestFunc2(TestClass)
%stestclass.class.inc
bool(true)
===NOFUNCTION===
-spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, function "unavailable_autoload_function" not found or invalid function name
+TypeError: spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, function "unavailable_autoload_function" not found or invalid function name
diff --git a/ext/spl/tests/autoloading/spl_autoload_003.phpt b/ext/spl/tests/autoloading/spl_autoload_003.phpt
index 016bcf2394b6..7485ea88ece1 100644
--- a/ext/spl/tests/autoloading/spl_autoload_003.phpt
+++ b/ext/spl/tests/autoloading/spl_autoload_003.phpt
@@ -31,7 +31,7 @@ try
}
catch(Exception $e)
{
- echo 'Exception: ' . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
diff --git a/ext/spl/tests/autoloading/spl_autoload_005.phpt b/ext/spl/tests/autoloading/spl_autoload_005.phpt
index 0f2c5ed2c302..a3f2bc3c4b96 100644
--- a/ext/spl/tests/autoloading/spl_autoload_005.phpt
+++ b/ext/spl/tests/autoloading/spl_autoload_005.phpt
@@ -22,7 +22,7 @@ class MyAutoLoader {
try {
spl_autoload_register(array('MyAutoLoader', 'autoLoad'), true);
} catch(\TypeError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
// and
@@ -38,12 +38,12 @@ try
}
catch(Exception $e)
{
- echo 'Exception: ' . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, non-static method MyAutoLoader::autoLoad() cannot be called statically
+TypeError: spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, non-static method MyAutoLoader::autoLoad() cannot be called statically
MyAutoLoader::autoLoad(TestClass)
MyAutoLoader::autoThrow(TestClass)
Exception: Unavailable
diff --git a/ext/spl/tests/autoloading/spl_autoload_007.phpt b/ext/spl/tests/autoloading/spl_autoload_007.phpt
index 0a8183dfb403..c47b10c270c7 100644
--- a/ext/spl/tests/autoloading/spl_autoload_007.phpt
+++ b/ext/spl/tests/autoloading/spl_autoload_007.phpt
@@ -45,23 +45,23 @@ foreach($funcs as $idx => $func)
spl_autoload_register($func);
echo "ok\n";
} catch(\TypeError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
}
?>
--EXPECTF--
string(22) "MyAutoLoader::notExist"
-spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, class MyAutoLoader does not have a method "notExist"
+TypeError: spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, class MyAutoLoader does not have a method "notExist"
string(22) "MyAutoLoader::noAccess"
-spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, cannot access protected method MyAutoLoader::noAccess()
+TypeError: spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, cannot access protected method MyAutoLoader::noAccess()
string(22) "MyAutoLoader::autoLoad"
ok
string(22) "MyAutoLoader::dynaLoad"
-spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, non-static method MyAutoLoader::dynaLoad() cannot be called statically
+TypeError: spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, non-static method MyAutoLoader::dynaLoad() cannot be called statically
array(2) {
[0]=>
@@ -69,7 +69,7 @@ array(2) {
[1]=>
string(8) "notExist"
}
-spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, class MyAutoLoader does not have a method "notExist"
+TypeError: spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, class MyAutoLoader does not have a method "notExist"
array(2) {
[0]=>
@@ -77,7 +77,7 @@ array(2) {
[1]=>
string(8) "noAccess"
}
-spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, cannot access protected method MyAutoLoader::noAccess()
+TypeError: spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, cannot access protected method MyAutoLoader::noAccess()
array(2) {
[0]=>
@@ -93,7 +93,7 @@ array(2) {
[1]=>
string(8) "dynaLoad"
}
-spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, non-static method MyAutoLoader::dynaLoad() cannot be called statically
+TypeError: spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, non-static method MyAutoLoader::dynaLoad() cannot be called statically
array(2) {
[0]=>
@@ -102,7 +102,7 @@ array(2) {
[1]=>
string(8) "notExist"
}
-spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, class MyAutoLoader does not have a method "notExist"
+TypeError: spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, class MyAutoLoader does not have a method "notExist"
array(2) {
[0]=>
@@ -111,7 +111,7 @@ array(2) {
[1]=>
string(8) "noAccess"
}
-spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, cannot access protected method MyAutoLoader::noAccess()
+TypeError: spl_autoload_register(): Argument #1 ($callback) must be a valid callback or null, cannot access protected method MyAutoLoader::noAccess()
array(2) {
[0]=>
diff --git a/ext/spl/tests/autoloading/spl_autoload_008.phpt b/ext/spl/tests/autoloading/spl_autoload_008.phpt
index 738c691ddfe9..9a45409beb5b 100644
--- a/ext/spl/tests/autoloading/spl_autoload_008.phpt
+++ b/ext/spl/tests/autoloading/spl_autoload_008.phpt
@@ -46,7 +46,7 @@ foreach($funcs as $idx => $func)
try {
spl_autoload_register($func);
} catch (TypeError $e) {
- echo get_class($e) . ': ' . $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
var_dump(count(spl_autoload_functions()));
continue;
}
@@ -57,7 +57,7 @@ foreach($funcs as $idx => $func)
try {
var_dump(class_exists("NoExistingTestClass", true));
} catch (Exception $e) {
- echo get_class($e) . ': ' . $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
}
diff --git a/ext/spl/tests/autoloading/spl_autoload_012.phpt b/ext/spl/tests/autoloading/spl_autoload_012.phpt
index 218d3e800ff2..a9da7cf8bbf9 100644
--- a/ext/spl/tests/autoloading/spl_autoload_012.phpt
+++ b/ext/spl/tests/autoloading/spl_autoload_012.phpt
@@ -22,7 +22,7 @@ try {
class_exists('ThisClassDoesNotExist');
} catch(Exception $e) {
do {
- echo $e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
} while($e = $e->getPrevious());
}
@@ -30,7 +30,7 @@ try {
new ThisClassDoesNotExist;
} catch(Exception $e) {
do {
- echo $e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
} while($e = $e->getPrevious());
}
@@ -39,9 +39,9 @@ class_exists('ThisClassDoesNotExist');
===DONE===
--EXPECTF--
autoload_first
-first
+Exception: first
autoload_first
-first
+Exception: first
autoload_first
Fatal error: Uncaught Exception: first in %sspl_autoload_012.php:%d
diff --git a/ext/spl/tests/autoloading/spl_autoload_throw_with_spl_autoloader_call_as_autoloader.phpt b/ext/spl/tests/autoloading/spl_autoload_throw_with_spl_autoloader_call_as_autoloader.phpt
index 943d80ae2537..48dd7120cfb0 100644
--- a/ext/spl/tests/autoloading/spl_autoload_throw_with_spl_autoloader_call_as_autoloader.phpt
+++ b/ext/spl/tests/autoloading/spl_autoload_throw_with_spl_autoloader_call_as_autoloader.phpt
@@ -6,9 +6,9 @@ spl_autoload_register() function - warn when using spl_autoload_call() as the au
try {
spl_autoload_register('spl_autoload_call');
} catch (\ValueError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-spl_autoload_register(): Argument #1 ($callback) must not be the spl_autoload_call() function
+ValueError: spl_autoload_register(): Argument #1 ($callback) must not be the spl_autoload_call() function
diff --git a/ext/spl/tests/bug31185.phpt b/ext/spl/tests/bug31185.phpt
index 70ae1c00983d..a327b4d4de1f 100644
--- a/ext/spl/tests/bug31185.phpt
+++ b/ext/spl/tests/bug31185.phpt
@@ -37,7 +37,7 @@ try
}
catch (Exception $e)
{
- echo "CAUGHT: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
print_R($foo);
@@ -46,7 +46,7 @@ print_R($foo);
FooBar::offsetSet(0, 0)
FooBar::offsetSet(1, 1)
FooBar::offsetSet(2, 2)
-CAUGHT: FAIL
+Exception: FAIL
FooBar Object
(
[array:FooBar:private] => Array
diff --git a/ext/spl/tests/bug37457.phpt b/ext/spl/tests/bug37457.phpt
index e8c7d7b9afca..c5ecd4567b61 100644
--- a/ext/spl/tests/bug37457.phpt
+++ b/ext/spl/tests/bug37457.phpt
@@ -64,7 +64,7 @@ try
}
catch (Exception $e)
{
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
@@ -75,4 +75,4 @@ Collection::valid
Collection::current
Collection::key
TestFilter::accept
-string(17) "Failure in Accept"
+Exception: Failure in Accept
diff --git a/ext/spl/tests/bug42703.phpt b/ext/spl/tests/bug42703.phpt
index d869fef0d58b..5323b187c7d1 100644
--- a/ext/spl/tests/bug42703.phpt
+++ b/ext/spl/tests/bug42703.phpt
@@ -29,13 +29,13 @@ try {
}
}
catch (Exception $e) {
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($itit->current());
var_dump($itit->key());
?>
--EXPECT--
-string(3) "boo"
+Exception: boo
NULL
NULL
diff --git a/ext/spl/tests/bug51119.phpt b/ext/spl/tests/bug51119.phpt
index 2f3348a2c493..c484a6fa5fa5 100644
--- a/ext/spl/tests/bug51119.phpt
+++ b/ext/spl/tests/bug51119.phpt
@@ -14,7 +14,7 @@ foreach ($limitIterator as $item) {
try {
$limitIterator = new LimitIterator($arrayIterator, -1);
} catch (\ValueError $e){
- print $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
@@ -22,4 +22,4 @@ try {
a
b
c
-LimitIterator::__construct(): Argument #2 ($offset) must be greater than or equal to 0
+ValueError: LimitIterator::__construct(): Argument #2 ($offset) must be greater than or equal to 0
diff --git a/ext/spl/tests/bug61828.phpt b/ext/spl/tests/bug61828.phpt
index 2a11b760bb35..a01f85c7b0da 100644
--- a/ext/spl/tests/bug61828.phpt
+++ b/ext/spl/tests/bug61828.phpt
@@ -7,9 +7,9 @@ $x = new DirectoryIterator('.');
try {
$x->__construct('/tmp');
} catch (\Error $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Directory object is already initialized
+Error: Directory object is already initialized
diff --git a/ext/spl/tests/bug67539.phpt b/ext/spl/tests/bug67539.phpt
index 61f70cf459bd..7149bd55a42f 100644
--- a/ext/spl/tests/bug67539.phpt
+++ b/ext/spl/tests/bug67539.phpt
@@ -9,7 +9,7 @@ function badsort($a, $b) {
try {
$GLOBALS['it']->unserialize($GLOBALS['it']->serialize());
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
return 0;
}
@@ -17,4 +17,4 @@ function badsort($a, $b) {
$it->uksort('badsort');
?>
--EXPECT--
-Modification of ArrayObject during sorting is prohibited
+Error: Modification of ArrayObject during sorting is prohibited
diff --git a/ext/spl/tests/bug70068.phpt b/ext/spl/tests/bug70068.phpt
index 54f3cca44963..adc38aff1423 100644
--- a/ext/spl/tests/bug70068.phpt
+++ b/ext/spl/tests/bug70068.phpt
@@ -5,10 +5,10 @@ Bug #70068 (Dangling pointer in the unserialization of ArrayObject items)
try {
$a = unserialize('a:3:{i:0;C:11:"ArrayObject":20:{x:i:0;r:3;;m:a:0:{};}i:1;d:11;i:2;S:31:"AAAAAAAABBBBCCCC\01\00\00\00\04\00\00\00\00\00\00\00\00\00\00";}');
} catch(Exception $e) {
- print $e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
OK
--EXPECT--
-Error at offset 10 of 20 bytes
+UnexpectedValueException: Error at offset 10 of 20 bytes
OK
diff --git a/ext/spl/tests/bug70561.phpt b/ext/spl/tests/bug70561.phpt
index c6c229ad89d0..47b1d3213747 100644
--- a/ext/spl/tests/bug70561.phpt
+++ b/ext/spl/tests/bug70561.phpt
@@ -14,10 +14,10 @@ while ($di->valid()) {
try {
$di->seek($cnt+1);
} catch (OutOfBoundsException $ex) {
- echo $ex->getMessage() . PHP_EOL;
+ echo $ex::class, ': ', $ex->getMessage(), PHP_EOL;
}
echo "Is valid? " . (int) $di->valid() . PHP_EOL;
?>
--EXPECTF--
-Seek position %d is out of range
+OutOfBoundsException: Seek position %d is out of range
Is valid? 0
diff --git a/ext/spl/tests/bug71735.phpt b/ext/spl/tests/bug71735.phpt
index 7063aaab5aad..7dd000421e08 100644
--- a/ext/spl/tests/bug71735.phpt
+++ b/ext/spl/tests/bug71735.phpt
@@ -6,8 +6,8 @@ try {
$var_1=new SplStack();
$var_1->offsetSet(100,new DateTime('2000-01-01'));
} catch(OutOfRangeException $e) {
- print $e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-SplDoublyLinkedList::offsetSet(): Argument #1 ($index) is out of range
+OutOfRangeException: SplDoublyLinkedList::offsetSet(): Argument #1 ($index) is out of range
diff --git a/ext/spl/tests/bug72684.phpt b/ext/spl/tests/bug72684.phpt
index 06665efdaab7..5962754f5606 100644
--- a/ext/spl/tests/bug72684.phpt
+++ b/ext/spl/tests/bug72684.phpt
@@ -13,9 +13,9 @@ iterator_to_array($appendIterator);
try {
iterator_to_array($appendIterator);
} catch (\Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Cannot traverse an already closed generator
+Exception: Cannot traverse an already closed generator
diff --git a/ext/spl/tests/bug72888.phpt b/ext/spl/tests/bug72888.phpt
index 5ca99a40a513..93bdaa7c3c66 100644
--- a/ext/spl/tests/bug72888.phpt
+++ b/ext/spl/tests/bug72888.phpt
@@ -7,12 +7,12 @@ $x = new SplFileObject(__FILE__);
try {
$y=clone $x;
} catch (Error $e) {
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($y);
?>
--EXPECTF--
-string(60) "Trying to clone an uncloneable object of class SplFileObject"
+Error: Trying to clone an uncloneable object of class SplFileObject
Warning: Undefined variable $y in %s on line %d
NULL
diff --git a/ext/spl/tests/bug73029.phpt b/ext/spl/tests/bug73029.phpt
index 771e81d5c4d4..cc174bd2cdf6 100644
--- a/ext/spl/tests/bug73029.phpt
+++ b/ext/spl/tests/bug73029.phpt
@@ -7,19 +7,19 @@ $a = 'C:11:"ArrayObject":19:{x:i:0;r:2;;m:a:0:{}}';
$m = unserialize($a);
$x = $m[2];
} catch(UnexpectedValueException $e) {
- print $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$a = 'C:11:"ArrayObject":19:0x:i:0;r:2;;m:a:0:{}}';
$m = unserialize($a);
$x = $m[2];
} catch(UnexpectedValueException $e) {
- print $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
DONE
--EXPECTF--
-Error at offset 10 of 19 bytes
+UnexpectedValueException: Error at offset 10 of 19 bytes
Warning: unserialize(): Error at offset 22 of 43 bytes in %s on line %d
diff --git a/ext/spl/tests/bug73629.phpt b/ext/spl/tests/bug73629.phpt
index f66c319ca184..dd6d78917681 100644
--- a/ext/spl/tests/bug73629.phpt
+++ b/ext/spl/tests/bug73629.phpt
@@ -6,13 +6,13 @@ $q = new SplQueue();
try {
$q->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO);
} catch (Exception $e) {
- echo 'unexpected exception: ' . $e->getMessage() . "\n";
+ echo 'unexpected: ', $e::class, ': ', $e->getMessage(), "\n";
}
try {
$q->setIteratorMode(SplDoublyLinkedList::IT_MODE_LIFO);
} catch (Exception $e) {
- echo 'expected exception: ' . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-expected exception: Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen
+RuntimeException: Iterators' LIFO/FIFO modes for SplStack/SplQueue objects are frozen
diff --git a/ext/spl/tests/bug79432.phpt b/ext/spl/tests/bug79432.phpt
index 1230340e991b..c3c9a9cb35f4 100644
--- a/ext/spl/tests/bug79432.phpt
+++ b/ext/spl/tests/bug79432.phpt
@@ -6,9 +6,9 @@ Bug #79432 (spl_autoload_call() with non-string argument violates assertion)
try {
spl_autoload_call([]);
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-spl_autoload_call(): Argument #1 ($class) must be of type string, array given
+TypeError: spl_autoload_call(): Argument #1 ($class) must be of type string, array given
diff --git a/ext/spl/tests/bug79987.phpt b/ext/spl/tests/bug79987.phpt
index b6ea8e2a9c41..d729f1d10cfb 100644
--- a/ext/spl/tests/bug79987.phpt
+++ b/ext/spl/tests/bug79987.phpt
@@ -13,26 +13,26 @@ set_error_handler(function ($type, $msg, $file, $line, $context = []) {
try {
var_dump($x->getLinkTarget());
} catch (Throwable $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($x->getFilename());
} catch (Throwable $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($x->getExtension());
} catch (Throwable $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($x->getBasename());
} catch (Throwable $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-Object not initialized
-Object not initialized
-Object not initialized
-Object not initialized
+Error: Object not initialized
+Error: Object not initialized
+Error: Object not initialized
+Error: Object not initialized
diff --git a/ext/spl/tests/bug80719.phpt b/ext/spl/tests/bug80719.phpt
index 506b250dae29..e0d7282fae38 100644
--- a/ext/spl/tests/bug80719.phpt
+++ b/ext/spl/tests/bug80719.phpt
@@ -7,7 +7,7 @@ $array = new ArrayObject([42]);
try {
$array->setIteratorClass(FilterIterator::class);
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
foreach ($array as $v) {
var_dump($v);
@@ -15,5 +15,5 @@ foreach ($array as $v) {
?>
--EXPECT--
-ArrayObject::setIteratorClass(): Argument #1 ($iteratorClass) must be a class name derived from ArrayIterator, FilterIterator given
+TypeError: ArrayObject::setIteratorClass(): Argument #1 ($iteratorClass) must be a class name derived from ArrayIterator, FilterIterator given
int(42)
diff --git a/ext/spl/tests/bug81992.phpt b/ext/spl/tests/bug81992.phpt
index 52235218a78f..73cda8840ad1 100644
--- a/ext/spl/tests/bug81992.phpt
+++ b/ext/spl/tests/bug81992.phpt
@@ -9,12 +9,12 @@ class InvalidDestructor {
try {
var_dump($obj[2]);
} catch (Throwable $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($obj[4]);
} catch (Throwable $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
}
}
@@ -28,5 +28,5 @@ $obj->setSize(2);
?>
--EXPECT--
string(10) "AAAAAAAAAA"
-Index invalid or out of range
-Index invalid or out of range
+OutOfBoundsException: Index invalid or out of range
+OutOfBoundsException: Index invalid or out of range
diff --git a/ext/spl/tests/class_implements_variation1.phpt b/ext/spl/tests/class_implements_variation1.phpt
index 1f7892f12834..058079ce53dd 100644
--- a/ext/spl/tests/class_implements_variation1.phpt
+++ b/ext/spl/tests/class_implements_variation1.phpt
@@ -102,7 +102,7 @@ foreach($inputs as $key =>$value) {
try {
var_dump( class_implements($value, $autoload) );
} catch (\TypeError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
};
@@ -113,61 +113,61 @@ fclose($res);
*** Testing class_implements() : variation ***
--int 0--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, int given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, int given
--int 1--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, int given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, int given
--int 12345--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, int given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, int given
--int -12345--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, int given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, int given
--float 10.5--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, float given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, float given
--float -10.5--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, float given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, float given
--float 12.3456789000e10--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, float given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, float given
--float -12.3456789000e10--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, float given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, float given
--float .5--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, float given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, float given
--empty array--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, array given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, array given
--int indexed array--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, array given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, array given
--associative array--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, array given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, array given
--nested arrays--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, array given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, array given
--uppercase NULL--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, null given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, null given
--lowercase null--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, null given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, null given
--lowercase true--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, true given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, true given
--lowercase false--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, false given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, false given
--uppercase TRUE--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, true given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, true given
--uppercase FALSE--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, false given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, false given
--empty string DQ--
Error: 2 - class_implements(): Class does not exist and could not be loaded, %s(%d)
@@ -188,10 +188,10 @@ array(0) {
}
--undefined var--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, null given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, null given
--unset var--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, null given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, null given
--resource--
-class_implements(): Argument #1 ($object_or_class) must be of type object|string, resource given
+TypeError: class_implements(): Argument #1 ($object_or_class) must be of type object|string, resource given
diff --git a/ext/spl/tests/class_uses_variation1.phpt b/ext/spl/tests/class_uses_variation1.phpt
index 016a9cc0d2f4..53e628e6fd65 100644
--- a/ext/spl/tests/class_uses_variation1.phpt
+++ b/ext/spl/tests/class_uses_variation1.phpt
@@ -102,7 +102,7 @@ foreach($inputs as $key =>$value) {
try {
var_dump( class_uses($value, $autoload) );
} catch (\TypeError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
};
@@ -113,61 +113,61 @@ fclose($res);
*** Testing class_uses() : variation ***
--int 0--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, int given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, int given
--int 1--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, int given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, int given
--int 12345--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, int given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, int given
--int -12345--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, int given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, int given
--float 10.5--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, float given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, float given
--float -10.5--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, float given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, float given
--float 12.3456789000e10--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, float given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, float given
--float -12.3456789000e10--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, float given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, float given
--float .5--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, float given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, float given
--empty array--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, array given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, array given
--int indexed array--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, array given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, array given
--associative array--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, array given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, array given
--nested arrays--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, array given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, array given
--uppercase NULL--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, null given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, null given
--lowercase null--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, null given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, null given
--lowercase true--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, true given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, true given
--lowercase false--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, false given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, false given
--uppercase TRUE--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, true given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, true given
--uppercase FALSE--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, false given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, false given
--empty string DQ--
Error: 2 - class_uses(): Class does not exist and could not be loaded, %s(%d)
@@ -186,10 +186,10 @@ array(0) {
}
--undefined var--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, null given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, null given
--unset var--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, null given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, null given
--resource--
-class_uses(): Argument #1 ($object_or_class) must be of type object|string, resource given
+TypeError: class_uses(): Argument #1 ($object_or_class) must be of type object|string, resource given
diff --git a/ext/spl/tests/countable_count_variation1.phpt b/ext/spl/tests/countable_count_variation1.phpt
index b4b382bea35c..19474d3b50aa 100644
--- a/ext/spl/tests/countable_count_variation1.phpt
+++ b/ext/spl/tests/countable_count_variation1.phpt
@@ -54,7 +54,7 @@ echo "Count throws an exception:\n";
try {
echo count(new throwException);
} catch (Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
@@ -70,4 +70,4 @@ int(1)
Count returns an array:
int(1)
Count throws an exception:
-Thrown from count
+Exception: Thrown from count
diff --git a/ext/spl/tests/dit_006.phpt b/ext/spl/tests/dit_006.phpt
index 42a2309c9925..a83dc7e75698 100644
--- a/ext/spl/tests/dit_006.phpt
+++ b/ext/spl/tests/dit_006.phpt
@@ -35,7 +35,7 @@ try {
$di->seek($o+1);
$p = 1;
} catch (\OutOfBoundsException $ex) {
- echo $ex->getMessage() . PHP_EOL;
+ echo $ex::class, ': ', $ex->getMessage(), PHP_EOL;
}
var_dump($n !== $m, $m === $o, $p === 0);
@@ -44,7 +44,7 @@ var_dump($n !== $m, $m === $o, $p === 0);
With seek(2) we get %d
With seek(0) we get %d
Without seek we get %d
-Seek position %d is out of range
+OutOfBoundsException: Seek position %d is out of range
bool(true)
bool(true)
bool(true)
diff --git a/ext/spl/tests/dllist_001.phpt b/ext/spl/tests/dllist_001.phpt
index e6ac2468afde..7f02ce6b733d 100644
--- a/ext/spl/tests/dllist_001.phpt
+++ b/ext/spl/tests/dllist_001.phpt
@@ -7,12 +7,12 @@ $dll = new SplDoublyLinkedList();
try {
$dll->pop();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$dll->shift();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
// data consistency
@@ -47,8 +47,8 @@ $dll_clone->pop();
echo count($dll)."\n";
?>
--EXPECT--
-Exception: Can't pop from an empty datastructure
-Exception: Can't shift from an empty datastructure
+RuntimeException: Can't pop from an empty datastructure
+RuntimeException: Can't shift from an empty datastructure
2
2
2
diff --git a/ext/spl/tests/dllist_004.phpt b/ext/spl/tests/dllist_004.phpt
index 8ac028ebf86f..33ed21d4a650 100644
--- a/ext/spl/tests/dllist_004.phpt
+++ b/ext/spl/tests/dllist_004.phpt
@@ -7,12 +7,12 @@ $stack = new SplStack();
try {
$stack->pop();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$stack->shift();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
// data consistency
@@ -45,8 +45,8 @@ $stack_clone->pop();
echo count($stack)."\n";
?>
--EXPECT--
-Exception: Can't pop from an empty datastructure
-Exception: Can't shift from an empty datastructure
+RuntimeException: Can't pop from an empty datastructure
+RuntimeException: Can't shift from an empty datastructure
2
2
[2]
diff --git a/ext/spl/tests/dllist_005.phpt b/ext/spl/tests/dllist_005.phpt
index 805f81a68a75..c5c8548ca7ed 100644
--- a/ext/spl/tests/dllist_005.phpt
+++ b/ext/spl/tests/dllist_005.phpt
@@ -7,12 +7,12 @@ $queue = new SplQueue();
try {
$queue->dequeue();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$queue->shift();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
// data consistency
@@ -45,8 +45,8 @@ $queue_clone->dequeue();
echo count($queue)."\n";
?>
--EXPECT--
-Exception: Can't shift from an empty datastructure
-Exception: Can't shift from an empty datastructure
+RuntimeException: Can't shift from an empty datastructure
+RuntimeException: Can't shift from an empty datastructure
2
2
[1]
diff --git a/ext/spl/tests/dllist_006.phpt b/ext/spl/tests/dllist_006.phpt
index 25b8bf330885..1d0bec1ef490 100644
--- a/ext/spl/tests/dllist_006.phpt
+++ b/ext/spl/tests/dllist_006.phpt
@@ -24,25 +24,25 @@ var_dump($a[2]);
try {
var_dump($a["1"]);
} catch (OutOfRangeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($a["a"]);
} catch (TypeError $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($a["0"]);
} catch (OutOfRangeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($a["9"]);
} catch (OutOfRangeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
@@ -54,6 +54,6 @@ Unsetting..
int(3)
int(4)
int(2)
-Exception: SplDoublyLinkedList::offsetGet(): Argument #1 ($index) must be of type int, string given
+TypeError: SplDoublyLinkedList::offsetGet(): Argument #1 ($index) must be of type int, string given
int(1)
-Exception: SplDoublyLinkedList::offsetGet(): Argument #1 ($index) is out of range
+OutOfRangeException: SplDoublyLinkedList::offsetGet(): Argument #1 ($index) is out of range
diff --git a/ext/spl/tests/dllist_013.phpt b/ext/spl/tests/dllist_013.phpt
index 2ec8396c0f52..8fc40eb877f0 100644
--- a/ext/spl/tests/dllist_013.phpt
+++ b/ext/spl/tests/dllist_013.phpt
@@ -7,7 +7,7 @@ $dll = new SplDoublyLinkedList();
try {
$dll->add(2,5);
} catch (OutOfRangeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$dll->add(0,6); // 6
@@ -40,7 +40,7 @@ var_dump($dll->shift());
?>
--EXPECT--
-Exception: SplDoublyLinkedList::add(): Argument #1 ($index) is out of range
+OutOfRangeException: SplDoublyLinkedList::add(): Argument #1 ($index) is out of range
7
7
6
diff --git a/ext/spl/tests/fixedarray_003.phpt b/ext/spl/tests/fixedarray_003.phpt
index cca9ac07e9f7..b5b3812cb713 100644
--- a/ext/spl/tests/fixedarray_003.phpt
+++ b/ext/spl/tests/fixedarray_003.phpt
@@ -14,17 +14,17 @@ $o[2.5] = 'c';
try {
$o[[]] = 'd';
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$o[new stdClass()] = 'e';
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$o[$r] = 'f';
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$o['3'] = 'g';
@@ -32,17 +32,17 @@ $o['3'] = 'g';
try {
$o['3.5'] = 'h';
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$o['03'] = 'i';
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$o[' 3'] = 'j';
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
@@ -54,17 +54,17 @@ var_dump($o[2.5]);
try {
var_dump($o[[]]);
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($o[new stdClass()]);
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($o[$r]);
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($o['3']);
@@ -72,17 +72,17 @@ var_dump($o['3']);
try {
var_dump($o['3.5']);
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($o['03']);
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($o[' 3']);
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
@@ -94,17 +94,17 @@ var_dump(isset($o[2.5]));
try {
var_dump(isset($o[[]]));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(isset($o[new stdClass()]));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(isset($o[$r]));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump(isset($o['3']));
@@ -112,17 +112,17 @@ var_dump(isset($o['3']));
try {
var_dump(isset($o['3.5']));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(isset($o['03']));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(isset($o[' 3']));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo 'empty()', \PHP_EOL;
@@ -133,17 +133,17 @@ var_dump(empty($o[2.5]));
try {
var_dump(empty($o[[]]));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(empty($o[new stdClass()]));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(empty($o[$r]));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump(empty($o['3']));
@@ -151,72 +151,72 @@ var_dump(empty($o['3']));
try {
var_dump(empty($o['3.5']));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(empty($o['03']));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(empty($o[' 3']));
} catch (\TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECTF--
Write context
Deprecated: Implicit conversion from float 2.5 to int loses precision in %s on line %d
-Cannot access offset of type array on SplFixedArray
-Cannot access offset of type stdClass on SplFixedArray
+TypeError: Cannot access offset of type array on SplFixedArray
+TypeError: Cannot access offset of type stdClass on SplFixedArray
Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
-Cannot access offset of type string on SplFixedArray
-Cannot access offset of type string on SplFixedArray
-Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
Read context
string(1) "a"
string(1) "b"
Deprecated: Implicit conversion from float 2.5 to int loses precision in %s on line %d
string(1) "c"
-Cannot access offset of type array on SplFixedArray
-Cannot access offset of type stdClass on SplFixedArray
+TypeError: Cannot access offset of type array on SplFixedArray
+TypeError: Cannot access offset of type stdClass on SplFixedArray
Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
string(1) "f"
string(1) "g"
-Cannot access offset of type string on SplFixedArray
-Cannot access offset of type string on SplFixedArray
-Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
isset()
bool(true)
bool(true)
Deprecated: Implicit conversion from float 2.5 to int loses precision in %s on line %d
bool(true)
-Cannot access offset of type array on SplFixedArray
-Cannot access offset of type stdClass on SplFixedArray
+TypeError: Cannot access offset of type array on SplFixedArray
+TypeError: Cannot access offset of type stdClass on SplFixedArray
Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
bool(true)
bool(true)
-Cannot access offset of type string on SplFixedArray
-Cannot access offset of type string on SplFixedArray
-Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
empty()
bool(false)
bool(false)
Deprecated: Implicit conversion from float 2.5 to int loses precision in %s on line %d
bool(false)
-Cannot access offset of type array on SplFixedArray
-Cannot access offset of type stdClass on SplFixedArray
+TypeError: Cannot access offset of type array on SplFixedArray
+TypeError: Cannot access offset of type stdClass on SplFixedArray
Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d
bool(false)
bool(false)
-Cannot access offset of type string on SplFixedArray
-Cannot access offset of type string on SplFixedArray
-Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
+TypeError: Cannot access offset of type string on SplFixedArray
diff --git a/ext/spl/tests/fixedarray_004.phpt b/ext/spl/tests/fixedarray_004.phpt
index c1bf3054030a..64773f7fdf5d 100644
--- a/ext/spl/tests/fixedarray_004.phpt
+++ b/ext/spl/tests/fixedarray_004.phpt
@@ -8,9 +8,9 @@ $a = new SplFixedArray(10);
try {
$a[] = 1;
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-[] operator not supported for SplFixedArray
+Error: [] operator not supported for SplFixedArray
diff --git a/ext/spl/tests/fixedarray_006.phpt b/ext/spl/tests/fixedarray_006.phpt
index 75ecbb7c7f22..6bf1ae0bc23e 100644
--- a/ext/spl/tests/fixedarray_006.phpt
+++ b/ext/spl/tests/fixedarray_006.phpt
@@ -11,12 +11,12 @@ try {
$a[] = new stdClass;
}
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
print "ok\n";
?>
--EXPECT--
-[] operator not supported for SplFixedArray
+Error: [] operator not supported for SplFixedArray
ok
diff --git a/ext/spl/tests/fixedarray_007.phpt b/ext/spl/tests/fixedarray_007.phpt
index 65b4dad90e2b..1bb80f260544 100644
--- a/ext/spl/tests/fixedarray_007.phpt
+++ b/ext/spl/tests/fixedarray_007.phpt
@@ -9,7 +9,7 @@ $a = new SplFixedArray($b);
try {
$a[1] = $a;
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
foreach ($a as $c) {
diff --git a/ext/spl/tests/fixedarray_012.phpt b/ext/spl/tests/fixedarray_012.phpt
index 0c54dc10552c..961e0022b04e 100644
--- a/ext/spl/tests/fixedarray_012.phpt
+++ b/ext/spl/tests/fixedarray_012.phpt
@@ -8,12 +8,12 @@ $a = new SplFixedArray(100);
try {
$b = &$a[];
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
print "ok\n";
?>
--EXPECT--
-[] operator not supported for SplFixedArray
+Error: [] operator not supported for SplFixedArray
ok
diff --git a/ext/spl/tests/fixedarray_013.phpt b/ext/spl/tests/fixedarray_013.phpt
index fa0d33a41655..9c6488602f7e 100644
--- a/ext/spl/tests/fixedarray_013.phpt
+++ b/ext/spl/tests/fixedarray_013.phpt
@@ -13,9 +13,9 @@ function test(SplFixedArray &$arr) {
try {
test($a[]);
} catch (\Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-[] operator not supported for SplFixedArray
+Error: [] operator not supported for SplFixedArray
diff --git a/ext/spl/tests/fixedarray_014.phpt b/ext/spl/tests/fixedarray_014.phpt
index 75108b586847..94bbfb884c33 100644
--- a/ext/spl/tests/fixedarray_014.phpt
+++ b/ext/spl/tests/fixedarray_014.phpt
@@ -7,9 +7,9 @@ try {
$a = new SplFixedArray(0);
echo $a[0]++;
} catch (Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Index invalid or out of range
+OutOfBoundsException: Index invalid or out of range
diff --git a/ext/spl/tests/fixedarray_020.phpt b/ext/spl/tests/fixedarray_020.phpt
index c0ff6e3b436c..6152e199fba7 100644
--- a/ext/spl/tests/fixedarray_020.phpt
+++ b/ext/spl/tests/fixedarray_020.phpt
@@ -14,14 +14,14 @@ try {
SplFixedArray::fromArray(array("foo"=>"bar"), false);
echo "No exception\n";
} catch (Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
echo "From Array with string keys, preserve\n";
SplFixedArray::fromArray(array("foo"=>"bar"), true);
echo "No exception\n";
} catch (Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
@@ -33,4 +33,4 @@ bool(true)
From Array with string keys, no preserve
No exception
From Array with string keys, preserve
-Exception: array must contain only positive integer keys
+InvalidArgumentException: array must contain only positive integer keys
diff --git a/ext/spl/tests/fixedarray_021.phpt b/ext/spl/tests/fixedarray_021.phpt
index 376985fd5d28..0f2bd694c67e 100644
--- a/ext/spl/tests/fixedarray_021.phpt
+++ b/ext/spl/tests/fixedarray_021.phpt
@@ -13,7 +13,7 @@ var_dump($a->count());
try {
$b = new SplFixedArray(-10);
} catch (\ValueError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
/* resize and negative value */
@@ -21,7 +21,7 @@ $b = new SplFixedArray();
try {
$b->setSize(-5);
} catch (\ValueError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
/* calling __construct() twice */
@@ -47,7 +47,7 @@ try {
var_dump($v);
}
} catch (\Error $e) {
- var_dump($e->getMessage());
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
//non-long indexes
@@ -63,14 +63,14 @@ var_dump(empty($a["3"]));
--EXPECTF--
int(0)
int(0)
-SplFixedArray::__construct(): Argument #1 ($size) must be greater than or equal to 0
-SplFixedArray::setSize(): Argument #1 ($size) must be greater than or equal to 0
+ValueError: SplFixedArray::__construct(): Argument #1 ($size) must be greater than or equal to 0
+ValueError: SplFixedArray::setSize(): Argument #1 ($size) must be greater than or equal to 0
NULL
int(0)
int(0)
object(SplFixedArray)#%d (0) {
}
-string(52) "An iterator cannot be used with foreach by reference"
+Error: An iterator cannot be used with foreach by reference
bool(false)
string(3) "foo"
bool(true)
diff --git a/ext/spl/tests/fixedarray_023.phpt b/ext/spl/tests/fixedarray_023.phpt
index 781685b7891d..9f2506eb2d87 100644
--- a/ext/spl/tests/fixedarray_023.phpt
+++ b/ext/spl/tests/fixedarray_023.phpt
@@ -33,4 +33,4 @@ object(SplFixedArray)#2 (4) refcount(6){
*RECURSION*
[3]=>
*RECURSION*
-}
\ No newline at end of file
+}
diff --git a/ext/spl/tests/gh13685.phpt b/ext/spl/tests/gh13685.phpt
index 2bdddec4584e..3f79f9280f5a 100644
--- a/ext/spl/tests/gh13685.phpt
+++ b/ext/spl/tests/gh13685.phpt
@@ -19,7 +19,7 @@ while (($data = $file->fgetcsv(',', '"', ''))) {
try {
var_dump((string) $file);
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "--- Use csv control ---\n";
@@ -35,7 +35,7 @@ foreach ($file as $row) {
try {
var_dump((string) $file);
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
diff --git a/ext/spl/tests/gh16217.phpt b/ext/spl/tests/gh16217.phpt
index 71760389c8e4..c6a0846e64f9 100644
--- a/ext/spl/tests/gh16217.phpt
+++ b/ext/spl/tests/gh16217.phpt
@@ -9,13 +9,13 @@ function uninitialized(): SplFileObject {
try {
(new ReflectionMethod(SplFileObject::class, "fputcsv"))->invoke(uninitialized(), []);
} catch (Error $e) {
- echo "fputcsv: ", $e->getMessage(), "\n";
+ echo 'fputcsv: ', $e::class, ': ', $e->getMessage(), "\n";
}
try {
(new ReflectionMethod(SplFileObject::class, "next"))->invoke(uninitialized());
} catch (Error $e) {
- echo "next: ", $e->getMessage(), "\n";
+ echo 'next: ', $e::class, ': ', $e->getMessage(), "\n";
}
$obj = uninitialized();
@@ -23,13 +23,13 @@ $obj = uninitialized();
try {
(new ReflectionMethod(SplFileObject::class, "next"))->invoke($obj);
} catch (Error $e) {
- echo "next (READ_AHEAD): ", $e->getMessage(), "\n";
+ echo 'next (READ_AHEAD): ', $e::class, ': ', $e->getMessage(), "\n";
}
echo "Done\n";
?>
--EXPECT--
-fputcsv: Object not initialized
-next: Object not initialized
-next (READ_AHEAD): Object not initialized
+fputcsv: Error: Object not initialized
+next: Error: Object not initialized
+next (READ_AHEAD): Error: Object not initialized
Done
diff --git a/ext/spl/tests/gh16337.phpt b/ext/spl/tests/gh16337.phpt
index 94cf9d90cb1a..6b6424b0f68f 100644
--- a/ext/spl/tests/gh16337.phpt
+++ b/ext/spl/tests/gh16337.phpt
@@ -9,12 +9,12 @@ class C {
try {
$heap->extract();
} catch (Throwable $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$heap->insert(1);
} catch (Throwable $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo $heap->top(), "\n";
return "0";
@@ -29,21 +29,21 @@ $heap->insert(new C);
?>
--EXPECT--
-Heap cannot be changed when it is already being modified.
-Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
0
-Heap cannot be changed when it is already being modified.
-Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
0
-Heap cannot be changed when it is already being modified.
-Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
0
-Heap cannot be changed when it is already being modified.
-Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
0
-Heap cannot be changed when it is already being modified.
-Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
0
-Heap cannot be changed when it is already being modified.
-Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
0
diff --git a/ext/spl/tests/gh16604_2.phpt b/ext/spl/tests/gh16604_2.phpt
index 703b37ce87df..042646393710 100644
--- a/ext/spl/tests/gh16604_2.phpt
+++ b/ext/spl/tests/gh16604_2.phpt
@@ -9,7 +9,7 @@ $obj = new SplFileObject(__DIR__.'/gh16604_2.tmp');
try {
$obj->__construct(__DIR__.'/gh16604_2.tmp');
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
@@ -18,4 +18,4 @@ try {
@unlink(__DIR__.'/gh16604_2.tmp');
?>
--EXPECT--
-Cannot call constructor twice
+Error: Cannot call constructor twice
diff --git a/ext/spl/tests/gh17463.phpt b/ext/spl/tests/gh17463.phpt
index 41939c62f5b2..60524dd96b27 100644
--- a/ext/spl/tests/gh17463.phpt
+++ b/ext/spl/tests/gh17463.phpt
@@ -9,8 +9,8 @@ $cls = new SplTempFileObject();
try {
$cls->ftruncate(-1);
} catch (\ValueError $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-SplFileObject::ftruncate(): Argument #1 ($size) must be greater than or equal to 0
+ValueError: SplFileObject::ftruncate(): Argument #1 ($size) must be greater than or equal to 0
diff --git a/ext/spl/tests/gh17516.phpt b/ext/spl/tests/gh17516.phpt
index f1a05f9ca184..669f2286abdd 100644
--- a/ext/spl/tests/gh17516.phpt
+++ b/ext/spl/tests/gh17516.phpt
@@ -11,7 +11,7 @@ var_dump($cls->getPathInfo('SplFileInfoChild'));
try {
$cls->getPathInfo('BadSplFileInfo');
} catch (\TypeError $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
@@ -21,4 +21,4 @@ object(SplFileInfoChild)#2 (2) {
["fileName":"SplFileInfo":private]=>
string(4) "php:"
}
-SplFileInfo::getPathInfo(): Argument #1 ($class) must be a class name derived from SplFileInfo or null, BadSplFileInfo given
+TypeError: SplFileInfo::getPathInfo(): Argument #1 ($class) must be a class name derived from SplFileInfo or null, BadSplFileInfo given
diff --git a/ext/spl/tests/gh18421.phpt b/ext/spl/tests/gh18421.phpt
index 42584ef8aacc..7b2306f0a9f6 100644
--- a/ext/spl/tests/gh18421.phpt
+++ b/ext/spl/tests/gh18421.phpt
@@ -9,9 +9,9 @@ try {
{
}
} catch (OutOfBoundsException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECTF--
-Seek position %d is out of range
+OutOfBoundsException: Seek position %d is out of range
diff --git a/ext/spl/tests/gh19094.phpt b/ext/spl/tests/gh19094.phpt
index d0665c3e8f06..6e507c26aaa0 100644
--- a/ext/spl/tests/gh19094.phpt
+++ b/ext/spl/tests/gh19094.phpt
@@ -35,22 +35,22 @@ $canary = new stdClass;
try {
$cls[$canary] = 1;
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$cls[new MyAggregate] = 1;
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$cls[new MyIterator] = 1;
try {
$cls->key();
} catch (RuntimeException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-Can only attach objects that implement the Iterator interface
-Can only attach objects that implement the Iterator interface
-Called key() with non valid sub iterator
+TypeError: Can only attach objects that implement the Iterator interface
+TypeError: Can only attach objects that implement the Iterator interface
+RuntimeException: Called key() with non valid sub iterator
diff --git a/ext/spl/tests/heap_001.phpt b/ext/spl/tests/heap_001.phpt
index 33f091838b03..438a62fe596a 100644
--- a/ext/spl/tests/heap_001.phpt
+++ b/ext/spl/tests/heap_001.phpt
@@ -8,7 +8,7 @@ $h = new SplMaxHeap();
try {
$h->extract();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
@@ -37,7 +37,7 @@ echo $h->extract()."\n";
echo $h2->extract()."\n";
?>
--EXPECT--
-Exception: Can't extract from an empty heap
+RuntimeException: Can't extract from an empty heap
5
3
3
diff --git a/ext/spl/tests/heap_002.phpt b/ext/spl/tests/heap_002.phpt
index 452fdf189a70..ce62a4bd0857 100644
--- a/ext/spl/tests/heap_002.phpt
+++ b/ext/spl/tests/heap_002.phpt
@@ -8,7 +8,7 @@ $h = new SplMinHeap();
try {
$h->extract();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
@@ -35,7 +35,7 @@ $b = 5;
echo $h->extract()."\n";
?>
--EXPECT--
-Exception: Can't extract from an empty heap
+RuntimeException: Can't extract from an empty heap
5
1
2
diff --git a/ext/spl/tests/heap_004.phpt b/ext/spl/tests/heap_004.phpt
index 3db18b673383..70f10c3ab317 100644
--- a/ext/spl/tests/heap_004.phpt
+++ b/ext/spl/tests/heap_004.phpt
@@ -18,25 +18,25 @@ try {
$h->insert(3);
echo "inserted 3\n";
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$h->insert(4);
echo "inserted 4\n";
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($h->extract());
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($h->extract());
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "Recovering..\n";
@@ -45,20 +45,20 @@ $h->recoverFromCorruption();
try {
var_dump($h->extract());
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($h->extract());
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
inserted 1
Exception: foo
-Exception: Heap is corrupted, heap properties are no longer ensured.
-Exception: Heap is corrupted, heap properties are no longer ensured.
-Exception: Heap is corrupted, heap properties are no longer ensured.
+RuntimeException: Heap is corrupted, heap properties are no longer ensured.
+RuntimeException: Heap is corrupted, heap properties are no longer ensured.
+RuntimeException: Heap is corrupted, heap properties are no longer ensured.
Recovering..
int(1)
int(2)
diff --git a/ext/spl/tests/heap_009.phpt b/ext/spl/tests/heap_009.phpt
index 833d079b253b..1b3b3a7dd3eb 100644
--- a/ext/spl/tests/heap_009.phpt
+++ b/ext/spl/tests/heap_009.phpt
@@ -13,7 +13,7 @@ function testForException( $heap )
}
catch( \Error $e )
{
- echo $e->getMessage(),"\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
}
@@ -46,9 +46,9 @@ testForException( $heap );
?>
--EXPECT--
-An iterator cannot be used with foreach by reference
-An iterator cannot be used with foreach by reference
-An iterator cannot be used with foreach by reference
-An iterator cannot be used with foreach by reference
-An iterator cannot be used with foreach by reference
-An iterator cannot be used with foreach by reference
+Error: An iterator cannot be used with foreach by reference
+Error: An iterator cannot be used with foreach by reference
+Error: An iterator cannot be used with foreach by reference
+Error: An iterator cannot be used with foreach by reference
+Error: An iterator cannot be used with foreach by reference
+Error: An iterator cannot be used with foreach by reference
diff --git a/ext/spl/tests/heap_corruption.phpt b/ext/spl/tests/heap_corruption.phpt
index 149d0b671996..9e75cce35450 100644
--- a/ext/spl/tests/heap_corruption.phpt
+++ b/ext/spl/tests/heap_corruption.phpt
@@ -48,14 +48,14 @@ try {
$heap->extract();
}
catch (Exception $e) {
- echo "Compare Exception: " . $e->getMessage() . PHP_EOL;
+ echo 'Compare: ', $e::class, ': ', $e->getMessage(), PHP_EOL;
}
try {
$heap->top();
}
catch (Exception $e) {
- echo "Corruption Exception: " . $e->getMessage() . PHP_EOL;
+ echo 'Corruption: ', $e::class, ': ', $e->getMessage(), PHP_EOL;
}
var_dump($heap->isCorrupted());
@@ -64,7 +64,7 @@ var_dump($heap->isCorrupted());
?>
--EXPECT--
bool(false)
-Compare Exception: Compare exception
-Corruption Exception: Heap is corrupted, heap properties are no longer ensured.
+Compare: Exception: Compare exception
+Corruption: RuntimeException: Heap is corrupted, heap properties are no longer ensured.
bool(true)
bool(false)
diff --git a/ext/spl/tests/heap_next_write_lock.phpt b/ext/spl/tests/heap_next_write_lock.phpt
index fcad94f3ccd3..f8beafbddddf 100644
--- a/ext/spl/tests/heap_next_write_lock.phpt
+++ b/ext/spl/tests/heap_next_write_lock.phpt
@@ -26,7 +26,7 @@ try {
$q->insert("d$i", 100 - $i);
}
} catch (RuntimeException $e) {
- echo $e::class, ": ", $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
diff --git a/ext/spl/tests/heap_top_variation_002.phpt b/ext/spl/tests/heap_top_variation_002.phpt
index 0a9a8db613be..48f995e9c234 100644
--- a/ext/spl/tests/heap_top_variation_002.phpt
+++ b/ext/spl/tests/heap_top_variation_002.phpt
@@ -24,8 +24,8 @@ try {
try {
$h->top();
} catch (Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Heap is corrupted, heap properties are no longer ensured.
+RuntimeException: Heap is corrupted, heap properties are no longer ensured.
diff --git a/ext/spl/tests/heap_top_variation_003.phpt b/ext/spl/tests/heap_top_variation_003.phpt
index 40d70c5966b9..466723c1220b 100644
--- a/ext/spl/tests/heap_top_variation_003.phpt
+++ b/ext/spl/tests/heap_top_variation_003.phpt
@@ -9,8 +9,8 @@ $h = new SplMinHeap();
try {
$h->top();
} catch (Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Can't peek at an empty heap
+RuntimeException: Can't peek at an empty heap
diff --git a/ext/spl/tests/heap_unserialize_under_corruption_or_modification.phpt b/ext/spl/tests/heap_unserialize_under_corruption_or_modification.phpt
index 2e54be09ad1a..0523aad9f47a 100644
--- a/ext/spl/tests/heap_unserialize_under_corruption_or_modification.phpt
+++ b/ext/spl/tests/heap_unserialize_under_corruption_or_modification.phpt
@@ -22,9 +22,9 @@ $heap->insert(0);
try {
$heap->insert(2);
} catch (RuntimeException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-Heap cannot be changed when it is already being modified.
+RuntimeException: Heap cannot be changed when it is already being modified.
diff --git a/ext/spl/tests/iterator_022.phpt b/ext/spl/tests/iterator_022.phpt
index fda42a97c830..afe024df0df2 100644
--- a/ext/spl/tests/iterator_022.phpt
+++ b/ext/spl/tests/iterator_022.phpt
@@ -121,7 +121,7 @@ try
}
catch(UnexpectedValueException $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
@@ -180,4 +180,4 @@ MyRecursiveArrayIterator::valid = false
RecursiveArrayIteratorIterator::endChildren(1)
RecursiveArrayIteratorIterator::callHasChildren(0) = yes/yes
RecursiveArrayIteratorIterator::callGetChildren(skip)
-Objects returned by RecursiveIterator::getChildren() must implement RecursiveIterator
+UnexpectedValueException: Objects returned by RecursiveIterator::getChildren() must implement RecursiveIterator
diff --git a/ext/spl/tests/iterator_023.phpt b/ext/spl/tests/iterator_023.phpt
index 8c7121ff2cb5..2ce54132abc3 100644
--- a/ext/spl/tests/iterator_023.phpt
+++ b/ext/spl/tests/iterator_023.phpt
@@ -121,7 +121,7 @@ try
}
catch(UnexpectedValueException $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
diff --git a/ext/spl/tests/iterator_024.phpt b/ext/spl/tests/iterator_024.phpt
index 21f0216d9b97..9fc13e82d3e7 100644
--- a/ext/spl/tests/iterator_024.phpt
+++ b/ext/spl/tests/iterator_024.phpt
@@ -16,7 +16,7 @@ try
}
catch (InvalidArgumentException $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "===MANUAL===\n";
@@ -35,7 +35,7 @@ foreach(new RecursiveIteratorIterator($it) as $v) echo "$v\n";
331
4
string(13) "ArrayIterator"
-An instance of RecursiveIterator or IteratorAggregate creating it is required
+InvalidArgumentException: An instance of RecursiveIterator or IteratorAggregate creating it is required
===MANUAL===
string(22) "RecursiveArrayIterator"
1
diff --git a/ext/spl/tests/iterator_028.phpt b/ext/spl/tests/iterator_028.phpt
index 92e00b4f78b3..9f9990e4b0dc 100644
--- a/ext/spl/tests/iterator_028.phpt
+++ b/ext/spl/tests/iterator_028.phpt
@@ -43,7 +43,7 @@ $it->setMaxDepth(4);
try {
$it->setMaxDepth(-2);
} catch(\ValueError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
var_dump($it->getMaxDepth());
?>
@@ -102,5 +102,5 @@ int(0)
0: 4
===-1===
bool(false)
-RecursiveIteratorIterator::setMaxDepth(): Argument #1 ($maxDepth) must be greater than or equal to -1
+ValueError: RecursiveIteratorIterator::setMaxDepth(): Argument #1 ($maxDepth) must be greater than or equal to -1
int(4)
diff --git a/ext/spl/tests/iterator_030.phpt b/ext/spl/tests/iterator_030.phpt
index 6a684ec30004..0520260b6909 100644
--- a/ext/spl/tests/iterator_030.phpt
+++ b/ext/spl/tests/iterator_030.phpt
@@ -17,7 +17,7 @@ try
}
catch(BadMethodCallException $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try
@@ -26,7 +26,7 @@ try
}
catch(BadMethodCallException $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
var_dump($it->valid());
@@ -36,6 +36,6 @@ var_dump($it->valid());
bool(false)
bool(false)
bool(false)
-Accessing the key of an EmptyIterator
-Accessing the value of an EmptyIterator
+BadMethodCallException: Accessing the key of an EmptyIterator
+BadMethodCallException: Accessing the value of an EmptyIterator
bool(false)
diff --git a/ext/spl/tests/iterator_031.phpt b/ext/spl/tests/iterator_031.phpt
index c2b5885dd23e..388512e48506 100644
--- a/ext/spl/tests/iterator_031.phpt
+++ b/ext/spl/tests/iterator_031.phpt
@@ -60,7 +60,7 @@ $ap = new MyAppendIterator;
try {
$ap->append($it);
} catch(\Error $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$ap->parent__construct();
@@ -68,7 +68,7 @@ $ap->parent__construct();
try {
$ap->parent__construct($it);
} catch(BadMethodCallException $e) {
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$ap->append($it);
@@ -87,8 +87,8 @@ MyArrayIterator::rewind
1=>2
MyAppendIterator::__construct
MyAppendIterator::append
-The object is in an invalid state as the parent constructor was not called
-AppendIterator::getIterator() must be called exactly once per instance
+Error: The object is in an invalid state as the parent constructor was not called
+BadMethodCallException: AppendIterator::getIterator() must be called exactly once per instance
MyAppendIterator::append
MyArrayIterator::rewind
MyAppendIterator::append
diff --git a/ext/spl/tests/iterator_032.phpt b/ext/spl/tests/iterator_032.phpt
index 9f56d7574db7..a08320cc56d7 100644
--- a/ext/spl/tests/iterator_032.phpt
+++ b/ext/spl/tests/iterator_032.phpt
@@ -17,7 +17,7 @@ try
}
catch(OutOfBoundsException $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$it->seek(2);
@@ -29,7 +29,7 @@ try
}
catch(OutOfBoundsException $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$it->next();
@@ -41,7 +41,7 @@ var_dump($it->valid());
int(1)
2=>3
int(2)
-Cannot seek to 0 which is below the offset 1
+OutOfBoundsException: Cannot seek to 0 which is below the offset 1
int(3)
-Cannot seek to 3 which is behind offset 1 plus count 2
+OutOfBoundsException: Cannot seek to 3 which is behind offset 1 plus count 2
bool(false)
diff --git a/ext/spl/tests/iterator_037.phpt b/ext/spl/tests/iterator_037.phpt
index c6c465baa2bf..011c63138bcd 100644
--- a/ext/spl/tests/iterator_037.phpt
+++ b/ext/spl/tests/iterator_037.phpt
@@ -10,7 +10,7 @@ function test($ar, $flags)
try {
$it->setFlags($flags);
} catch (\ValueError $e) {
- echo 'Exception: ' . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
var_dump($it->getFlags());
return;
}
@@ -21,7 +21,7 @@ function test($ar, $flags)
var_dump((string)$it);
}
} catch (Exception $e) {
- echo 'Exception: ' . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
}
@@ -66,7 +66,7 @@ try
}
catch (Exception $e)
{
- echo 'Exception: ' . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try
{
@@ -75,7 +75,7 @@ try
}
catch (Exception $e)
{
- echo 'Exception: ' . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
@@ -101,20 +101,20 @@ string(3) "0:1"
string(3) "1:2"
string(3) "2:3"
===3===
-Exception: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
+ValueError: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
int(0)
===5===
-Exception: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
+ValueError: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
int(0)
===9===
-Exception: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
+ValueError: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
int(0)
===6===
-Exception: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
+ValueError: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
int(0)
===10===
-Exception: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
+ValueError: CachingIterator::setFlags(): Argument #1 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
int(0)
===X===
-Exception: Unsetting flag CALL_TO_STRING is not possible
-Exception: Unsetting flag TOSTRING_USE_INNER is not possible
+InvalidArgumentException: Unsetting flag CALL_TO_STRING is not possible
+InvalidArgumentException: Unsetting flag TOSTRING_USE_INNER is not possible
diff --git a/ext/spl/tests/iterator_041.phpt b/ext/spl/tests/iterator_041.phpt
index 1fc73c1a1dda..3d3266db66cc 100644
--- a/ext/spl/tests/iterator_041.phpt
+++ b/ext/spl/tests/iterator_041.phpt
@@ -72,7 +72,7 @@ class MyArrayIterator extends ArrayIterator
}
catch (Exception $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
if (isset($skip[self::$fail]))
{
@@ -92,13 +92,13 @@ MyArrayIterator::test('iterator_count', array(3 => 6));
?>
--EXPECT--
===iterator_to_array===
-State 0: __construct()
-State 1: __construct()
-State 2: rewind()
-State 3: valid()
-State 4: current()
-State 5: key()
-State 6: next()
+Exception: State 0: __construct()
+Exception: State 1: __construct()
+Exception: State 2: rewind()
+Exception: State 3: valid()
+Exception: State 4: current()
+Exception: State 5: key()
+Exception: State 6: next()
array(2) {
[0]=>
int(1)
@@ -106,9 +106,9 @@ array(2) {
int(2)
}
===iterator_count===
-State 0: __construct()
-State 1: __construct()
-State 2: rewind()
-State 3: valid()
-State 6: next()
+Exception: State 0: __construct()
+Exception: State 1: __construct()
+Exception: State 2: rewind()
+Exception: State 3: valid()
+Exception: State 6: next()
int(2)
diff --git a/ext/spl/tests/iterator_041a.phpt b/ext/spl/tests/iterator_041a.phpt
index d57735dc2cd0..5a316a109a3c 100644
--- a/ext/spl/tests/iterator_041a.phpt
+++ b/ext/spl/tests/iterator_041a.phpt
@@ -72,7 +72,7 @@ class MyArrayIterator extends ArrayIterator
}
catch (Exception $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
if (isset($skip[self::$fail]))
{
@@ -92,7 +92,7 @@ MyArrayIterator::test('iterator_count', array(3 => 6));
?>
--EXPECT--
===iterator_to_array===
-State 7: __destruct()
+Exception: State 7: __destruct()
array(2) {
[0]=>
int(1)
@@ -100,5 +100,5 @@ array(2) {
int(2)
}
===iterator_count===
-State 7: __destruct()
+Exception: State 7: __destruct()
int(2)
diff --git a/ext/spl/tests/iterator_041b.phpt b/ext/spl/tests/iterator_041b.phpt
index 83d9388161e3..48c57882826d 100644
--- a/ext/spl/tests/iterator_041b.phpt
+++ b/ext/spl/tests/iterator_041b.phpt
@@ -72,7 +72,7 @@ class MyArrayIterator extends ArrayIterator
}
catch (Exception $e)
{
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
if (isset($skip[self::$fail]))
{
@@ -96,14 +96,14 @@ MyArrayIterator::test('iterator_count', array(3 => 6));
?>
--EXPECT--
===iterator_to_array===
-State 0: __construct()
-State 1: __construct()
-State 2: rewind()
-State 3: valid()
-State 4: current()
-State 5: key()
-State 6: next()
-State 7: __destruct()
+Exception: State 0: __construct()
+Exception: State 1: __construct()
+Exception: State 2: rewind()
+Exception: State 3: valid()
+Exception: State 4: current()
+Exception: State 5: key()
+Exception: State 6: next()
+Exception: State 7: __destruct()
array(2) {
[0]=>
int(1)
@@ -111,10 +111,10 @@ array(2) {
int(2)
}
===iterator_count===
-State 0: __construct()
-State 1: __construct()
-State 2: rewind()
-State 3: valid()
-State 6: next()
-State 7: __destruct()
+Exception: State 0: __construct()
+Exception: State 1: __construct()
+Exception: State 2: rewind()
+Exception: State 3: valid()
+Exception: State 6: next()
+Exception: State 7: __destruct()
int(2)
diff --git a/ext/spl/tests/iterator_044.phpt b/ext/spl/tests/iterator_044.phpt
index 74321194e098..64b545118bbb 100644
--- a/ext/spl/tests/iterator_044.phpt
+++ b/ext/spl/tests/iterator_044.phpt
@@ -27,12 +27,12 @@ class MyCachingIterator extends CachingIterator
try {
var_dump($this->offsetExists($v));
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($this->offsetGet($v));
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
}
}
@@ -46,7 +46,7 @@ try
}
catch(Exception $e)
{
- echo "Exception: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try
@@ -55,7 +55,7 @@ try
}
catch(Exception $e)
{
- echo "Exception: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$it = new MyCachingIterator(new ArrayIterator(array(0, 'foo'=>1, 2, 'bar'=>3, 4)), CachingIterator::FULL_CACHE);
@@ -72,8 +72,8 @@ $it->test($checks);
?>
--EXPECTF--
-Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct)
-Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct)
+BadMethodCallException: MyCachingIterator does not use a full cache (see CachingIterator::__construct)
+BadMethodCallException: MyCachingIterator does not use a full cache (see CachingIterator::__construct)
===0===
int(0)
bool(false)
@@ -83,8 +83,8 @@ NULL
===1===
object(stdClass)#%d (0) {
}
-CachingIterator::offsetExists(): Argument #1 ($key) must be of type string, stdClass given
-CachingIterator::offsetGet(): Argument #1 ($key) must be of type string, stdClass given
+TypeError: CachingIterator::offsetExists(): Argument #1 ($key) must be of type string, stdClass given
+TypeError: CachingIterator::offsetGet(): Argument #1 ($key) must be of type string, stdClass given
===2===
object(MyFoo)#%d (0) {
}
@@ -128,8 +128,8 @@ int(0)
===1===
object(stdClass)#1 (0) {
}
-CachingIterator::offsetExists(): Argument #1 ($key) must be of type string, stdClass given
-CachingIterator::offsetGet(): Argument #1 ($key) must be of type string, stdClass given
+TypeError: CachingIterator::offsetExists(): Argument #1 ($key) must be of type string, stdClass given
+TypeError: CachingIterator::offsetGet(): Argument #1 ($key) must be of type string, stdClass given
===2===
object(MyFoo)#2 (0) {
}
diff --git a/ext/spl/tests/iterator_045.phpt b/ext/spl/tests/iterator_045.phpt
index e245b9568886..fed62cc1e71c 100644
--- a/ext/spl/tests/iterator_045.phpt
+++ b/ext/spl/tests/iterator_045.phpt
@@ -59,7 +59,7 @@ try
}
catch(Exception $e)
{
- echo "Exception: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try
@@ -68,7 +68,7 @@ try
}
catch(Exception $e)
{
- echo "Exception: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$it = new MyCachingIterator(new ArrayIterator(array(0, 1, 2, 3)), CachingIterator::FULL_CACHE);
@@ -89,8 +89,8 @@ $it->show();
?>
--EXPECT--
-Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct)
-Exception: MyCachingIterator does not use a full cache (see CachingIterator::__construct)
+BadMethodCallException: MyCachingIterator does not use a full cache (see CachingIterator::__construct)
+BadMethodCallException: MyCachingIterator does not use a full cache (see CachingIterator::__construct)
MyCachingIterator::testSet()
set(0,25)
set(1,42)
diff --git a/ext/spl/tests/iterator_047.phpt b/ext/spl/tests/iterator_047.phpt
index 353990856bd8..e5fd299acc36 100644
--- a/ext/spl/tests/iterator_047.phpt
+++ b/ext/spl/tests/iterator_047.phpt
@@ -48,7 +48,7 @@ class MyRecursiveCachingIterator extends RecursiveCachingIterator
}
catch (Exception $e)
{
- echo "Exception: " . $e->getMessage() . " in " . $e->getFile() . " on line " . $e->getLine() . "\n";
+ echo $e::class, ': ', $e->getMessage(), ' in ', $e->getFile(), "\n";
}
MyRecursiveArrayIterator::$fail++;
}
@@ -88,14 +88,14 @@ int(4)
int(4)
===1===
MyRecursiveArrayIterator::hasChildren()
-Exception: State 1: MyRecursiveArrayIterator::hasChildren() in %s on line %d
+Exception: State 1: MyRecursiveArrayIterator::hasChildren() in %s
===2===
MyRecursiveArrayIterator::hasChildren()
int(0)
int(0)
MyRecursiveArrayIterator::hasChildren()
MyRecursiveArrayIterator::getChildren()
-Exception: State 2: MyRecursiveArrayIterator::getChildren() in %s on line %d
+Exception: State 2: MyRecursiveArrayIterator::getChildren() in %s
===3===
MyRecursiveArrayIterator::hasChildren()
int(0)
diff --git a/ext/spl/tests/iterator_056.phpt b/ext/spl/tests/iterator_056.phpt
index 84427b8707dc..477d71037bb9 100644
--- a/ext/spl/tests/iterator_056.phpt
+++ b/ext/spl/tests/iterator_056.phpt
@@ -22,43 +22,43 @@ class myNoRewindIterator extends NoRewindIterator {}
try {
$it = new myFilterIterator();
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$it = new myCachingIterator();
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$it = new myRecursiveCachingIterator();
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$it = new myParentIterator();
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$it = new myLimitIterator();
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$it = new myNoRewindIterator();
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-FilterIterator::__construct() expects exactly 1 argument, 0 given
-CachingIterator::__construct() expects at least 1 argument, 0 given
-RecursiveCachingIterator::__construct() expects at least 1 argument, 0 given
-ParentIterator::__construct() expects exactly 1 argument, 0 given
-LimitIterator::__construct() expects at least 1 argument, 0 given
-NoRewindIterator::__construct() expects exactly 1 argument, 0 given
+ArgumentCountError: FilterIterator::__construct() expects exactly 1 argument, 0 given
+ArgumentCountError: CachingIterator::__construct() expects at least 1 argument, 0 given
+ArgumentCountError: RecursiveCachingIterator::__construct() expects at least 1 argument, 0 given
+ArgumentCountError: ParentIterator::__construct() expects exactly 1 argument, 0 given
+ArgumentCountError: LimitIterator::__construct() expects at least 1 argument, 0 given
+ArgumentCountError: NoRewindIterator::__construct() expects exactly 1 argument, 0 given
diff --git a/ext/spl/tests/iterator_062.phpt b/ext/spl/tests/iterator_062.phpt
index 904b7f0ccfdf..bbea651c223f 100644
--- a/ext/spl/tests/iterator_062.phpt
+++ b/ext/spl/tests/iterator_062.phpt
@@ -11,8 +11,8 @@ class myRecursiveIteratorIterator extends RecursiveIteratorIterator {
try {
$it = new myRecursiveIteratorIterator();
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-RecursiveIteratorIterator::__construct() expects at least 1 argument, 0 given
+ArgumentCountError: RecursiveIteratorIterator::__construct() expects at least 1 argument, 0 given
diff --git a/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt b/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt
index c5fc21ea8bc7..b0635e34c1fe 100644
--- a/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt
+++ b/ext/spl/tests/iterator_to_array_nonscalar_keys.phpt
@@ -15,7 +15,7 @@ function gen() {
try {
var_dump(iterator_to_array(gen()));
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
@@ -23,4 +23,4 @@ try {
Deprecated: Implicit conversion from float 2.5 to int loses precision in %s on line %d
Deprecated: Using null as an array offset is deprecated, use an empty string instead in %s on line %d
-Cannot access offset of type array on array
+TypeError: Cannot access offset of type array on array
diff --git a/ext/spl/tests/multiple_iterator_001.phpt b/ext/spl/tests/multiple_iterator_001.phpt
index e022b54dafd4..5b7f76fbd573 100644
--- a/ext/spl/tests/multiple_iterator_001.phpt
+++ b/ext/spl/tests/multiple_iterator_001.phpt
@@ -16,12 +16,12 @@ foreach($m as $value) {
try {
var_dump($m->current());
} catch (RuntimeException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($m->key());
} catch (RuntimeException $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$m->attachIterator($iter1);
@@ -38,12 +38,12 @@ foreach($m as $key => $value) {
try {
$m->current();
} catch(RuntimeException $e) {
- echo "RuntimeException thrown: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$m->key();
} catch(RuntimeException $e) {
- echo "RuntimeException thrown: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "-- Flags = MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC --\n";
@@ -71,7 +71,7 @@ $m->rewind();
try {
$m->current();
} catch(InvalidArgumentException $e) {
- echo "InvalidArgumentException thrown: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "-- Flags |= MultipleIterator::MIT_KEYS_ASSOC --\n";
@@ -89,7 +89,7 @@ echo "-- Associate with invalid value --\n";
try {
$m->attachIterator($iter3, new stdClass());
} catch(TypeError $e) {
- echo "TypeError thrown: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "-- Associate with duplicate value --\n";
@@ -97,7 +97,7 @@ echo "-- Associate with duplicate value --\n";
try {
$m->attachIterator($iter3, "iter1");
} catch(InvalidArgumentException $e) {
- echo "InvalidArgumentException thrown: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "-- Count, contains, detach, count, contains, iterate --\n";
@@ -114,8 +114,8 @@ foreach($m as $key => $value) {
?>
--EXPECTF--
-- Default flags, no iterators --
-Called current() on an invalid iterator
-Called key() on an invalid iterator
+RuntimeException: Called current() on an invalid iterator
+RuntimeException: Called key() on an invalid iterator
-- Default flags, MultipleIterator::MIT_NEED_ALL | MultipleIterator::MIT_KEYS_NUMERIC --
bool(true)
array(3) {
@@ -151,8 +151,8 @@ array(3) {
[2]=>
string(6) "string"
}
-RuntimeException thrown: Called current() with non valid sub iterator
-RuntimeException thrown: Called key() with non valid sub iterator
+RuntimeException: Called current() with non valid sub iterator
+RuntimeException: Called key() with non valid sub iterator
-- Flags = MultipleIterator::MIT_NEED_ANY | MultipleIterator::MIT_KEYS_NUMERIC --
bool(true)
array(3) {
@@ -255,7 +255,7 @@ array(3) {
int(3)
}
-- Flags |= MultipleIterator::MIT_KEYS_ASSOC, with iterator associated with NULL --
-InvalidArgumentException thrown: Sub-Iterator is associated with NULL
+InvalidArgumentException: Sub-Iterator is associated with NULL
-- Flags |= MultipleIterator::MIT_KEYS_ASSOC --
array(3) {
["iter1"]=>
@@ -307,9 +307,9 @@ array(3) {
int(3)
}
-- Associate with invalid value --
-TypeError thrown: MultipleIterator::attachIterator(): Argument #2 ($info) must be of type string|int|null, stdClass given
+TypeError: MultipleIterator::attachIterator(): Argument #2 ($info) must be of type string|int|null, stdClass given
-- Associate with duplicate value --
-InvalidArgumentException thrown: Key duplication error
+InvalidArgumentException: Key duplication error
-- Count, contains, detach, count, contains, iterate --
int(3)
bool(true)
diff --git a/ext/spl/tests/pqueue_001.phpt b/ext/spl/tests/pqueue_001.phpt
index a318487273eb..fd0629b62146 100644
--- a/ext/spl/tests/pqueue_001.phpt
+++ b/ext/spl/tests/pqueue_001.phpt
@@ -8,7 +8,7 @@ $pq = new SplPriorityQueue();
try {
$pq->extract();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$pq->insert("a", 1);
@@ -60,7 +60,7 @@ foreach ($pq3 as $k=>$v) {
?>
--EXPECT--
-Exception: Can't extract from an empty heap
+RuntimeException: Can't extract from an empty heap
2=>b
1=>a
0=>c
diff --git a/ext/spl/tests/pqueue_002.phpt b/ext/spl/tests/pqueue_002.phpt
index df4a64f4b2d0..c33477e96528 100644
--- a/ext/spl/tests/pqueue_002.phpt
+++ b/ext/spl/tests/pqueue_002.phpt
@@ -18,25 +18,25 @@ try {
$h->insert(3, 1);
echo "inserted 3\n";
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$h->insert(4, 1);
echo "inserted 4\n";
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($h->extract());
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($h->extract());
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "Recovering..\n";
@@ -45,20 +45,20 @@ $h->recoverFromCorruption();
try {
var_dump($h->extract());
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump($h->extract());
} catch(Exception $e) {
- echo "Exception: ".$e->getMessage()."\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
inserted 1
Exception: foo
-Exception: Heap is corrupted, heap properties are no longer ensured.
-Exception: Heap is corrupted, heap properties are no longer ensured.
-Exception: Heap is corrupted, heap properties are no longer ensured.
+RuntimeException: Heap is corrupted, heap properties are no longer ensured.
+RuntimeException: Heap is corrupted, heap properties are no longer ensured.
+RuntimeException: Heap is corrupted, heap properties are no longer ensured.
Recovering..
int(1)
int(2)
diff --git a/ext/spl/tests/recursive_tree_iterator_002.phpt b/ext/spl/tests/recursive_tree_iterator_002.phpt
index 01f12bf59538..6f2262dc275f 100644
--- a/ext/spl/tests/recursive_tree_iterator_002.phpt
+++ b/ext/spl/tests/recursive_tree_iterator_002.phpt
@@ -7,8 +7,8 @@ error_reporting=E_ALL&~E_NOTICE
try {
new RecursiveTreeIterator();
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-RecursiveTreeIterator::__construct() expects at least 1 argument, 0 given
+ArgumentCountError: RecursiveTreeIterator::__construct() expects at least 1 argument, 0 given
diff --git a/ext/spl/tests/recursive_tree_iterator_003.phpt b/ext/spl/tests/recursive_tree_iterator_003.phpt
index 80225720f27b..f1898206eb08 100644
--- a/ext/spl/tests/recursive_tree_iterator_003.phpt
+++ b/ext/spl/tests/recursive_tree_iterator_003.phpt
@@ -5,8 +5,8 @@ SPL: RecursiveTreeIterator(non-traversable)
try {
new RecursiveTreeIterator(new ArrayIterator(array()));
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-RecursiveCachingIterator::__construct(): Argument #1 ($iterator) must be of type RecursiveIterator, ArrayIterator given
+TypeError: RecursiveCachingIterator::__construct(): Argument #1 ($iterator) must be of type RecursiveIterator, ArrayIterator given
diff --git a/ext/spl/tests/recursive_tree_iterator_007.phpt b/ext/spl/tests/recursive_tree_iterator_007.phpt
index 75f1e6386c8e..996ef3fbef2c 100644
--- a/ext/spl/tests/recursive_tree_iterator_007.phpt
+++ b/ext/spl/tests/recursive_tree_iterator_007.phpt
@@ -24,7 +24,7 @@ try {
echo "[$k] => $v\n";
}
} catch (Error $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
@@ -34,4 +34,4 @@ try {
[1] => \-Array
Deprecated: ArrayIterator::__construct(): Using an object as a backing array for ArrayIterator is deprecated, as it allows violating class constraints and invariants in %s on line %d
-Object of class stdClass could not be converted to string
+Error: Object of class stdClass could not be converted to string
diff --git a/ext/spl/tests/recursive_tree_iterator_008.phpt b/ext/spl/tests/recursive_tree_iterator_008.phpt
index 2dd531882463..339eb14635ea 100644
--- a/ext/spl/tests/recursive_tree_iterator_008.phpt
+++ b/ext/spl/tests/recursive_tree_iterator_008.phpt
@@ -21,12 +21,12 @@ foreach($it as $k => $v) {
try {
$it->setPrefixPart(-1, "");
} catch (\ValueError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
try {
$it->setPrefixPart(6, "");
} catch (\ValueError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
@@ -34,5 +34,5 @@ try {
[0] => 0145b
[c] => 045Array
[0] => 0245d
-RecursiveTreeIterator::setPrefixPart(): Argument #1 ($part) must be a RecursiveTreeIterator::PREFIX_* constant
-RecursiveTreeIterator::setPrefixPart(): Argument #1 ($part) must be a RecursiveTreeIterator::PREFIX_* constant
+ValueError: RecursiveTreeIterator::setPrefixPart(): Argument #1 ($part) must be a RecursiveTreeIterator::PREFIX_* constant
+ValueError: RecursiveTreeIterator::setPrefixPart(): Argument #1 ($part) must be a RecursiveTreeIterator::PREFIX_* constant
diff --git a/ext/spl/tests/regexIterator_setMode_error.phpt b/ext/spl/tests/regexIterator_setMode_error.phpt
index 10df255f4a01..808fb2c960be 100644
--- a/ext/spl/tests/regexIterator_setMode_error.phpt
+++ b/ext/spl/tests/regexIterator_setMode_error.phpt
@@ -13,12 +13,12 @@ var_dump($regexIterator->getMode());
try {
$regexIterator->setMode(7);
} catch (\ValueError $e) {
- echo $e->getMessage() . \PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
var_dump($e->getCode());
}
?>
--EXPECT--
int(0)
-RegexIterator::setMode(): Argument #1 ($mode) must be RegexIterator::MATCH, RegexIterator::GET_MATCH, RegexIterator::ALL_MATCHES, RegexIterator::SPLIT, or RegexIterator::REPLACE
+ValueError: RegexIterator::setMode(): Argument #1 ($mode) must be RegexIterator::MATCH, RegexIterator::GET_MATCH, RegexIterator::ALL_MATCHES, RegexIterator::SPLIT, or RegexIterator::REPLACE
int(0)
diff --git a/ext/spl/tests/spl_004.phpt b/ext/spl/tests/spl_004.phpt
index 3538fa6b489c..8c61739d96e8 100644
--- a/ext/spl/tests/spl_004.phpt
+++ b/ext/spl/tests/spl_004.phpt
@@ -45,17 +45,17 @@ echo "===ERRORS===\n";
try {
var_dump(iterator_apply($it, 'test', 1));
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(iterator_apply($it, 'non_existing_function'));
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
var_dump(iterator_apply($it, 'non_existing_function', NULL, 2));
} catch (TypeError $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
@@ -84,6 +84,6 @@ int(5)
int(6)
int(4)
===ERRORS===
-iterator_apply(): Argument #3 ($args) must be of type ?array, int given
-iterator_apply(): Argument #2 ($callback) must be a valid callback, function "non_existing_function" not found or invalid function name
-iterator_apply() expects at most 3 arguments, 4 given
+TypeError: iterator_apply(): Argument #3 ($args) must be of type ?array, int given
+TypeError: iterator_apply(): Argument #2 ($callback) must be a valid callback, function "non_existing_function" not found or invalid function name
+ArgumentCountError: iterator_apply() expects at most 3 arguments, 4 given
diff --git a/ext/spl/tests/spl_caching_iterator_constructor_flags.phpt b/ext/spl/tests/spl_caching_iterator_constructor_flags.phpt
index 0d107d206f4a..9676ceae82c5 100644
--- a/ext/spl/tests/spl_caching_iterator_constructor_flags.phpt
+++ b/ext/spl/tests/spl_caching_iterator_constructor_flags.phpt
@@ -16,10 +16,10 @@ new CachingIterator($arrayIterator, CachingIterator::TOSTRING_USE_INNER);
try {
$test = new CachingIterator($arrayIterator, 3); // this throws an exception
} catch (\ValueError $e){
- print $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-CachingIterator::__construct(): Argument #2 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
+ValueError: CachingIterator::__construct(): Argument #2 ($flags) must contain only one of CachingIterator::CALL_TOSTRING, CachingIterator::TOSTRING_USE_KEY, CachingIterator::TOSTRING_USE_CURRENT, or CachingIterator::TOSTRING_USE_INNER
diff --git a/ext/spl/tests/spl_heap_count_basic.phpt b/ext/spl/tests/spl_heap_count_basic.phpt
index e8be968e06d4..42ecd2cfc5ae 100644
--- a/ext/spl/tests/spl_heap_count_basic.phpt
+++ b/ext/spl/tests/spl_heap_count_basic.phpt
@@ -26,7 +26,7 @@ $heap->insert(1);
try {
count($heap);// refers to MyHeap->count() method
} catch (Exception $e) {
- echo "Exception: " . $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
diff --git a/ext/spl/tests/spl_iterator_apply_error.phpt b/ext/spl/tests/spl_iterator_apply_error.phpt
index 2a5caa008670..c047c6fc5b3f 100644
--- a/ext/spl/tests/spl_iterator_apply_error.phpt
+++ b/ext/spl/tests/spl_iterator_apply_error.phpt
@@ -16,11 +16,11 @@ $it = new MyArrayIterator(array(1, 21, 22));
try {
$res = iterator_apply($it, 'test');
} catch (Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Make the iterator break
+Exception: Make the iterator break
diff --git a/ext/spl/tests/spl_iterator_apply_error_001.phpt b/ext/spl/tests/spl_iterator_apply_error_001.phpt
index 9c021cf98fe0..c4c239578ebf 100644
--- a/ext/spl/tests/spl_iterator_apply_error_001.phpt
+++ b/ext/spl/tests/spl_iterator_apply_error_001.phpt
@@ -12,9 +12,9 @@ $it = new RecursiveArrayIterator(array(1, 21, 22));
try {
iterator_apply($it, 'test');
} catch (Exception $e) {
- echo $e->getMessage();
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Broken callback
+Exception: Broken callback
diff --git a/ext/spl/tests/spl_iterator_getcallchildren.phpt b/ext/spl/tests/spl_iterator_getcallchildren.phpt
index 8a0d1cd735be..04701b5394e5 100644
--- a/ext/spl/tests/spl_iterator_getcallchildren.phpt
+++ b/ext/spl/tests/spl_iterator_getcallchildren.phpt
@@ -17,7 +17,7 @@ try {
$output = $test->callGetChildren();
} catch (TypeError $exception) {
$output = null;
- echo $exception->getMessage() . "\n";
+ echo $exception::class, ': ', $exception->getMessage(), "\n";
}
var_dump($output);
@@ -33,5 +33,5 @@ array(3) {
int(9)
}
int(7)
-ArrayIterator::__construct(): Argument #1 ($array) must be of type array, int given
+TypeError: ArrayIterator::__construct(): Argument #1 ($array) must be of type array, int given
NULL
diff --git a/ext/spl/tests/spl_iterator_iterator_constructor.phpt b/ext/spl/tests/spl_iterator_iterator_constructor.phpt
index 2349a13e3160..f7ed07265e45 100644
--- a/ext/spl/tests/spl_iterator_iterator_constructor.phpt
+++ b/ext/spl/tests/spl_iterator_iterator_constructor.phpt
@@ -16,9 +16,9 @@ try {
$test = new IteratorIterator($arrayIterator, 1, 1, 1);
$test = new IteratorIterator($arrayIterator, 1, 1, 1, 1);
} catch (TypeError $e){
- echo $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
-IteratorIterator::__construct() expects at most 2 arguments, 3 given
+ArgumentCountError: IteratorIterator::__construct() expects at most 2 arguments, 3 given
diff --git a/ext/spl/tests/spl_iterator_to_array_error.phpt b/ext/spl/tests/spl_iterator_to_array_error.phpt
index 1185f8082d29..467b6901f555 100644
--- a/ext/spl/tests/spl_iterator_to_array_error.phpt
+++ b/ext/spl/tests/spl_iterator_to_array_error.phpt
@@ -15,19 +15,19 @@ try {
// get keys
$ar = iterator_to_array($it);
} catch (Exception $e) {
- echo $e->getMessage() . PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
try {
// get values
$ar = iterator_to_array($it, false);
} catch (Exception $e) {
- echo $e->getMessage() . PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Make the iterator break
-Make the iterator break
+Exception: Make the iterator break
+Exception: Make the iterator break
diff --git a/ext/spl/tests/spl_limit_iterator_check_limits.phpt b/ext/spl/tests/spl_limit_iterator_check_limits.phpt
index 3cf4bbab175e..a7c85decb1cb 100644
--- a/ext/spl/tests/spl_limit_iterator_check_limits.phpt
+++ b/ext/spl/tests/spl_limit_iterator_check_limits.phpt
@@ -11,18 +11,18 @@ $arrayIterator = new ArrayIterator($array);
try {
$limitIterator = new LimitIterator($arrayIterator, -1);
} catch (\ValueError $e){
- print $e->getMessage(). "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
$limitIterator = new LimitIterator($arrayIterator, 0, -2);
} catch (\ValueError $e){
- print $e->getMessage() . "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
$limitIterator = new LimitIterator($arrayIterator, 0, -1);
?>
--EXPECT--
-LimitIterator::__construct(): Argument #2 ($offset) must be greater than or equal to 0
-LimitIterator::__construct(): Argument #3 ($limit) must be greater than or equal to -1
+ValueError: LimitIterator::__construct(): Argument #2 ($offset) must be greater than or equal to 0
+ValueError: LimitIterator::__construct(): Argument #3 ($limit) must be greater than or equal to -1
diff --git a/ext/spl/tests/spl_pq_top_error_corrupt.phpt b/ext/spl/tests/spl_pq_top_error_corrupt.phpt
index 60f532b02fe8..f8b33e37dd62 100644
--- a/ext/spl/tests/spl_pq_top_error_corrupt.phpt
+++ b/ext/spl/tests/spl_pq_top_error_corrupt.phpt
@@ -30,9 +30,9 @@ try {
try {
$priorityQueue->top();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage().PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Exception: Heap is corrupted, heap properties are no longer ensured.
+RuntimeException: Heap is corrupted, heap properties are no longer ensured.
diff --git a/ext/spl/tests/spl_pq_top_error_empty.phpt b/ext/spl/tests/spl_pq_top_error_empty.phpt
index 9e2a31bbc07a..62d74f1f6f8d 100644
--- a/ext/spl/tests/spl_pq_top_error_empty.phpt
+++ b/ext/spl/tests/spl_pq_top_error_empty.phpt
@@ -11,9 +11,9 @@ $priorityQueue = new SplPriorityQueue();
try {
$priorityQueue->top();
} catch (RuntimeException $e) {
- echo "Exception: ".$e->getMessage().PHP_EOL;
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}
?>
--EXPECT--
-Exception: Can't peek at an empty heap
+RuntimeException: Can't peek at an empty heap
diff --git a/ext/spl/tests/unserialize_errors.phpt b/ext/spl/tests/unserialize_errors.phpt
index 64356923ae29..ee616129ac59 100644
--- a/ext/spl/tests/unserialize_errors.phpt
+++ b/ext/spl/tests/unserialize_errors.phpt
@@ -9,38 +9,38 @@ try {
// empty array
unserialize('O:11:"ArrayObject":0:{}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:11:"ArrayObject":3:{i:0;b:1;i:1;a:0:{}i:2;a:0:{}}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:11:"ArrayObject":3:{i:0;i:0;i:1;a:0:{}i:2;i:0;}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:11:"ArrayObject":3:{i:0;i:0;i:1;i:0;i:2;a:0:{}}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
// iterator class name is not a string
unserialize('O:11:"ArrayObject":4:{i:0;i:0;i:1;i:0;i:2;a:0:{}i:3;i:0;}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:11:"ArrayObject":4:{i:0;i:0;i:1;a:2:{i:0;i:1;i:1;i:2;}i:2;a:0:{}i:3;s:11:"NonExistent";}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
class Existent {}
@@ -48,7 +48,7 @@ class Existent {}
try {
unserialize('O:11:"ArrayObject":4:{i:0;i:0;i:1;a:2:{i:0;i:1;i:1;i:2;}i:2;a:0:{}i:3;s:8:"Existent";}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "ArrayIterator:\n";
@@ -56,25 +56,25 @@ echo "ArrayIterator:\n";
try {
unserialize('O:13:"ArrayIterator":0:{}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:13:"ArrayIterator":3:{i:0;b:1;i:1;a:0:{}i:2;a:0:{}}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:13:"ArrayIterator":3:{i:0;i:0;i:1;a:0:{}i:2;i:0;}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:13:"ArrayIterator":3:{i:0;i:0;i:1;i:0;i:2;a:0:{}}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "SplDoublyLinkedList:\n";
@@ -82,25 +82,25 @@ echo "SplDoublyLinkedList:\n";
try {
unserialize('O:19:"SplDoublyLinkedList":0:{}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:19:"SplDoublyLinkedList":3:{i:0;b:1;i:1;a:0:{}i:2;a:0:{}}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:19:"SplDoublyLinkedList":3:{i:0;i:0;i:1;a:0:{}i:2;i:0;}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:19:"SplDoublyLinkedList":3:{i:0;i:0;i:1;i:0;i:2;a:0:{}}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
echo "SplObjectStorage:\n";
@@ -108,56 +108,56 @@ echo "SplObjectStorage:\n";
try {
unserialize('O:16:"SplObjectStorage":0:{}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:16:"SplObjectStorage":2:{i:0;i:0;i:1;a:0:{}}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:16:"SplObjectStorage":2:{i:0;a:0:{}i:1;i:1;}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:16:"SplObjectStorage":2:{i:0;a:1:{i:0;i:0;}i:1;a:0:{}}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
try {
unserialize('O:16:"SplObjectStorage":2:{i:0;a:2:{i:0;i:0;i:1;i:0;}i:1;a:0:{}}');
} catch (Exception $e) {
- echo $e->getMessage(), "\n";
+ echo $e::class, ': ', $e->getMessage(), "\n";
}
?>
--EXPECT--
ArrayObject:
-Incomplete or ill-typed serialization data
-Incomplete or ill-typed serialization data
-Incomplete or ill-typed serialization data
-Passed variable is not an array or object
-Incomplete or ill-typed serialization data
-Cannot deserialize ArrayObject with iterator class 'NonExistent'; no such class exists
-Cannot deserialize ArrayObject with iterator class 'Existent'; this class is not derived from ArrayIterator
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Incomplete or ill-typed serialization data
+InvalidArgumentException: Passed variable is not an array or object
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Cannot deserialize ArrayObject with iterator class 'NonExistent'; no such class exists
+UnexpectedValueException: Cannot deserialize ArrayObject with iterator class 'Existent'; this class is not derived from ArrayIterator
ArrayIterator:
-Incomplete or ill-typed serialization data
-Incomplete or ill-typed serialization data
-Incomplete or ill-typed serialization data
-Passed variable is not an array or object
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Incomplete or ill-typed serialization data
+InvalidArgumentException: Passed variable is not an array or object
SplDoublyLinkedList:
-Incomplete or ill-typed serialization data
-Incomplete or ill-typed serialization data
-Incomplete or ill-typed serialization data
-Incomplete or ill-typed serialization data
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Incomplete or ill-typed serialization data
SplObjectStorage:
-Incomplete or ill-typed serialization data
-Incomplete or ill-typed serialization data
-Incomplete or ill-typed serialization data
-Odd number of elements
-Non-object key
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Incomplete or ill-typed serialization data
+UnexpectedValueException: Odd number of elements
+UnexpectedValueException: Non-object key
diff --git a/ext/standard/io_poll.c b/ext/standard/io_poll.c
index ca363c7b37d9..f57813874d52 100644
--- a/ext/standard/io_poll.c
+++ b/ext/standard/io_poll.c
@@ -19,6 +19,7 @@
#include "php_poll.h"
#include "io_poll_arginfo.h"
#include "io_poll_decl.h"
+#include "ext/date/php_time.h"
/* Class entries */
static zend_class_entry *php_io_poll_backend_class_entry;
@@ -774,38 +775,28 @@ PHP_METHOD(Io_Poll_Context, add)
PHP_METHOD(Io_Poll_Context, wait)
{
- zend_long timeout_seconds = -1;
- bool timeout_seconds_is_null = true;
- zend_long timeout_microseconds = 0;
+ php_date_time_duration *timeout = NULL;
zend_long max_events = 0;
bool max_events_is_null = true;
- ZEND_PARSE_PARAMETERS_START(0, 3)
+ ZEND_PARSE_PARAMETERS_START(0, 2)
Z_PARAM_OPTIONAL
- Z_PARAM_LONG_OR_NULL(timeout_seconds, timeout_seconds_is_null)
- Z_PARAM_LONG(timeout_microseconds)
+ Z_PARAM_DATE_TIME_DURATION_OR_NULL(timeout)
Z_PARAM_LONG_OR_NULL(max_events, max_events_is_null)
ZEND_PARSE_PARAMETERS_END();
php_io_poll_context_object *intern = PHP_POLL_CONTEXT_OBJ_FROM_ZV(getThis());
- /* Build timespec from seconds + microseconds, or NULL for indefinite */
- struct timespec ts;
- const struct timespec *timeout = NULL;
- if (timeout_seconds >= 0) {
- if (timeout_microseconds < 0) {
- zend_argument_value_error(2, "must be greater than or equal to 0");
+ /* Build timespec from php_date_time_duration, or NULL for indefinite */
+ struct timespec timeout_ts;
+ if (timeout) {
+ if (timeout->duration.negative) {
+ zend_argument_value_error(1, "must not be negative");
RETURN_THROWS();
}
- /* Allow microseconds >= 1000000, carry overflow into seconds
- * (same behavior as stream_select) */
- ts.tv_sec = (time_t) (timeout_seconds + (timeout_microseconds / 1000000));
- ts.tv_nsec = (long) ((timeout_microseconds % 1000000) * 1000);
- timeout = &ts;
- } else if (!timeout_seconds_is_null) {
- zend_argument_value_error(1, "must be greater than or equal to 0");
- RETURN_THROWS();
+ timeout_ts.tv_sec = timeout->duration.seconds;
+ timeout_ts.tv_nsec = timeout->duration.nanoseconds;
}
if (max_events_is_null) {
@@ -814,12 +805,12 @@ PHP_METHOD(Io_Poll_Context, wait)
max_events = 64;
}
} else if (max_events <= 0) {
- zend_argument_value_error(3, "must be greater than 0");
+ zend_argument_value_error(2, "must be greater than 0");
RETURN_THROWS();
}
php_poll_event *events = safe_emalloc(max_events, sizeof(*events), 0);
- int num_events = php_poll_wait(intern->ctx, events, (int) max_events, timeout);
+ int num_events = php_poll_wait(intern->ctx, events, (int) max_events, timeout ? &timeout_ts : NULL);
if (num_events < 0) {
php_poll_error err = php_poll_get_error(intern->ctx);
diff --git a/ext/standard/io_poll.stub.php b/ext/standard/io_poll.stub.php
index 83c1ba5cbe2e..e3bcbf11c871 100644
--- a/ext/standard/io_poll.stub.php
+++ b/ext/standard/io_poll.stub.php
@@ -86,7 +86,7 @@ public function __construct(Backend $backend = Backend::Auto) {}
public function add(Handle $handle, array $events, mixed $data = null): Watcher {}
/** @return list */
- public function wait(?int $timeoutSeconds = null, int $timeoutMicroseconds = 0, ?int $maxEvents = null): array {}
+ public function wait(?\Time\Duration $timeout = null, ?int $maxEvents = null): array {}
public function getBackend(): Backend {}
}
diff --git a/ext/standard/io_poll_arginfo.h b/ext/standard/io_poll_arginfo.h
index 5fc62f629564..801df235c26b 100644
--- a/ext/standard/io_poll_arginfo.h
+++ b/ext/standard/io_poll_arginfo.h
@@ -1,5 +1,5 @@
/* This is a generated file, edit io_poll.stub.php instead.
- * Stub hash: a7450146c5b3b3f3486611c83a55cf0cc932b27a
+ * Stub hash: 2f52b00fd6dfc62291e0dd288ffd68547b29bdaa
* Has decl header: yes */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Backend_getAvailableBackends, 0, 0, IS_ARRAY, 0)
@@ -56,8 +56,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Io_Poll_Context_add, 0, 2,
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Io_Poll_Context_wait, 0, 0, IS_ARRAY, 0)
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeoutSeconds, IS_LONG, 1, "null")
- ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, timeoutMicroseconds, IS_LONG, 0, "0")
+ ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, timeout, Time\\Duration, 1, "null")
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, maxEvents, IS_LONG, 1, "null")
ZEND_END_ARG_INFO()
diff --git a/ext/standard/io_poll_decl.h b/ext/standard/io_poll_decl.h
index 2b09e3665f58..de49880392a7 100644
--- a/ext/standard/io_poll_decl.h
+++ b/ext/standard/io_poll_decl.h
@@ -1,8 +1,8 @@
/* This is a generated file, edit io_poll.stub.php instead.
- * Stub hash: a7450146c5b3b3f3486611c83a55cf0cc932b27a */
+ * Stub hash: 2f52b00fd6dfc62291e0dd288ffd68547b29bdaa */
-#ifndef ZEND_IO_POLL_DECL_a7450146c5b3b3f3486611c83a55cf0cc932b27a_H
-#define ZEND_IO_POLL_DECL_a7450146c5b3b3f3486611c83a55cf0cc932b27a_H
+#ifndef ZEND_IO_POLL_DECL_2f52b00fd6dfc62291e0dd288ffd68547b29bdaa_H
+#define ZEND_IO_POLL_DECL_2f52b00fd6dfc62291e0dd288ffd68547b29bdaa_H
typedef enum zend_enum_Io_Poll_Backend {
ZEND_ENUM_Io_Poll_Backend_Auto = 1,
@@ -23,4 +23,4 @@ typedef enum zend_enum_Io_Poll_Event {
ZEND_ENUM_Io_Poll_Event_EdgeTriggered = 7,
} zend_enum_Io_Poll_Event;
-#endif /* ZEND_IO_POLL_DECL_a7450146c5b3b3f3486611c83a55cf0cc932b27a_H */
+#endif /* ZEND_IO_POLL_DECL_2f52b00fd6dfc62291e0dd288ffd68547b29bdaa_H */
diff --git a/ext/standard/tests/poll/poll_ctx_wait.phpt b/ext/standard/tests/poll/poll_ctx_wait.phpt
new file mode 100644
index 000000000000..5080c1421fdb
--- /dev/null
+++ b/ext/standard/tests/poll/poll_ctx_wait.phpt
@@ -0,0 +1,24 @@
+--TEST--
+Io\Poll\Context::wait(): Parameter validation
+--FILE--
+wait(timeout: Time\Duration::fromSeconds(1)->negate());
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+try {
+ $poll_ctx->wait(maxEvents: -1);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+ValueError: Io\Poll\Context::wait(): Argument #1 ($timeout) must not be negative
+ValueError: Io\Poll\Context::wait(): Argument #2 ($maxEvents) must be greater than 0
diff --git a/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt b/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt
index 4f32ec28c88d..3e64d950c19e 100644
--- a/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_modify_write.phpt
@@ -10,7 +10,7 @@ $poll_ctx = pt_new_stream_poll();
$watcher = pt_stream_poll_add($poll_ctx, $socket2, [Io\Poll\Event::Write], "socket_data");
$watcher->modify([Io\Poll\Event::Write], "modified_data");
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'modified_data']
]);
?>
diff --git a/ext/standard/tests/poll/poll_stream_sock_read.phpt b/ext/standard/tests/poll/poll_stream_sock_read.phpt
index 70aebc9cd926..0b44a3d14eac 100644
--- a/ext/standard/tests/poll/poll_stream_sock_read.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_read.phpt
@@ -10,7 +10,7 @@ $poll_ctx = pt_new_stream_poll();
pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read], "socket_data");
fwrite($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Read], 'data' => 'socket_data', 'read' => 'test data']
]);
diff --git a/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt b/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt
index c5fec5391652..2662a4e1f4c1 100644
--- a/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_remove_write.phpt
@@ -11,14 +11,14 @@ $poll_ctx = pt_new_stream_poll();
$watcher1w = pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write], "socket_data_1");
pt_stream_poll_add($poll_ctx, $socket2w, [Io\Poll\Event::Write], "socket_data_2");
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket_data_1'],
['events' => [Io\Poll\Event::Write], 'data' => 'socket_data_2']
]);
$watcher1w->remove();
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket_data_2']
]);
diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt
index 3909dea58637..f81ac40bcfab 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_close.phpt
@@ -13,7 +13,7 @@ pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write], "socket2_data")
fwrite($socket1w, "test data");
fclose($socket1r);
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
[
'events' => [
'default' => [Io\Poll\Event::Write, Io\Poll\Event::Error, Io\Poll\Event::HangUp],
@@ -28,7 +28,7 @@ pt_expect_events($poll_ctx->wait(0, 100000), [
], $poll_ctx);
fclose($socket1w);
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt
index d78d3f4fde35..c7374d2986e0 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_max_events.phpt
@@ -23,14 +23,14 @@ for ($i = 0; $i < 4; $i++) {
];
}
-pt_expect_events($poll_ctx->wait(0, 100000, 8), $expected);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000), 8), $expected);
// All read data was drained above, so only write events remain
$expected = [];
for ($i = 0; $i < 4; $i++) {
$expected[] = ['events' => [Io\Poll\Event::Write], 'data' => "sock$i"];
}
-pt_expect_events($poll_ctx->wait(0, 100000, 8), $expected);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000), 8), $expected);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt
index f25cb973ddce..63b22bd94941 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_multi_edge.phpt
@@ -15,32 +15,32 @@ $poll_ctx = pt_new_stream_poll();
pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read, Io\Poll\Event::EdgeTriggered], "socket1_data");
pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write, Io\Poll\Event::EdgeTriggered], "socket2_data");
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data']
]);
-pt_expect_events($poll_ctx->wait(0), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), []);
fwrite($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data']
]);
fwrite($socket1w, "more data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data']
]);
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
fwrite($socket1w, " and even more data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'more data and even more data']
]);
fclose($socket1r);
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
[
'events' => ['default' => [Io\Poll\Event::Write, Io\Poll\Event::HangUp]],
'data' => 'socket2_data'
@@ -48,7 +48,7 @@ pt_expect_events($poll_ctx->wait(0, 100000), [
], $poll_ctx);
fclose($socket1w);
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt
index 8bc8ea7fcc3d..639420872614 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_multi_level.phpt
@@ -10,39 +10,39 @@ $poll_ctx = pt_new_stream_poll();
pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read], "socket1_data");
pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write], "socket2_data");
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data']
]);
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data']
]);
fwrite($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data']
]);
fwrite($socket1w, "more data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data']
]);
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data']
]);
fwrite($socket1w, " and even more data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'more data and even more data']
]);
fclose($socket1r);
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
[
'events' => [
'default' => [Io\Poll\Event::Write, Io\Poll\Event::HangUp],
@@ -56,7 +56,7 @@ pt_expect_events($poll_ctx->wait(0, 100000), [
], $poll_ctx);
fclose($socket1w);
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt
index 4a7b67b8243f..29432b7f95af 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_single_edge.phpt
@@ -15,11 +15,11 @@ $poll_ctx = pt_new_stream_poll();
pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read, Io\Poll\Event::EdgeTriggered], "socket1_data");
pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write, Io\Poll\Event::EdgeTriggered], "socket2_data");
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data']
]);
fwrite($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data']
]);
diff --git a/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt b/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt
index a807e573c5fe..f0a64fc06387 100644
--- a/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_rw_single_level.phpt
@@ -10,11 +10,11 @@ $poll_ctx = pt_new_stream_poll();
pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read], "socket1_data");
pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write], "socket2_data");
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data']
]);
fwrite($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket2_data'],
['events' => [Io\Poll\Event::Read], 'data' => 'socket1_data', 'read' => 'test data']
]);
diff --git a/ext/standard/tests/poll/poll_stream_sock_write.phpt b/ext/standard/tests/poll/poll_stream_sock_write.phpt
index 2d937d7e9a3b..1bfb0524ec87 100644
--- a/ext/standard/tests/poll/poll_stream_sock_write.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_write.phpt
@@ -9,7 +9,7 @@ $poll_ctx = pt_new_stream_poll();
pt_stream_poll_add($poll_ctx, $socket1w, [Io\Poll\Event::Write], "socket_data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Write], 'data' => 'socket_data']
]);
diff --git a/ext/standard/tests/poll/poll_stream_sock_write_close.phpt b/ext/standard/tests/poll/poll_stream_sock_write_close.phpt
index 8927e017b05d..49e452907f20 100644
--- a/ext/standard/tests/poll/poll_stream_sock_write_close.phpt
+++ b/ext/standard/tests/poll/poll_stream_sock_write_close.phpt
@@ -13,7 +13,7 @@ pt_stream_poll_add($poll_ctx, $socket2w, [Io\Poll\Event::Write], "socket2w_data"
fclose($socket1w);
fclose($socket2w);
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_read.phpt b/ext/standard/tests/poll/poll_stream_tcp_read.phpt
index 71c7af0ca734..e9296a266e04 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_read.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_read.phpt
@@ -10,7 +10,7 @@ $poll_ctx = pt_new_stream_poll();
pt_stream_poll_add($poll_ctx, $socket1r, [Io\Poll\Event::Read], "socket_data");
pt_write_sleep($socket1w, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Read], 'data' => 'socket_data', 'read' => 'test data']
]);
diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt
index f927e73ed4d3..bb2c734cbf2c 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_read_max_events.phpt
@@ -19,7 +19,7 @@ for ($i = 0; $i < count($clients); $i++) {
// events must be delivered by the following wait() without any duplicates.
$seen = [];
for ($round = 1; $round <= 2; $round++) {
- $watchers = $poll_ctx->wait(0, 100000, 4);
+ $watchers = $poll_ctx->wait(Time\Duration::fromMicroseconds(100000), 4);
echo "Round $round count: " . count($watchers) . "\n";
foreach ($watchers as $watcher) {
$data = $watcher->getData();
@@ -35,7 +35,7 @@ for ($round = 1; $round <= 2; $round++) {
ksort($seen);
echo "Seen: " . implode(',', array_keys($seen)) . "\n";
-pt_expect_events($poll_ctx->wait(0), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), []);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt
index db2ff71fb7c8..bc49571ca8ef 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_read_multiple_level.phpt
@@ -11,7 +11,7 @@ for ($i = 0; $i < count($servers); $i++) {
pt_stream_poll_add($poll_ctx, $servers[$i], [Io\Poll\Event::Read], "server{$i}_data");
}
-pt_expect_events($poll_ctx->wait(0), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), []);
for ($i = 0; $i < count($clients); $i++) {
pt_write_sleep($clients[$i], "test $i data");
@@ -22,16 +22,16 @@ $expected_events = [];
for ($i = 0; $i < 20; $i++) {
$expected_events[] = ['events' => [Io\Poll\Event::Read], 'data' => "server{$i}_data", 'read' => "test $i data"];
}
-pt_expect_events($poll_ctx->wait(0, 100000), $expected_events);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), $expected_events);
pt_write_sleep($clients[1], "more data");
pt_write_sleep($clients[2], "more data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Read], 'data' => 'server1_data', 'read' => 'more data'],
['events' => [Io\Poll\Event::Read], 'data' => 'server2_data', 'read' => 'more data']
]);
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt
index 02db6355ca1a..c8f7c424b3dc 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot.phpt
@@ -13,18 +13,18 @@ pt_stream_poll_add($poll_ctx, $server1, [Io\Poll\Event::Read, Io\Poll\Event::One
pt_stream_poll_add($poll_ctx, $client2, [Io\Poll\Event::Read, Io\Poll\Event::OneShot], "client2_data");
pt_stream_poll_add($poll_ctx, $server2, [Io\Poll\Event::Read, Io\Poll\Event::OneShot], "server2_data");
-pt_expect_events($poll_ctx->wait(0), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), []);
pt_write_sleep($client1, "test data");
pt_write_sleep($client2, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Read], 'data' => 'server1_data', 'read' => 'test data'],
['events' => [Io\Poll\Event::Read], 'data' => 'server2_data', 'read' => 'test data']
]);
pt_write_sleep($client1, "more data");
pt_write_sleep($client2, "more data");
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt
index d7a2e48be6f4..73142b16f636 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_read_one_shot_max_events.phpt
@@ -20,7 +20,7 @@ for ($i = 0; $i < count($clients); $i++) {
// them, and each oneshot event must be delivered exactly once.
$seen = [];
for ($round = 1; $round <= 2; $round++) {
- $watchers = $poll_ctx->wait(0, 100000, 4);
+ $watchers = $poll_ctx->wait(Time\Duration::fromMicroseconds(100000), 4);
echo "Round $round count: " . count($watchers) . "\n";
foreach ($watchers as $watcher) {
$data = $watcher->getData();
@@ -36,7 +36,7 @@ echo "Seen: " . implode(',', array_keys($seen)) . "\n";
// Every oneshot watcher fired once, so new data must not be reported
pt_write_sleep($clients[0], "more data");
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt
index 6132975e1b50..79db5608b974 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot.phpt
@@ -10,16 +10,16 @@ $poll_ctx = pt_new_stream_poll();
pt_stream_poll_add($poll_ctx, $client, [Io\Poll\Event::Read, Io\Poll\Event::Write, Io\Poll\Event::OneShot], "client_data");
pt_stream_poll_add($poll_ctx, $server, [Io\Poll\Event::Read, Io\Poll\Event::Write, Io\Poll\Event::OneShot], "server_data");
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'client_data'],
['events' => [Io\Poll\Event::Write], 'data' => 'server_data']
]);
pt_write_sleep($client, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
pt_write_sleep($client, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt
index c480caf1b73d..b8646f252e70 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_rw_one_shot_mixed.phpt
@@ -11,13 +11,13 @@ pt_stream_poll_add($poll_ctx, $client, [Io\Poll\Event::Read, Io\Poll\Event::Writ
pt_stream_poll_add($poll_ctx, $server, [Io\Poll\Event::Read, Io\Poll\Event::Write, Io\Poll\Event::OneShot], "server_data");
pt_write_sleep($client, "test data");
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'client_data'],
['events' => [Io\Poll\Event::Read, Io\Poll\Event::Write], 'data' => 'server_data']
]);
pt_write_sleep($client, "test data");
-pt_expect_events($poll_ctx->wait(0, 100000), []);
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), []);
?>
--EXPECT--
diff --git a/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt b/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt
index f29a74f19edd..9300e2266f37 100644
--- a/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt
+++ b/ext/standard/tests/poll/poll_stream_tcp_rw_single_level.phpt
@@ -10,14 +10,14 @@ $poll_ctx = pt_new_stream_poll();
pt_stream_poll_add($poll_ctx, $client, [Io\Poll\Event::Read, Io\Poll\Event::Write], "client_data");
pt_stream_poll_add($poll_ctx, $server, [Io\Poll\Event::Read, Io\Poll\Event::Write], "server_data");
-pt_expect_events($poll_ctx->wait(0), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromSeconds(0)), [
['events' => [Io\Poll\Event::Write], 'data' => 'client_data'],
['events' => [Io\Poll\Event::Write], 'data' => 'server_data']
]);
fwrite($client, "test data");
usleep(10000);
-pt_expect_events($poll_ctx->wait(0, 100000), [
+pt_expect_events($poll_ctx->wait(Time\Duration::fromMicroseconds(100000)), [
['events' => [Io\Poll\Event::Write], 'data' => 'client_data'],
['events' => [Io\Poll\Event::Read, Io\Poll\Event::Write], 'data' => 'server_data', 'read' => 'test data']
]);
diff --git a/ext/standard/tests/poll/poll_stream_wait_no_add.phpt b/ext/standard/tests/poll/poll_stream_wait_no_add.phpt
index a297fa5e1162..14789d709f6b 100644
--- a/ext/standard/tests/poll/poll_stream_wait_no_add.phpt
+++ b/ext/standard/tests/poll/poll_stream_wait_no_add.phpt
@@ -4,7 +4,7 @@ Poll stream - only wait
wait(0, 100000);
+$events = $poll_ctx->wait(Time\Duration::fromMicroseconds(100000));
pt_print_events($events);
?>
diff --git a/ext/standard/tests/serialize/unserialize_callback_func/gh23082.phpt b/ext/standard/tests/serialize/unserialize_callback_func/gh23082.phpt
new file mode 100644
index 000000000000..adbc5e892655
--- /dev/null
+++ b/ext/standard/tests/serialize/unserialize_callback_func/gh23082.phpt
@@ -0,0 +1,23 @@
+--TEST--
+Bug GH-23082: unserialize_callback_func can no longer be reset to its empty default at runtime
+--FILE--
+
+--EXPECT--
+string(0) ""
+string(11) "my_callback"
+string(0) ""
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
index 27647c907d3a..eca9660c5605 100644
--- a/ext/standard/var_unserializer.re
+++ b/ext/standard/var_unserializer.re
@@ -1249,7 +1249,7 @@ object ":" uiv ":" ["] {
}
/* Check for unserialize callback */
- if (PG(unserialize_callback_func) == NULL) {
+ if (PG(unserialize_callback_func) == NULL || zend_string_equals(PG(unserialize_callback_func), zend_empty_string)) {
incomplete_class = 1;
ce = PHP_IC_ENTRY;
break;
diff --git a/main/SAPI.c b/main/SAPI.c
index 3daa88e07f25..7de36af440c3 100644
--- a/main/SAPI.c
+++ b/main/SAPI.c
@@ -495,9 +495,11 @@ SAPI_API void sapi_deactivate_module(void)
}
if (SG(request_info).content_type_dup) {
efree(SG(request_info).content_type_dup);
+ SG(request_info).content_type_dup = NULL;
}
if (SG(request_info).current_user) {
zend_string_release_ex(SG(request_info).current_user, false);
+ SG(request_info).current_user = NULL;
}
if (sapi_module.deactivate) {
sapi_module.deactivate();
diff --git a/main/main.c b/main/main.c
index 2eb55c5cff07..0539220de362 100644
--- a/main/main.c
+++ b/main/main.c
@@ -824,7 +824,7 @@ PHP_INI_BEGIN()
STD_PHP_INI_BOOLEAN("auto_globals_jit", "1", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, auto_globals_jit, php_core_globals, core_globals)
STD_PHP_INI_BOOLEAN("short_open_tag", DEFAULT_SHORT_OPEN_TAG, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, short_tags, zend_compiler_globals, compiler_globals)
- STD_PHP_INI_ENTRY("unserialize_callback_func", NULL, PHP_INI_ALL, OnUpdateStrNotEmpty, unserialize_callback_func, php_core_globals, core_globals)
+ STD_PHP_INI_ENTRY("unserialize_callback_func", NULL, PHP_INI_ALL, OnUpdateStr, unserialize_callback_func, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("serialize_precision", "-1", PHP_INI_ALL, OnSetSerializePrecision, serialize_precision, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("arg_separator.output", "&", PHP_INI_ALL, OnUpdateStrNotEmpty, arg_separator.output, php_core_globals, core_globals)
STD_PHP_INI_ENTRY("arg_separator.input", "&", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateStrNotEmpty, arg_separator.input, php_core_globals, core_globals)
diff --git a/sapi/fpm/tests/tester.inc b/sapi/fpm/tests/tester.inc
index 907988654337..557f8c25e193 100644
--- a/sapi/fpm/tests/tester.inc
+++ b/sapi/fpm/tests/tester.inc
@@ -225,7 +225,7 @@ class Tester
*/
static public function findExecutable(): bool|string
{
- $phpPath = getenv("TEST_PHP_EXECUTABLE");
+ $phpPath = getenv("TEST_PHP_FPM_EXECUTABLE") ?: getenv("TEST_PHP_EXECUTABLE");
for ($i = 0; $i < 2; $i++) {
$slashPosition = strrpos($phpPath, "/");
if ($slashPosition) {