Treatment of locales in PHP is currently inconsistent: The LC_ALL
locale is set to "C", as is standard behavior on program startup.
The LC_CTYPE locale is set to "", which will inherit it from the
environment. However, the inherited LC_CTYPE locale will only be
used in some cases, while in other cases it is necessary to perform
an explicit setlocale() call in PHP first. This is the case for
the locale-sensitive handling in the PCRE extension.
Make things consistent by *never* inheriting any locales from the
environment. LC_ALL, including LC_CTYPE will be "C" on startup.
A locale can be set or inherited through an explicit setlocale()
call, at which point the behavior will be fully consistent and
predictable.
Closes GH-5488.
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.
RFC: https://wiki.php.net/rfc/throw_expression
This has an open issue with temporaries that are live at the time
of the throw being leaked. Landing this now for easier testing and
will revert if we cannot resolve the issue.
Closes GH-5279.
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>
This reverts commit bb43a3822e.
After thinking about this a bit more, this is now going to be
a complete solution for the "readonly properties" case, for example:
unset($foo->readOnly->bar);
should also be legal and
$foo->readOnly['bar'] = 42;
should also be legal if $foo->readOnly is not an array but an
ArrayAccess object.
I think it may be better to distinguish better on the BP_VAR flag
level. Reverting for now.
$a->b->c = 'd';
is now compiled the same way as
$b = $a->b;
$b->c = 'd';
That is, we perform a read fetch on $a->b, rather than a write
fetch.
This is possible, because PHP 8 removed auto-vivification support
for objects, so $a->b->c = 'd' may no longer modify $a->b proper
(i.e. not counting interior mutability of the object).
Closes GH-5250.
It is hard to impossible to work around iconv() implementations which
do not properly set errno according to POSIX. We therefore do no
longer allow to build against such iconv() implementations.
Co-Authored-By: Nikita Popov <nikita.ppv@googlemail.com>
Currently, when writing something like
class X {
use T1, T2 {
func as otherFunc;
}
function func() {}
}
where both T1::func() and T2::func() exist, we will simply assume
that func refers to T1::func(). This is surprising, and it doesn't
really make sense that this particular method gets picked.
This commit validates that non-absolute method references are
unambiguous, i.e. refer to exactly one method. If there is
ambiguity, it is required to write T1::func as otherFunc or
similar.
Closes GH-5232.
Provides the last PCRE error as a human-readable message, similar
to functionality existing in other extensions, such as
json_last_error_msg().
Closes GH-5185.
var_dump() is debugging functionality, so it should print
floating-point numbers accurately. We do this by switching
to serialize_precision, which (by default) will print with
as much precision as necessary to preserve the exact value
of the float.
This also affects debug_zval_dump().
Closes GH-5172.
As an exception, we allow "Type $foo = null" to occur before a
required parameter, because this pattern was used as a replacement
for nullable types in PHP versions older than 7.1.
Closes GH-5067.
While the `$command` passed to `proc_open()` had to be wrapped in
double-quotes manually, that was implicitly done for all other
program execution functions. This could easily introduce bugs and
even security issues when switching from one to another program
execution function.
Furthermore we ensure that the additional quotes are always
unwrapped regardless of what is passed as `$command` by passing
the `/s` flag to cmd.exe. As it was, `shell_exec('path with
spaces/program.exe')` did execute program.exe, but adding an
argument (`shell_exec('path with spaces/program.exe -h)`) failed
to execute program.exe, because cmd.exe stripped the additional
quotes.
While these changes obviously can cause BC breaks, we feel that in
the long run the benefits of having consistent behavior for all
program execution functions outweighs the drawbacks of potentially
breaking some code now.
In order of preference, the generated name will be:
new class extends ParentClass {};
// -> ParentClass@anonymous
new class implements FirstInterface, SecondInterface {};
// -> FirstInterface@anonymous
new class {};
// -> class@anonymous
This is intended to display a more useful class name in error messages
and stack traces, and thus make debugging easier.
Closes GH-5153.
RFC: https://wiki.php.net/rfc/static_return_type
The "static" type is represented as MAY_BE_STATIC, rather than
a class type like "self" and "parent", as it has special
resolution semantics, and cannot be cached in the runtime cache.
Closes GH-5062.
This helps to avoid unnecessary IS_REFERENCE checks.
This changes some notices "Only variables should be passed by reference" to exception "Cannot pass parameter %d by reference".
Also, for consistency, compile-time fatal error "Only variables can be passed by reference" was converted to exception "Cannot pass parameter %d by reference"