It's possible to return a reference from __toString(), but this is not
handled and results in a (confusing) error telling that the return value
must be a string.
Properly handle this by unwrapping the reference.
Closes GH-18810.
Relates to #14461 and https://wiki.php.net/rfc/url_parsing_api
Co-authored-by: Niels Dossche <7771979+nielsdos@users.noreply.github.com>
Co-authored-by: Tim Düsterhus <tim@tideways-gmbh.com>
- Property hooks may now throw exceptions, that seem to be forgotten to be handled by https://github.com/php/php-src/pull/18442
- The $previous and $trace properties are private, and they were not accessible from the constructor of a child class
The class structure is fixed, so it makes no sense to go through all the
logic of looking up property info etc if there are no hooks.
This patch introduces a local function `zend_update_property_num_checked()` to
help with that.
For this benchmark:
```php
for ($i = 0; $i < 1000000; $i++)
new Error;
```
On an i7-4790:
```
Benchmark 1: ./sapi/cli/php x.php
Time (mean ± σ): 141.6 ms ± 9.3 ms [User: 138.7 ms, System: 2.0 ms]
Range (min … max): 135.4 ms … 177.7 ms 20 runs
Benchmark 2: ../RELx64_old/sapi/cli/php x.php
Time (mean ± σ): 214.1 ms ± 7.0 ms [User: 207.6 ms, System: 5.0 ms]
Range (min … max): 206.6 ms … 230.9 ms 13 runs
Summary
./sapi/cli/php x.php ran
1.51 ± 0.11 times faster than ../RELx64_old/sapi/cli/php x.php
```
For this benchmark:
```php
for ($i = 0; $i < 1000000; $i++)
new Exception("message", 0, null);
```
On an i7-4790:
```
Benchmark 1: ./sapi/cli/php x.php
Time (mean ± σ): 184.3 ms ± 9.5 ms [User: 181.2 ms, System: 1.8 ms]
Range (min … max): 173.8 ms … 205.1 ms 15 runs
Benchmark 2: ../RELx64_old/sapi/cli/php x.php
Time (mean ± σ): 253.7 ms ± 7.0 ms [User: 247.6 ms, System: 4.6 ms]
Range (min … max): 245.7 ms … 263.7 ms 11 runs
Summary
./sapi/cli/php x.php ran
1.38 ± 0.08 times faster than ../RELx64_old/sapi/cli/php x.php
```
For this benchmark:
```php
for ($i = 0; $i < 1000000; $i++)
new ErrorException("message", 0, 0, "xyz", 0, null);
```
On an i7-4790:
```
Benchmark 1: ./sapi/cli/php x.php
Time (mean ± σ): 223.6 ms ± 7.7 ms [User: 220.1 ms, System: 2.4 ms]
Range (min … max): 216.9 ms … 242.5 ms 12 runs
Benchmark 2: ../RELx64_old/sapi/cli/php x.php
Time (mean ± σ): 343.5 ms ± 8.1 ms [User: 337.1 ms, System: 4.6 ms]
Range (min … max): 337.3 ms … 362.8 ms 10 runs
Summary
./sapi/cli/php x.php ran
1.54 ± 0.06 times faster than ../RELx64_old/sapi/cli/php x.php
```
`zend_test_create_throwing_resource` sets the exception in the `test`
call frame and unwinds to `main`. It then throws for the `resource`
variable and verifies that the exception opline is set. However, it
wasn't set in `main`, it was set at the `test` call frame and rethrown later.
The assertion is too conservative, but the end result is right, so drop
the assertion.
Closes GH-17533.
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
For the `Exception`, `ReflectionClass`, and `ReflectionAttribute` classes, the
`__clone()` method is declared to be private, and the implementation has a
comment that it should never be executed. However, the implementation can be
executed by using a `ReflectionMethod`. Fix the comments to instead explain why
the implementation is needed.
[skip ci]
RFC: https://wiki.php.net/rfc/rfc1867-non-post
This function allows populating the $_POST and $_FILES globals for non-post
requests. This avoids manual parsing of RFC1867 requests.
Fixes#55815
Closes GH-11472
Object handlers being separate from class entries is a legacy inherited from PHP 5. Today it has little benefit to keep them separate: in fact, accessing object handlers usually requires not-so-safe hacks.
While it is possible to swap handlers in a custom installed create_object handler, this mostly is tedious, as well as it requires allocating the object handlers struct at runtime, possibly caching it etc..
This allows extensions, which intend to observe other classes to install their own class handlers.
The life cycle of internal classes may now be simply observed by swapping the class handlers in post_startup stage.
The life cycle of userland classes may be observed by iterating over the new classes in zend_compile_file and zend_compile_string and then swapping their handlers.
In general, this would also be a first step in directly tying the object handlers to classes. Especially given that I am not aware of any case where the object handlers would be different between various instances of a given class.
Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
When killing a coroutine by throwing an unwind exit into it during
an I/O operation, the I/O failure may result in an exception being
thrown, which will replace the unwind exit exception and the
coroutine will ultimately not exit. This patch avoids this by
ignoring the newly thrown exception and keeping the unwind exit
exception.
Closes GH-7459.
This code is used by generic EH_THROW with arbitrary Exception
types, while only ErrorException has a $severity property. We
don't want this code to add $severity properties to random
exception types like PDOException.
zend_double_to_str() converts a double to string in the way that
(string) would (using %.*H using precision).
smart_str_append_double() provides some more fine control over
the precision, and whether a zero fraction should be appeneded
for whole numbers.
A caveat here is that raw calls to zend_gcvt and going through
s*printf has slightly different behavior for the degenarate
precision=0 case. zend_gcvt will add a dummy E+0 in that case,
while s*printf convert this to precision=1 and will not. I'm
going with the s*printf behavior here, which is more common,
but does result in a minor change to the precision.phpt test.
Convert zend_hash_find_ex(..., 1) to zend_hash_find_known_hash(...)
Convert zend_hash_find_ex(..., 0) to zend_hash_find(...)
Also add serializable changes to UPGRADING.INTERNALS summary
Direct creation of GracefulExit allows the the special exception object to be transfered and thrown into a destroyed fiber using the same path as any other exception thrown into a fiber instead of needing to check for a flag.
Now that inheritance can throw deprecations again, these may be
converted to exception by a custom error handler. In this case
we need to convert the exception to a fatal error, as inheritance
cannot safely throw in the general case.
This makes debug_print_backtrace() use the same formatting as exception
backtraces. The only difference is that the final #{main} is omitted,
because it wouldn't make sense for limited backtraces, and wasn't there
previously either.