diff --git a/NEWS b/NEWS index b99bdc51e87c..c4b6eacb6069 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,8 @@ PHP NEWS (Sjoerd Langkemper) . Raise a value error when the callback registered with CURLOPT_READFUNCTION returns an unexpected long. (Sjoerd Langkemper) + . Fix bug GH-16513 (curl: exceptions in callbacks do not abort the request). + (Sjoerd Langkemper) - Date: . Update timelib to 2026.02. (Derick, timwolla) @@ -42,6 +44,10 @@ PHP NEWS . Fixed bug GH-23016 (NULL values in long columns come back as garbage binary strings). (Calvin Buckley, iliaal) +- Readline: + . Fixed the interactive shell not waiting for the pager process to exit. + (Weilin Du) + - Reflection: . Added ReflectionAttribute::inNamespace(), ReflectionAttribute::getNamespaceName(), and diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 6554c752b8af..28cefb1e0afb 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -197,6 +197,9 @@ PHP 8.6 INTERNALS UPGRADE NOTES zend_reflection_property_set_raw_value() to expose the functionality of ReflectionProperty::setRawValueWithoutLazyInitialization() and ReflectionProperty::setRawValue() to C extensions. + . Added zend_object_set_properties_reinitable() to centralise temporarily + allowing reinitialisation of initialised readonly properties during + controlled operations such as cloning and unserialisation. . Added zend_argument_error_ex(), zend_argument_type_error_ex(), zend_argument_value_error_ex(). . Added zend_ast_dup(). diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 474157e73d39..03ac5de67c78 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -193,6 +193,24 @@ ZEND_API zend_object* ZEND_FASTCALL zend_objects_new(zend_class_entry *ce) return object; } +ZEND_API void ZEND_FASTCALL zend_object_set_properties_reinitable(zend_object *object, bool reinitable) +{ + if (!ZEND_CLASS_HAS_READONLY_PROPS(object->ce)) { + return; + } + + for (uint32_t i = 0; i < object->ce->default_properties_count; i++) { + zval *prop = OBJ_PROP_NUM(object, i); + if (reinitable) { + if (!Z_ISUNDEF_P(prop)) { + Z_PROP_FLAG_P(prop) |= IS_PROP_REINITABLE; + } + } else { + Z_PROP_FLAG_P(prop) &= ~IS_PROP_REINITABLE; + } + } +} + ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, const zend_object *old_object) { bool has_clone_method = old_object->ce->clone != NULL; @@ -206,10 +224,6 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, i_zval_ptr_dtor(dst); ZVAL_COPY_VALUE_PROP(dst, src); zval_add_ref(dst); - if (has_clone_method) { - /* Unconditionally add the IS_PROP_REINITABLE flag to avoid a potential cache miss of property_info */ - Z_PROP_FLAG_P(dst) |= IS_PROP_REINITABLE; - } if (UNEXPECTED(Z_ISREF_P(dst)) && (ZEND_DEBUG || ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(dst)))) { @@ -255,10 +269,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, ZVAL_COPY_VALUE(&new_prop, prop); zval_add_ref(&new_prop); } - if (has_clone_method) { - /* Unconditionally add the IS_PROP_REINITABLE flag to avoid a potential cache miss of property_info */ - Z_PROP_FLAG_P(&new_prop) |= IS_PROP_REINITABLE; - } + if (EXPECTED(key)) { _zend_hash_append(new_object->properties, key, &new_prop); } else { @@ -268,15 +279,9 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, } if (has_clone_method) { + zend_object_set_properties_reinitable(new_object, /* reinitable */ true); zend_call_known_instance_method_with_0_params(new_object->ce->clone, new_object, NULL); - - if (ZEND_CLASS_HAS_READONLY_PROPS(new_object->ce)) { - for (uint32_t i = 0; i < new_object->ce->default_properties_count; i++) { - zval* prop = OBJ_PROP_NUM(new_object, i); - /* Unconditionally remove the IS_PROP_REINITABLE flag to avoid a potential cache miss of property_info */ - Z_PROP_FLAG_P(prop) &= ~IS_PROP_REINITABLE; - } - } + zend_object_set_properties_reinitable(new_object, /* reinitable */ false); } } @@ -285,13 +290,8 @@ ZEND_API zend_object *zend_objects_clone_obj_with(zend_object *old_object, const zend_object *new_object = old_object->handlers->clone_obj(old_object); if (EXPECTED(!EG(exception))) { - /* Unlock readonly properties once more. */ - if (ZEND_CLASS_HAS_READONLY_PROPS(new_object->ce)) { - for (uint32_t i = 0; i < new_object->ce->default_properties_count; i++) { - zval* prop = OBJ_PROP_NUM(new_object, i); - Z_PROP_FLAG_P(prop) |= IS_PROP_REINITABLE; - } - } + + zend_object_set_properties_reinitable(new_object, /* reinitable */ true); const zend_class_entry *old_scope = EG(fake_scope); @@ -322,13 +322,7 @@ ZEND_API zend_object *zend_objects_clone_obj_with(zend_object *old_object, const EG(fake_scope) = old_scope; - /* Lock readonly properties once more. */ - if (ZEND_CLASS_HAS_READONLY_PROPS(new_object->ce)) { - for (uint32_t i = 0; i < new_object->ce->default_properties_count; i++) { - zval* prop = OBJ_PROP_NUM(new_object, i); - Z_PROP_FLAG_P(prop) &= ~IS_PROP_REINITABLE; - } - } + zend_object_set_properties_reinitable(new_object, /* reinitable */ false); } return new_object; diff --git a/Zend/zend_objects.h b/Zend/zend_objects.h index 0930fa043101..8bb6c053b0c7 100644 --- a/Zend/zend_objects.h +++ b/Zend/zend_objects.h @@ -25,6 +25,7 @@ BEGIN_EXTERN_C() ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce); ZEND_API zend_object* ZEND_FASTCALL zend_objects_new(zend_class_entry *ce); ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, const zend_object *old_object); +ZEND_API void ZEND_FASTCALL zend_object_set_properties_reinitable(zend_object *object, bool reinitable); ZEND_API void zend_object_std_dtor(zend_object *object); ZEND_API void zend_objects_destroy_object(zend_object *object); diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 8c6d6a0c1f20..e198b0bb7d77 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -583,6 +583,8 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx) _php_curl_verify_handlers(ch, /* reporterror */ true); /* TODO Check callback returns an int or something castable to int */ length = php_curl_get_long(&retval); + } else { + length = -1; } zval_ptr_dtor(&argv[0]); @@ -632,14 +634,14 @@ static int curl_fnmatch(void *ctx, const char *pattern, const char *string) static int curl_progress(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { php_curl *ch = (php_curl *)clientp; - int rval = 0; + int rval = 1; // error #if PHP_CURL_DEBUG fprintf(stderr, "curl_progress() called\n"); fprintf(stderr, "clientp = %p, dltotal = %f, dlnow = %f, ultotal = %f, ulnow = %f\n", clientp, dltotal, dlnow, ultotal, ulnow); #endif if (!ZEND_FCC_INITIALIZED(ch->handlers.progress)) { - return rval; + return 0; // ok } zval args[5]; @@ -659,8 +661,8 @@ static int curl_progress(void *clientp, double dltotal, double dlnow, double ult if (!Z_ISUNDEF(retval)) { _php_curl_verify_handlers(ch, /* reporterror */ true); /* TODO Check callback returns an int or something castable to int */ - if (0 != php_curl_get_long(&retval)) { - rval = 1; + if (0 == php_curl_get_long(&retval)) { + rval = 0; // ok } } @@ -673,14 +675,14 @@ static int curl_progress(void *clientp, double dltotal, double dlnow, double ult static int curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) { php_curl *ch = (php_curl *)clientp; - int rval = 0; + int rval = 1; // error #if PHP_CURL_DEBUG fprintf(stderr, "curl_xferinfo() called\n"); fprintf(stderr, "clientp = %p, dltotal = %ld, dlnow = %ld, ultotal = %ld, ulnow = %ld\n", clientp, dltotal, dlnow, ultotal, ulnow); #endif - if (!ZEND_FCC_INITIALIZED(ch->handlers.xferinfo)) { - return rval; + if (UNEXPECTED(!ZEND_FCC_INITIALIZED(ch->handlers.xferinfo))) { + return 0; // ok } zval argv[5]; @@ -700,8 +702,8 @@ static int curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow, cu if (!Z_ISUNDEF(retval)) { _php_curl_verify_handlers(ch, /* reporterror */ true); /* TODO Check callback returns an int or something castable to int */ - if (0 != php_curl_get_long(&retval)) { - rval = 1; + if (0 == php_curl_get_long(&retval)) { + rval = 0; // ok } } @@ -714,13 +716,13 @@ static int curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow, cu static int curl_prereqfunction(void *clientp, char *conn_primary_ip, char *conn_local_ip, int conn_primary_port, int conn_local_port) { php_curl *ch = (php_curl *)clientp; - int rval = CURL_PREREQFUNC_OK; + int rval = CURL_PREREQFUNC_ABORT; // when CURLOPT_PREREQFUNCTION is set to null, curl_prereqfunction still // gets called. Return CURL_PREREQFUNC_OK immediately in this case to avoid // zend_call_known_fcc() with an uninitialized FCC. - if (!ZEND_FCC_INITIALIZED(ch->handlers.prereq)) { - return rval; + if (UNEXPECTED(!ZEND_FCC_INITIALIZED(ch->handlers.prereq))) { + return CURL_PREREQFUNC_OK; } #if PHP_CURL_DEBUG @@ -858,6 +860,8 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) } // TODO Do type error if invalid type? zval_ptr_dtor(&retval); + } else { + length = CURL_READFUNC_ABORT; } zval_ptr_dtor(&argv[0]); @@ -952,6 +956,8 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx // TODO: Check for valid int type for return value _php_curl_verify_handlers(ch, /* reporterror */ true); length = php_curl_get_long(&retval); + } else { + length = -1; } zval_ptr_dtor(&argv[0]); zval_ptr_dtor(&argv[1]); diff --git a/ext/curl/tests/curl_headerfunction_throws_abort.phpt b/ext/curl/tests/curl_headerfunction_throws_abort.phpt new file mode 100644 index 000000000000..9a69c966f144 --- /dev/null +++ b/ext/curl/tests/curl_headerfunction_throws_abort.phpt @@ -0,0 +1,45 @@ +--TEST-- +CURLOPT_HEADERFUNCTION aborts transfer when callback throws +--EXTENSIONS-- +curl +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +var_dump(curl_errno($ch) === CURLE_WRITE_ERROR); + +echo "Test: header function is null\n"; +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_HEADERFUNCTION, null); +curl_exec($ch); +var_dump(curl_errno($ch) === CURLE_OK); + +?> +--EXPECTF-- +Test: header function throws exception +header exception +bool(true) +Test: header function is null +bool(true) diff --git a/ext/curl/tests/curl_prereqfunction_throws_abort.phpt b/ext/curl/tests/curl_prereqfunction_throws_abort.phpt new file mode 100644 index 000000000000..7e8ccbf94f53 --- /dev/null +++ b/ext/curl/tests/curl_prereqfunction_throws_abort.phpt @@ -0,0 +1,35 @@ +--TEST-- +CURLOPT_PREREQFUNCTION aborts transfer when callback throws +--EXTENSIONS-- +curl +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +var_dump(curl_errno($ch) === CURLE_ABORTED_BY_CALLBACK); + +?> +--EXPECTF-- +prereq exception +bool(true) diff --git a/ext/curl/tests/curl_progressfunction_throws_abort.phpt b/ext/curl/tests/curl_progressfunction_throws_abort.phpt new file mode 100644 index 000000000000..55e0f76cb61f --- /dev/null +++ b/ext/curl/tests/curl_progressfunction_throws_abort.phpt @@ -0,0 +1,46 @@ +--TEST-- +CURLOPT_PROGRESSFUNCTION aborts transfer when callback throws +--EXTENSIONS-- +curl +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +var_dump(curl_errno($ch) === CURLE_ABORTED_BY_CALLBACK); + +echo "Test: progress function is null\n"; +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, null); +curl_exec($ch); +var_dump(curl_errno($ch) === CURLE_OK); + +?> +--EXPECTF-- +Test: progress function throws exception +info exception +bool(true) +Test: progress function is null +bool(true) diff --git a/ext/curl/tests/curl_readfunction_throws_abort.phpt b/ext/curl/tests/curl_readfunction_throws_abort.phpt new file mode 100644 index 000000000000..a030f8c4f41e --- /dev/null +++ b/ext/curl/tests/curl_readfunction_throws_abort.phpt @@ -0,0 +1,48 @@ +--TEST-- +CURLOPT_READFUNCTION aborts transfer when callback throws +--EXTENSIONS-- +curl +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +var_dump(curl_errno($ch) === CURLE_ABORTED_BY_CALLBACK); + +echo "Test: read function is null\n"; +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_READFUNCTION, null); +curl_exec($ch); +var_dump(curl_errno($ch) === CURLE_OK); + +?> +--EXPECTF-- +Test: read function throws exception +read exception +bool(true) +Test: read function is null +bool(true) diff --git a/ext/curl/tests/curl_writefunction_throws_abort.phpt b/ext/curl/tests/curl_writefunction_throws_abort.phpt new file mode 100644 index 000000000000..3da2fe8107b4 --- /dev/null +++ b/ext/curl/tests/curl_writefunction_throws_abort.phpt @@ -0,0 +1,45 @@ +--TEST-- +CURLOPT_WRITEFUNCTION aborts transfer when callback throws +--EXTENSIONS-- +curl +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +var_dump(curl_errno($ch) === CURLE_WRITE_ERROR); + +echo "Test: write function is null\n"; +curl_setopt($ch, CURLOPT_WRITEFUNCTION, null); +curl_exec($ch); +var_dump(curl_errno($ch) === CURLE_OK); + +?> +--EXPECTF-- +Test: write function throws exception +write exception +bool(true) +Test: write function is null +Hello World! +Hello World!bool(true) diff --git a/ext/curl/tests/curl_xferinfofunction_throws_abort.phpt b/ext/curl/tests/curl_xferinfofunction_throws_abort.phpt new file mode 100644 index 000000000000..fbc28f07ee96 --- /dev/null +++ b/ext/curl/tests/curl_xferinfofunction_throws_abort.phpt @@ -0,0 +1,46 @@ +--TEST-- +CURLOPT_XFERINFOFUNCTION aborts transfer when callback throws +--EXTENSIONS-- +curl +--SKIPIF-- + +--FILE-- +getMessage(), "\n"; +} + +var_dump(curl_errno($ch) === CURLE_ABORTED_BY_CALLBACK); + +echo "Test: xfer info function is null\n"; +curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); +curl_setopt($ch, CURLOPT_XFERINFOFUNCTION, null); +curl_exec($ch); +var_dump(curl_errno($ch) === CURLE_OK); + +?> +--EXPECTF-- +Test: xfer info function throws exception +info exception +bool(true) +Test: xfer info function is null +bool(true) diff --git a/ext/pdo_sqlite/tests/bug66033.phpt b/ext/pdo_sqlite/tests/bug66033.phpt index a45d34a580e6..611cc59c982d 100644 --- a/ext/pdo_sqlite/tests/bug66033.phpt +++ b/ext/pdo_sqlite/tests/bug66033.phpt @@ -24,8 +24,8 @@ $pdo->exec("CREATE TABLE IF NOT EXISTS messages ( try { $pdoStatement = $pdo->query("select * from messages"); } catch (Exception $e) { - var_dump($e->getMessage()); + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -string(4) "Blah" +Exception: Blah diff --git a/ext/pdo_sqlite/tests/bug81227.phpt b/ext/pdo_sqlite/tests/bug81227.phpt index b15818e8a137..8fc469ed36f9 100644 --- a/ext/pdo_sqlite/tests/bug81227.phpt +++ b/ext/pdo_sqlite/tests/bug81227.phpt @@ -13,7 +13,7 @@ var_dump($db->inTransaction()); try { $db->beginTransaction(); } catch (PDOException $e) { - echo $e->getMessage(), "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } $db->commit(); @@ -25,6 +25,6 @@ var_dump($db->inTransaction()); --EXPECT-- bool(false) bool(true) -There is already an active transaction +PDOException: There is already an active transaction bool(false) bool(true) diff --git a/ext/pdo_sqlite/tests/bug_44159_sqlite_version.phpt b/ext/pdo_sqlite/tests/bug_44159_sqlite_version.phpt index 69cd0897e388..d22f7c7a85bc 100644 --- a/ext/pdo_sqlite/tests/bug_44159_sqlite_version.phpt +++ b/ext/pdo_sqlite/tests/bug_44159_sqlite_version.phpt @@ -10,19 +10,19 @@ $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING); try { var_dump($pdo->setAttribute(PDO::NULL_TO_STRING, NULL)); } catch (\TypeError $e) { - echo $e->getMessage(), \PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump($pdo->setAttribute(PDO::NULL_TO_STRING, 1)); try { var_dump($pdo->setAttribute(PDO::NULL_TO_STRING, 'nonsense')); } catch (\TypeError $e) { - echo $e->getMessage(), \PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } @unlink(__DIR__."/foo.db"); ?> --EXPECT-- -Attribute value must be of type int for selected attribute, null given +TypeError: Attribute value must be of type int for selected attribute, null given bool(true) -Attribute value must be of type int for selected attribute, string given +TypeError: Attribute value must be of type int for selected attribute, string given diff --git a/ext/pdo_sqlite/tests/gh14712.phpt b/ext/pdo_sqlite/tests/gh14712.phpt index d565abacdcd1..c0f0d003cbfb 100644 --- a/ext/pdo_sqlite/tests/gh14712.phpt +++ b/ext/pdo_sqlite/tests/gh14712.phpt @@ -11,8 +11,8 @@ $db = new PDO('sqlite::memory:'); try { $db->query("select 1 as queryStringxx")->fetch(PDO::FETCH_LAZY)->documentElement->firstChild->nextElementSibling->textContent = "é"; } catch (Error $e) { - echo $e->getMessage(); + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -Attempt to modify property "firstChild" on null +Error: Attempt to modify property "firstChild" on null diff --git a/ext/pdo_sqlite/tests/gh9032.phpt b/ext/pdo_sqlite/tests/gh9032.phpt index 332190484cfb..a793a71cee5b 100644 --- a/ext/pdo_sqlite/tests/gh9032.phpt +++ b/ext/pdo_sqlite/tests/gh9032.phpt @@ -16,9 +16,9 @@ $st = $db->prepare('attach database :a AS "db2"'); $st->execute([':a' => ':memory:']); var_dump($db->exec('create table db2.r (id int)')); } catch (PDOException $ex) { - echo $ex->getMessage(), PHP_EOL; + echo $ex::class, ': ', $ex->getMessage(), "\n"; } ?> --EXPECT-- int(0) -SQLSTATE[HY000]: General error: 23 not authorized +PDOException: SQLSTATE[HY000]: General error: 23 not authorized diff --git a/ext/pdo_sqlite/tests/open_basedir.phpt b/ext/pdo_sqlite/tests/open_basedir.phpt index a82c3027aed0..59e5fe273c2c 100644 --- a/ext/pdo_sqlite/tests/open_basedir.phpt +++ b/ext/pdo_sqlite/tests/open_basedir.phpt @@ -11,21 +11,21 @@ chdir(__DIR__); try { $db = new PDO('sqlite:../not_in_open_basedir.sqlite'); } catch (Exception $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db = new PDO('sqlite:file:../not_in_open_basedir.sqlite'); } catch (Exception $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db = new PDO('sqlite:file:../not_in_open_basedir.sqlite?mode=ro'); } catch (Exception $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -open_basedir prohibits opening ../not_in_open_basedir.sqlite -open_basedir prohibits opening file:../not_in_open_basedir.sqlite -open_basedir prohibits opening file:../not_in_open_basedir.sqlite?mode=ro +PDOException: open_basedir prohibits opening ../not_in_open_basedir.sqlite +PDOException: open_basedir prohibits opening file:../not_in_open_basedir.sqlite +PDOException: open_basedir prohibits opening file:../not_in_open_basedir.sqlite?mode=ro diff --git a/ext/pdo_sqlite/tests/pdo_sqlite___construct_uri.phpt b/ext/pdo_sqlite/tests/pdo_sqlite___construct_uri.phpt index 7fc686b21472..2f88ed8ea6d1 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite___construct_uri.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite___construct_uri.phpt @@ -26,7 +26,7 @@ var_dump(file_exists($dbFile)); try { new PDO("uri:{$dsnFile}"); } catch (Throwable $e) { - echo $e::class, ": ", $e->getMessage(), PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } clearstatcache(); diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt index 192eabbf74fd..7ca31ee9c50d 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createaggregate_002.phpt @@ -10,18 +10,18 @@ $pdo = new PDO('sqlite::memory:'); try { $pdo->sqliteCreateAggregate('foo', 'a', ''); } catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $pdo->sqliteCreateAggregate('foo', 'strlen', ''); } catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECTF-- Deprecated: Method PDO::sqliteCreateAggregate() is deprecated since 8.5, use Pdo\Sqlite::createAggregate() instead in %s on line %d -PDO::sqliteCreateAggregate(): Argument #2 ($step) must be a valid callback, function "a" not found or invalid function name +TypeError: PDO::sqliteCreateAggregate(): Argument #2 ($step) must be a valid callback, function "a" not found or invalid function name Deprecated: Method PDO::sqliteCreateAggregate() is deprecated since 8.5, use Pdo\Sqlite::createAggregate() instead in %s on line %d -PDO::sqliteCreateAggregate(): Argument #3 ($finalize) must be a valid callback, function "" not found or invalid function name +TypeError: PDO::sqliteCreateAggregate(): Argument #3 ($finalize) must be a valid callback, function "" not found or invalid function name diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt index eb5ea6c97b7d..b8308e7d7ef3 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createcollation.phpt @@ -29,7 +29,7 @@ $db->sqliteCreateCollation('MYCOLLATEBAD', function($a, $b) { return $a; }); try { $db->query('SELECT name FROM test_pdo_sqlite_createcollation ORDER BY name COLLATE MYCOLLATEBAD'); } catch (\TypeError $e) { - echo $e->getMessage(), PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECTF-- @@ -42,4 +42,4 @@ Deprecated: Method PDO::sqliteCreateCollation() is deprecated since 8.5, use Pdo 2 Deprecated: Method PDO::sqliteCreateCollation() is deprecated since 8.5, use Pdo\Sqlite::createCollation() instead in %s on line %d -PDO::query(): Return value of the collation callback must be of type int, string returned +TypeError: PDO::query(): Return value of the collation callback must be of type int, string returned diff --git a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt index ead2f7b6a830..b6249a8b4165 100644 --- a/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt +++ b/ext/pdo_sqlite/tests/pdo_sqlite_createfunction_002.phpt @@ -13,10 +13,10 @@ $db = new PDO( 'sqlite::memory:'); try { $db->sqliteCreateFunction('bar-alias', 'bar'); } catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECTF-- Deprecated: Method PDO::sqliteCreateFunction() is deprecated since 8.5, use Pdo\Sqlite::createFunction() instead in %s on line %d -PDO::sqliteCreateFunction(): Argument #2 ($callback) must be a valid callback, function "bar" not found or invalid function name +TypeError: PDO::sqliteCreateFunction(): Argument #2 ($callback) must be a valid callback, function "bar" not found or invalid function name diff --git a/ext/pdo_sqlite/tests/subclasses/gh_16131.phpt b/ext/pdo_sqlite/tests/subclasses/gh_16131.phpt index 601ce24f5152..ac0d31bd6122 100644 --- a/ext/pdo_sqlite/tests/subclasses/gh_16131.phpt +++ b/ext/pdo_sqlite/tests/subclasses/gh_16131.phpt @@ -9,7 +9,7 @@ pdo_sqlite try { new Pdo\Pgsql('sqlite::memory:'); } catch (PDOException $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } class MyPgsql extends Pdo\Pgsql @@ -19,10 +19,10 @@ class MyPgsql extends Pdo\Pgsql try { new MyPgsql('sqlite::memory:'); } catch (PDOException $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -Pdo\Pgsql::__construct() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::__construct() or PDO::__construct() instead -MyPgsql::__construct() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::__construct() or PDO::__construct() instead +PDOException: Pdo\Pgsql::__construct() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::__construct() or PDO::__construct() instead +PDOException: MyPgsql::__construct() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::__construct() or PDO::__construct() instead diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createafunction_arg_error.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createafunction_arg_error.phpt index dce8ecf28785..7afa43ac9d3c 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createafunction_arg_error.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createafunction_arg_error.phpt @@ -18,32 +18,32 @@ class TrampolineTest { try { $db->createFunction(null, [new TrampolineTest(), 'strtoupper']); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db->createFunction('strtoupper', null); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db->createFunction('strtoupper', [new TrampolineTest(), 'strtoupper'], null); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db->createFunction('strtoupper', [new TrampolineTest(), 'strtoupper'], 1, null); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } echo 'done!'; ?> --EXPECT-- -Pdo\Sqlite::createFunction(): Argument #1 ($function_name) must be of type string, null given -Pdo\Sqlite::createFunction(): Argument #2 ($callback) must be a valid callback, no array or string given -Pdo\Sqlite::createFunction(): Argument #3 ($num_args) must be of type int, null given -Pdo\Sqlite::createFunction(): Argument #4 ($flags) must be of type int, null given +TypeError: Pdo\Sqlite::createFunction(): Argument #1 ($function_name) must be of type string, null given +TypeError: Pdo\Sqlite::createFunction(): Argument #2 ($callback) must be a valid callback, no array or string given +TypeError: Pdo\Sqlite::createFunction(): Argument #3 ($num_args) must be of type int, null given +TypeError: Pdo\Sqlite::createFunction(): Argument #4 ($flags) must be of type int, null given done! diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate_002.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate_002.phpt index 3419f5548057..161a2d820446 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate_002.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate_002.phpt @@ -11,15 +11,15 @@ $pdo = new Pdo\Sqlite('sqlite::memory:'); try { $pdo->createAggregate('foo', 'a', ''); } catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $pdo->createAggregate('foo', 'strlen', ''); } catch (\TypeError $e) { - echo $e->getMessage() . \PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -Pdo\Sqlite::createAggregate(): Argument #2 ($step) must be a valid callback, function "a" not found or invalid function name -Pdo\Sqlite::createAggregate(): Argument #3 ($finalize) must be a valid callback, function "" not found or invalid function name +TypeError: Pdo\Sqlite::createAggregate(): Argument #2 ($step) must be a valid callback, function "a" not found or invalid function name +TypeError: Pdo\Sqlite::createAggregate(): Argument #3 ($finalize) must be a valid callback, function "" not found or invalid function name diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate_arg_error.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate_arg_error.phpt index 7707f8cae978..896aac27a558 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate_arg_error.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createaggregate_arg_error.phpt @@ -18,46 +18,46 @@ class TrampolineTest { try { $db->createAggregate(null, [new TrampolineTest(), 'step'], null, 1); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db->createAggregate(null, null, [new TrampolineTest(), 'step'], 1); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db->createAggregate(null, [new TrampolineTest(), 'step'], [new TrampolineTest(), 'step'], 1); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db->createAggregate('S', null, [new TrampolineTest(), 'finalize'], 1); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db->createAggregate('S', [new TrampolineTest(), 'step'], null, 1); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db->createAggregate('S', [new TrampolineTest(), 'step'], [new TrampolineTest(), 'finalize'], null); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } echo 'done!'; ?> --EXPECT-- -Pdo\Sqlite::createAggregate(): Argument #1 ($name) must be of type string, null given -Pdo\Sqlite::createAggregate(): Argument #1 ($name) must be of type string, null given -Pdo\Sqlite::createAggregate(): Argument #1 ($name) must be of type string, null given -Pdo\Sqlite::createAggregate(): Argument #2 ($step) must be a valid callback, no array or string given -Pdo\Sqlite::createAggregate(): Argument #3 ($finalize) must be a valid callback, no array or string given -Pdo\Sqlite::createAggregate(): Argument #4 ($numArgs) must be of type int, null given +TypeError: Pdo\Sqlite::createAggregate(): Argument #1 ($name) must be of type string, null given +TypeError: Pdo\Sqlite::createAggregate(): Argument #1 ($name) must be of type string, null given +TypeError: Pdo\Sqlite::createAggregate(): Argument #1 ($name) must be of type string, null given +TypeError: Pdo\Sqlite::createAggregate(): Argument #2 ($step) must be a valid callback, no array or string given +TypeError: Pdo\Sqlite::createAggregate(): Argument #3 ($finalize) must be a valid callback, no array or string given +TypeError: Pdo\Sqlite::createAggregate(): Argument #4 ($numArgs) must be of type int, null given done! diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_arg_error.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_arg_error.phpt index 16bb8b9333e4..95b591b105c2 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_arg_error.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_arg_error.phpt @@ -18,18 +18,18 @@ class TrampolineTest { try { $db->createCollation(null, [new TrampolineTest(), 'NAT']); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $db->createCollation('NAT', null); } catch (Throwable $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } echo 'done!'; ?> --EXPECT-- -Pdo\Sqlite::createCollation(): Argument #1 ($name) must be of type string, null given -Pdo\Sqlite::createCollation(): Argument #2 ($callback) must be a valid callback, no array or string given +TypeError: Pdo\Sqlite::createCollation(): Argument #1 ($name) must be of type string, null given +TypeError: Pdo\Sqlite::createCollation(): Argument #2 ($callback) must be a valid callback, no array or string given done! diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_wrong_callback.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_wrong_callback.phpt index 2a493c211797..6c97860a6617 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_wrong_callback.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_createcollation_wrong_callback.phpt @@ -17,8 +17,8 @@ $db->createCollation('NAT', function($a, $b): string { return $a . $b; }); try { $db->query("SELECT c FROM test ORDER BY c COLLATE NAT"); } catch (\TypeError $e) { - echo $e->getMessage(), PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -PDO::query(): Return value of the collation callback must be of type int, string returned +TypeError: PDO::query(): Return value of the collation callback must be of type int, string returned diff --git a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt index d2a6c2a5f52b..9604d4e10212 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdo_sqlite_getsetattr_explain.phpt @@ -36,25 +36,25 @@ class Duh {} try { $stmts->setAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT, "EXPLAIN"); } catch (\TypeError $e) { - echo $e->getMessage(), PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $stmts->setAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT, new Duh()); } catch (\TypeError $e) { - echo $e->getMessage(), PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $stmts->setAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT, -1); } catch (\ValueError $e) { - echo $e->getMessage(), PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } try { $stmts->setAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT, 256); } catch (\ValueError $e) { - echo $e->getMessage(), PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } var_dump($stmts->getAttribute(Pdo\Sqlite::ATTR_EXPLAIN_STATEMENT) == Pdo\Sqlite::EXPLAIN_MODE_PREPARED); @@ -393,8 +393,8 @@ array(2) { string(13) "second_insert" } } -explain mode must be of type int, string given -explain mode must be of type int, Duh given -explain mode must be one of the Pdo\Sqlite::EXPLAIN_MODE_* constants -explain mode must be one of the Pdo\Sqlite::EXPLAIN_MODE_* constants +TypeError: explain mode must be of type int, string given +TypeError: explain mode must be of type int, Duh given +ValueError: explain mode must be one of the Pdo\Sqlite::EXPLAIN_MODE_* constants +ValueError: explain mode must be one of the Pdo\Sqlite::EXPLAIN_MODE_* constants bool(true) diff --git a/ext/pdo_sqlite/tests/subclasses/pdosqlite_005.phpt b/ext/pdo_sqlite/tests/subclasses/pdosqlite_005.phpt index 24120f1d8205..19da0daaebab 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdosqlite_005.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdosqlite_005.phpt @@ -9,9 +9,9 @@ pdo_sqlite try { Pdo\Pgsql::connect('sqlite::memory:'); } catch (PDOException $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -Pdo\Pgsql::connect() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::connect() or PDO::connect() instead +PDOException: Pdo\Pgsql::connect() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::connect() or PDO::connect() instead diff --git a/ext/pdo_sqlite/tests/subclasses/pdosqlite_007.phpt b/ext/pdo_sqlite/tests/subclasses/pdosqlite_007.phpt index 58568abe7363..cc8cdec78967 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdosqlite_007.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdosqlite_007.phpt @@ -10,9 +10,9 @@ class MyPDO extends PDO {} try { MyPDO::connect('sqlite::memory:'); } catch (PDOException $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> --EXPECT-- -MyPDO::connect() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::connect() or PDO::connect() instead +PDOException: MyPDO::connect() cannot be used for connecting to the "sqlite" driver, either call Pdo\Sqlite::connect() or PDO::connect() instead diff --git a/ext/pdo_sqlite/tests/subclasses/pdosqlite_load_extension_failure.phpt b/ext/pdo_sqlite/tests/subclasses/pdosqlite_load_extension_failure.phpt index 75f3de6b581a..829f515ece64 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdosqlite_load_extension_failure.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdosqlite_load_extension_failure.phpt @@ -22,7 +22,7 @@ try { echo "Failed to throw exception"; } catch (PDOException $pdoException) { - echo $pdoException->getMessage() . "\n"; + echo $pdoException::class, ': ', $pdoException->getMessage(), "\n"; } try { @@ -31,14 +31,14 @@ try { echo "Failed to throw exception"; } catch (PDOException $pdoException) { - echo $pdoException->getMessage() . "\n"; + echo $pdoException::class, ': ', $pdoException->getMessage(), "\n"; } echo "Fin."; ?> --EXPECTF-- Loading non-existent file. -Unable to load extension "/this/does/not_exist" +PDOException: Unable to load extension "/this/does/not_exist" Loading invalid file. -Unable to load extension "%a" +PDOException: Unable to load extension "%a" Fin. diff --git a/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer.phpt b/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer.phpt index d1e9039ea1c4..92a9b28a3cfb 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer.phpt @@ -22,7 +22,7 @@ try { // This one should fail var_dump($db->exec('CREATE TABLE test (a, b);')); } catch (\Exception $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } // Test disabling the authorizer @@ -51,7 +51,7 @@ $db->setAuthorizer(function () { try { var_dump($db->query('SELECT 1;')); } catch (\Error $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } $db->setAuthorizer(function () { @@ -61,7 +61,7 @@ $db->setAuthorizer(function () { try { var_dump($db->query('SELECT 1;')); } catch (\Error $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> @@ -70,7 +70,7 @@ object(PDOStatement)#%d (1) { ["queryString"]=> string(9) "SELECT 1;" } -SQLSTATE[HY000]: General error: 23 not authorized +PDOException: SQLSTATE[HY000]: General error: 23 not authorized int(1) int(1) string(6) "SELECT" @@ -97,5 +97,5 @@ string(28) "sqlite_master,rootpage,main," string(4) "READ" string(28) "sqlite_master,rootpage,main," int(1) -PDO::query(): Return value of the authorizer callback must be of type int, string returned -PDO::query(): Return value of the authorizer callback must be one of Pdo\Sqlite::OK, Pdo\Sqlite::DENY, or Pdo\Sqlite::IGNORE +TypeError: PDO::query(): Return value of the authorizer callback must be of type int, string returned +ValueError: PDO::query(): Return value of the authorizer callback must be one of Pdo\Sqlite::OK, Pdo\Sqlite::DENY, or Pdo\Sqlite::IGNORE diff --git a/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer_trampoline.phpt b/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer_trampoline.phpt index c93a1f2e34a5..1bceccb48570 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer_trampoline.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer_trampoline.phpt @@ -29,7 +29,7 @@ try { // This one should fail var_dump($db->query('CREATE TABLE test (a, b);')); } catch (\Exception $e) { - echo $e->getMessage() . "\n"; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> @@ -40,4 +40,4 @@ object(PDOStatement)#%d (1) { string(9) "SELECT 1;" } Trampoline for authorizer -SQLSTATE[HY000]: General error: 23 not authorized +PDOException: SQLSTATE[HY000]: General error: 23 not authorized diff --git a/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer_trampoline_no_leak.phpt b/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer_trampoline_no_leak.phpt index 84b83877b94a..c6f240120c92 100644 --- a/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer_trampoline_no_leak.phpt +++ b/ext/pdo_sqlite/tests/subclasses/pdosqlite_setauthorizer_trampoline_no_leak.phpt @@ -25,7 +25,7 @@ $obj = $rc->newInstanceWithoutConstructor(); try { var_dump($obj->setAuthorizer($callback)); } catch (\Throwable $e) { - echo $e::class, ': ', $e->getMessage(), PHP_EOL; + echo $e::class, ': ', $e->getMessage(), "\n"; } ?> diff --git a/sapi/apache2handler/php_functions.c b/sapi/apache2handler/php_functions.c index 1baa1f5225e0..db2dcca72bda 100644 --- a/sapi/apache2handler/php_functions.c +++ b/sapi/apache2handler/php_functions.c @@ -308,6 +308,8 @@ static const char *php_apache_get_version(void) /* {{{ Fetch Apache version */ PHP_FUNCTION(apache_get_version) { + ZEND_PARSE_PARAMETERS_NONE(); + const char *apv = php_apache_get_version(); if (apv && *apv) { @@ -324,6 +326,8 @@ PHP_FUNCTION(apache_get_modules) int n; char *p; + ZEND_PARSE_PARAMETERS_NONE(); + array_init(return_value); for (n = 0; ap_loaded_modules[n]; ++n) {