When a class (or enum) has no methods, rather than using an array that only
contains `ZEND_FE_END`, use `NULL` for the functions. The implementation of
class registration for internal classes, `do_register_internal_class()` in
zend_API.c, already skips classes where the functions are `NULL`. By removing
these unneeded arrays, we can reduce the size of the header files, while also
removing an unneeded call to zend_register_functions() for each internal class
with no extra methods.
Currently, internal classes are registered with the following code:
INIT_CLASS_ENTRY(ce, "InternalClass", class_InternalClass_methods);
class_entry = zend_register_internal_class_ex(&ce, NULL);
class_entry->ce_flags |= ...;
This has worked well so far, except if InternalClass is readonly. It is because some inheritance checks are run by zend_register_internal_class_ex before ZEND_ACC_READONLY_CLASS is added to ce_flags.
The issue is fixed by adding a zend_register_internal_class_with_flags() zend API function that stubs can use from now on. This function makes sure to add the flags before running any checks. Since the new API is not available in lower PHP versions, gen_stub.php has to keep support for the existing API for PHP 8.3 and below.
Follow up on 13483
As previously reported in https://github.com/php/php-src/pull/13483#discussion_r1718546927:
> The parameter names seem to be incorrect.
>
> It should be `$status`, not `$code`.
>
> The RFC explicitly uses that parameter name in the proposal: https://wiki.php.net/rfc/exit-as-function#proposal
>
> It is also the name already used in the [manual](https://www.php.net/exit).
>
> Lastly, the parameter name `$status` better covers what can be passed: either a status _message_ or a status _code_.
> While `$code` would read pretty weird when passing a message:
> ```php
> exit(code: 'message');
> ```
This commit attempts to fix this.
Includes adding a test for exit/die using a named argument.
Co-authored-by: jrfnl <jrfnl@users.noreply.github.com>
- running: true if garbage collection is currently running
- protected: true if the garbage collector is protected and root
additions are forbidden
- full: true if the garbage collector buffer size exceeds GC_MAX_BUF_SIZE
- buffer_size: current garbage collector buffer size
Documentation for existing fields:
- runs: the number of times the garbage collector has been run
- collected: the number of objects collected
- threshold: the number of roots in the buffer which will trigger
garbage collection
- roots: the current number of roots in the buffer
Updated manual example output:
array(8) {
["running"]=>
bool(false)
["protected"]=>
bool(false)
["full"]=>
bool(false)
["runs"]=>
int(5)
["collected"]=>
int(100002)
["threshold"]=>
int(50001)
["buffer_size"]=>
int(131072)
["roots"]=>
int(0)
}
* Support the `#[\AllowDynamicProperties]` attribute in stubs
* Use `#[\AllowDynamicProperties]` attribute in stubs
* Disallow applying both `@strict-properties` and `#[\AllowDynamicProperties]`
https://wiki.php.net/rfc/strtolower-ascii means that these functions no longer
depend on the current locale in php 8.2. Before that, this was unsafe to
evaluate at compile time.
Followup to GH-7506
Add strcmp/strcasecmp/strtolower/strtoupper functions
Add bin2hex/hex2bin and related functions
Update test of garbage collection using strtolower to use something else to create a refcounted string
The hash is used to check whether the arginfo file needs to be
regenerated. PHP-Parser will only be downloaded if this is actually
necessary.
This ensures that release artifacts will never try to regenerate
stubs and thus fetch PHP-Parser, as long as you do not modify any
files.
Closes GH-5739.
Behavior is same as for (int) $resource, just under a clearer
name. Also type-safe, in that the parameter actually needs to
be a resource.
Closes GH-5427.
Currently, disabling a function only replaces the internal
function handler with one that throws a warning, and a few
places in the engine special-case such functions, such as
function_exists. This leaves us with a Schrödinger's function,
which both does not exist (function_exists returns false) and
does exist (you cannot define a function with the same name).
In particular, this prevents the implementation of robust
polyfills, as reported in https://bugs.php.net/bug.php?id=79382:
if (!function_exists('getallheaders')) {
function getallheaders(...) { ... }
}
If getallheaders() is a disabled function, this code will break.
This patch changes disable_functions to remove the functions from
the function table completely. For all intents and purposes, it
will look like the function does not exist.
This also renders two bits of PHP functionality obsolete and thus
deprecated:
* ReflectionFunction::isDisabled(), as it will no longer be
possible to construct the ReflectionFunction of a disabled
function in the first place.
* get_defined_functions() with $exclude_disabled=false, as
get_defined_functions() now never returns disabled functions.
Fixed bug #79382.
Closes GH-5473.
Closes GH-5353. From now on, PHP will have reflection information
about default values of parameters of internal functions.
Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>