Skip to content

Commit c530f24

Browse files
committed
Merge branch 'master' into php-build-provider-constant
2 parents 3afe58b + e91d2c7 commit c530f24

File tree

89 files changed

+1974
-503
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+1974
-503
lines changed

.github/actions/apt-x32/action.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ runs:
3535
libssl-dev:i386 \
3636
libwebp-dev:i386 \
3737
libxml2-dev:i386 \
38-
libxml2-dev:i386 \
3938
libxpm-dev:i386 \
4039
libxslt1-dev:i386 \
4140
firebird-dev:i386 \

NEWS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ PHP NEWS
33
?? ??? ????, PHP 8.5.0alpha3
44

55
- Core:
6+
. Add clone-with support to the clone() function. (timwolla, edorian)
7+
. Fix support for non-userland stream notifiers. (timwolla)
68
. Added PHP_BUILD_PROVIDER constant. (timwolla)
79

810
- Curl:
@@ -13,11 +15,17 @@ PHP NEWS
1315
. socket_set_option for multicast context throws a ValueError
1416
when the socket family is not of AF_INET/AF_INET6 family. (David Carlier)
1517

18+
- Standard:
19+
. Add HEIF/HEIC support to getimagesize. (Benstone Zhang)
20+
. Implement #71517 (Implement SVG support for getimagesize() and friends).
21+
(nielsdos)
22+
1623
- URI:
1724
. Empty host handling is fixed. (Máté Kocsis)
1825
. Error handling of Uri\WhatWg\Url::withHost() is fixed when the input
1926
contains a port. Now, it triggers an exception; previously, the error
2027
was silently swallowed. (Máté Kocsis)
28+
. Support empty URIs with Uri\Rfc3986\Uri. (timwolla)
2129

2230
17 Jul 2025, PHP 8.5.0alpha2
2331

UPGRADING

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,16 @@ PHP 8.5 UPGRADE NOTES
244244
process was terminated unexpectedly. In such cases, a warning is emitted
245245
and the function returns false. Previously, these errors were silently
246246
ignored. This change affects only the sendmail transport.
247+
. getimagesize() now supports HEIF/HEIC images.
248+
249+
- Standard:
250+
. getimagesize() now supports SVG images when ext-libxml is also loaded.
251+
Similarly, image_type_to_extension() and image_type_to_extension()
252+
now also handle IMAGETYPE_SVG.
253+
. The array returned by getimagesize() now has two additional entries:
254+
"width_unit" and "height_unit" to indicate in which units the dimensions
255+
are expressed. These units are px by default. They are not necessarily
256+
the same (just to give one example: one may be cm and the other may be px).
247257

248258
- XSL:
249259
. The $namespace argument of XSLTProcessor::getParameter(),
@@ -408,7 +418,8 @@ PHP 8.5 UPGRADE NOTES
408418
. get_exception_handler() allows retrieving the current user-defined exception
409419
handler function.
410420
RFC: https://wiki.php.net/rfc/get-error-exception-handler
411-
. The clone language construct is now a function.
421+
. The clone language construct is now a function and supports reassigning
422+
(readonly) properties during cloning via the new $withProperties parameter.
412423
RFC: https://wiki.php.net/rfc/clone_with_v2
413424

414425
- Curl:
@@ -565,6 +576,9 @@ PHP 8.5 UPGRADE NOTES
565576
. T_VOID_CAST.
566577
. T_PIPE.
567578

579+
- Standard:
580+
. IMAGETYPE_SVG when libxml is loaded.
581+
568582
========================================
569583
11. Changes to INI File Handling
570584
========================================

UPGRADING.INTERNALS

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ PHP 8.5 INTERNALS UPGRADE NOTES
2323
the user side when requiring libphp.so, by using dlmopen with LM_ID_NEWLM
2424
instead of dlopen.
2525
RTLD_DEEPBIND is still enabled when the Apache SAPI is in use.
26+
. The ptr field of the php_stream_notifier struct is now a void* instead
27+
of a zval. If the zval was used to store IS_PTR values only, the
28+
extra layer of indirection can be removed. In other cases a zval can
29+
be heap-allocated and stored in the pointer as a minimal change to keep
30+
compatibility.
2631

2732
- Zend
2833
. Added zend_safe_assign_to_variable_noref() function to safely assign
@@ -129,6 +134,10 @@ PHP 8.5 INTERNALS UPGRADE NOTES
129134
. The php_std_date() function has been removed. Use php_format_date() with
130135
the "D, d M Y H:i:s \\G\\M\\T" format instead.
131136
. Added php_url_encode_to_smart_str() to encode a URL to a smart_str buffer.
137+
. The functionality of getimagesize(), image_type_to_mime_type(),
138+
and image_type_to_extension() is now extensible using the internal APIs
139+
php_image_register_handler() and php_image_unregister_handler() in
140+
php_image.h.
132141

133142
========================
134143
4. OpCode changes
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
--TEST--
2+
Clone with basic
3+
--FILE--
4+
<?php
5+
6+
class Dummy { }
7+
8+
$x = new stdClass();
9+
10+
$foo = 'FOO';
11+
$bar = new Dummy();
12+
$array = [
13+
'baz' => 'BAZ',
14+
'array' => [1, 2, 3],
15+
];
16+
17+
var_dump(clone $x);
18+
var_dump(clone($x));
19+
var_dump(clone($x, [ 'foo' => $foo, 'bar' => $bar ]));
20+
var_dump(clone($x, $array));
21+
var_dump(clone($x, [ 'obj' => $x ]));
22+
23+
var_dump(clone($x, [
24+
'abc',
25+
'def',
26+
new Dummy(),
27+
'named' => 'value',
28+
]));
29+
30+
?>
31+
--EXPECTF--
32+
object(stdClass)#%d (0) {
33+
}
34+
object(stdClass)#%d (0) {
35+
}
36+
object(stdClass)#%d (2) {
37+
["foo"]=>
38+
string(3) "FOO"
39+
["bar"]=>
40+
object(Dummy)#%d (0) {
41+
}
42+
}
43+
object(stdClass)#%d (2) {
44+
["baz"]=>
45+
string(3) "BAZ"
46+
["array"]=>
47+
array(3) {
48+
[0]=>
49+
int(1)
50+
[1]=>
51+
int(2)
52+
[2]=>
53+
int(3)
54+
}
55+
}
56+
object(stdClass)#%d (1) {
57+
["obj"]=>
58+
object(stdClass)#%d (0) {
59+
}
60+
}
61+
object(stdClass)#%d (4) {
62+
["0"]=>
63+
string(3) "abc"
64+
["1"]=>
65+
string(3) "def"
66+
["2"]=>
67+
object(Dummy)#%d (0) {
68+
}
69+
["named"]=>
70+
string(5) "value"
71+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
--TEST--
2+
Clone with respects visiblity
3+
--FILE--
4+
<?php
5+
6+
class P {
7+
public $a = 'default';
8+
protected $b = 'default';
9+
private $c = 'default';
10+
public private(set) string $d = 'default';
11+
12+
public function m1() {
13+
return clone($this, [ 'a' => 'updated A', 'b' => 'updated B', 'c' => 'updated C', 'd' => 'updated D' ]);
14+
}
15+
}
16+
17+
class C extends P {
18+
public function m2() {
19+
return clone($this, [ 'a' => 'updated A', 'b' => 'updated B', 'c' => 'dynamic C' ]);
20+
}
21+
22+
public function m3() {
23+
return clone($this, [ 'd' => 'inaccessible' ]);
24+
}
25+
}
26+
27+
class Unrelated {
28+
public function m3(P $p) {
29+
return clone($p, [ 'b' => 'inaccessible' ]);
30+
}
31+
}
32+
33+
$p = new P();
34+
35+
var_dump(clone($p, [ 'a' => 'updated A' ]));
36+
var_dump($p->m1());
37+
38+
$c = new C();
39+
var_dump($c->m1());
40+
var_dump($c->m2());
41+
try {
42+
var_dump($c->m3());
43+
} catch (Error $e) {
44+
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
45+
}
46+
47+
try {
48+
var_dump(clone($p, [ 'b' => 'inaccessible' ]));
49+
} catch (Error $e) {
50+
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
51+
}
52+
53+
try {
54+
var_dump(clone($p, [ 'd' => 'inaccessible' ]));
55+
} catch (Error $e) {
56+
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
57+
}
58+
59+
try {
60+
var_dump((new Unrelated())->m3($p));
61+
} catch (Error $e) {
62+
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
63+
}
64+
65+
?>
66+
--EXPECTF--
67+
object(P)#%d (4) {
68+
["a"]=>
69+
string(9) "updated A"
70+
["b":protected]=>
71+
string(7) "default"
72+
["c":"P":private]=>
73+
string(7) "default"
74+
["d"]=>
75+
string(7) "default"
76+
}
77+
object(P)#%d (4) {
78+
["a"]=>
79+
string(9) "updated A"
80+
["b":protected]=>
81+
string(9) "updated B"
82+
["c":"P":private]=>
83+
string(9) "updated C"
84+
["d"]=>
85+
string(9) "updated D"
86+
}
87+
object(C)#%d (4) {
88+
["a"]=>
89+
string(9) "updated A"
90+
["b":protected]=>
91+
string(9) "updated B"
92+
["c":"P":private]=>
93+
string(9) "updated C"
94+
["d"]=>
95+
string(9) "updated D"
96+
}
97+
98+
Deprecated: Creation of dynamic property C::$c is deprecated in %s on line %d
99+
object(C)#%d (5) {
100+
["a"]=>
101+
string(9) "updated A"
102+
["b":protected]=>
103+
string(9) "updated B"
104+
["c":"P":private]=>
105+
string(7) "default"
106+
["d"]=>
107+
string(7) "default"
108+
["c"]=>
109+
string(9) "dynamic C"
110+
}
111+
Error: Cannot modify private(set) property P::$d from scope C
112+
Error: Cannot access protected property P::$b
113+
Error: Cannot modify private(set) property P::$d from global scope
114+
Error: Cannot access protected property P::$b
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Clone with supports property hooks
3+
--FILE--
4+
<?php
5+
6+
class Clazz {
7+
public string $hooked = 'default' {
8+
set {
9+
$this->hooked = strtoupper($value);
10+
}
11+
}
12+
}
13+
14+
$c = new Clazz();
15+
16+
var_dump(clone($c, [ 'hooked' => 'updated' ]));
17+
18+
?>
19+
--EXPECTF--
20+
object(Clazz)#%d (1) {
21+
["hooked"]=>
22+
string(7) "UPDATED"
23+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
--TEST--
2+
Clone with evaluation order
3+
--FILE--
4+
<?php
5+
6+
class Clazz {
7+
public string $hooked = 'default' {
8+
set {
9+
echo __FUNCTION__, PHP_EOL;
10+
11+
$this->hooked = strtoupper($value);
12+
}
13+
}
14+
15+
public string $maxLength {
16+
set {
17+
echo __FUNCTION__, PHP_EOL;
18+
19+
if (strlen($value) > 5) {
20+
throw new \Exception('Length exceeded');
21+
}
22+
23+
$this->maxLength = $value;
24+
}
25+
}
26+
27+
public string $minLength {
28+
set {
29+
echo __FUNCTION__, PHP_EOL;
30+
31+
if (strlen($value) < 5) {
32+
throw new \Exception('Length unsufficient');
33+
}
34+
35+
$this->minLength = $value;
36+
}
37+
}
38+
}
39+
40+
$c = new Clazz();
41+
42+
var_dump(clone($c, [ 'hooked' => 'updated' ]));
43+
echo PHP_EOL;
44+
var_dump(clone($c, [ 'hooked' => 'updated', 'maxLength' => 'abc', 'minLength' => 'abcdef' ]));
45+
echo PHP_EOL;
46+
var_dump(clone($c, [ 'minLength' => 'abcdef', 'hooked' => 'updated', 'maxLength' => 'abc' ]));
47+
48+
?>
49+
--EXPECTF--
50+
$hooked::set
51+
object(Clazz)#%d (1) {
52+
["hooked"]=>
53+
string(7) "UPDATED"
54+
["maxLength"]=>
55+
uninitialized(string)
56+
["minLength"]=>
57+
uninitialized(string)
58+
}
59+
60+
$hooked::set
61+
$maxLength::set
62+
$minLength::set
63+
object(Clazz)#%d (3) {
64+
["hooked"]=>
65+
string(7) "UPDATED"
66+
["maxLength"]=>
67+
string(3) "abc"
68+
["minLength"]=>
69+
string(6) "abcdef"
70+
}
71+
72+
$minLength::set
73+
$hooked::set
74+
$maxLength::set
75+
object(Clazz)#%d (3) {
76+
["hooked"]=>
77+
string(7) "UPDATED"
78+
["maxLength"]=>
79+
string(3) "abc"
80+
["minLength"]=>
81+
string(6) "abcdef"
82+
}

0 commit comments

Comments
 (0)