Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
aad3d93
Update screens for operator semantics that changed
KentarouTakeda Jul 27, 2026
99304e8
Update screens for diagnostics that changed
KentarouTakeda Jul 27, 2026
410ad2f
Reflect a tentative return type instead of a built-in function
KentarouTakeda Jul 27, 2026
a5e5417
Regenerate the ReflectionClass::__toString() screen
KentarouTakeda Jul 27, 2026
90da1c9
Update screens for how class names are printed
KentarouTakeda Jul 27, 2026
8019374
Update the mb_detect_encoding() screen for its PHP 8.3 behaviour
KentarouTakeda Jul 27, 2026
5b3a466
Split the mb_detect_encoding() screens at PHP 8.3
KentarouTakeda Jul 31, 2026
d1e9f23
Use simpara for the getReturnType() note
KentarouTakeda Jul 31, 2026
05846fc
Merge the . precedence examples and split them at PHP 8.0
KentarouTakeda Aug 1, 2026
f2738aa
Note the instanceof constant error removed at PHP 7.3
KentarouTakeda Aug 1, 2026
84e7d83
Split the foreach list() screens at PHP 8.0
KentarouTakeda Aug 1, 2026
d0013d0
Split the __set_state() screens at PHP 8.2
KentarouTakeda Aug 1, 2026
96e2f6e
Keep Run code off the mb_detect_encoding() PHP 8.2 screen
KentarouTakeda Aug 1, 2026
6f02892
Use `fopen()` to show a built-in without a declared return type
KentarouTakeda Aug 4, 2026
ac23008
Document only the current `mb_detect_encoding()` output
KentarouTakeda Aug 4, 2026
5ad2d0e
Document only the current `var_export()` output for `__set_state()`
KentarouTakeda Aug 4, 2026
0f9e0a1
Update the anonymous class screens that no version produces
KentarouTakeda Aug 4, 2026
78a36c5
Apply suggestions from code review
KentarouTakeda Aug 4, 2026
db1b881
Mark the volatile Reflection and enum screens as similar output
KentarouTakeda Aug 4, 2026
f71c8be
Leave the opaque anonymous class name alone
KentarouTakeda Aug 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions language/control-structures/foreach.xml
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,11 @@ foreach ($array as [, , $c]) {
</para>

<para>
A notice will be generated if there aren't enough array elements to fill
the <function>list</function>:
If there are not enough array elements to populate the variables,
a warning is emitted; prior to PHP 8.0.0, a notice was emitted instead:

<informalexample>
<programlisting role="php">
<programlisting role="php" annotations="non-interactive">
<![CDATA[
<?php
$array = [
Expand All @@ -238,13 +238,23 @@ foreach ($array as [$a, $b, $c]) {
}
]]>
</programlisting>
&example.outputs;
&example.outputs.71;
<screen>
<![CDATA[
Notice: Undefined offset: 2 in script on line 7
A: 1; B: 2; C:

Notice: Undefined offset: 2 in script on line 7
A: 3; B: 4; C:
]]>
</screen>
&example.outputs.8;
<screen>
<![CDATA[
Notice: Undefined offset: 2 in example.php on line 7
Warning: Undefined array key 2 in script on line 7
A: 1; B: 2; C:

Notice: Undefined offset: 2 in example.php on line 7
Warning: Undefined array key 2 in script on line 7
A: 3; B: 4; C:
]]>
</screen>
Expand Down
4 changes: 2 additions & 2 deletions language/oop5/anonymous.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ var_dump(new class(10) extends SomeClass implements SomeInterface {
&example.outputs;
<screen>
<![CDATA[
object(class@anonymous)#1 (1) {
["Command line code0x104c5b612":"class@anonymous":private]=>
object(SomeClass@anonymous)#1 (1) {
["num":"SomeClass@anonymous":private]=>
Comment on lines +66 to +67

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, I am not actually sure what's changed. I can see that PHP 8 uses the parent class name, but is this important? Is this intentional or just an implementation detail?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional — migration80 lists it under incompatible changes, with examples for ParentClass@anonymous, FirstInterface@anonymous and class@anonymous.

But the naming is not really why this hunk exists. The old screen printed ["Command line code0x104c5b612":"class@anonymous":private], where the property-name slot holds part of the class name. 7.4 prints ["num":"class@anonymous":private]. It was a broken capture rather than an outdated one.

int(10)
}
]]>
Expand Down
2 changes: 1 addition & 1 deletion language/oop5/magic.xml
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ var_dump($c);
&example.outputs;
<screen>
<![CDATA[
string(60) "A::__set_state(array(
string(61) "\A::__set_state(array(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't even remember what this change was. Is this something that we document or is this an implementation detail?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documented and intentional — migration82 lists it under incompatible changes ("var_export() no longer omits the leading backslash for exported classes").

I dropped the split anyway. This example is about __set_state(); the backslash is a var_export() detail. 8.1 is EOL, so the current output covers every supported version.

'var1' => 5,
'var2' => 'foo',
))"
Expand Down
55 changes: 28 additions & 27 deletions language/operators/precedence.xml
Original file line number Diff line number Diff line change
Expand Up @@ -371,32 +371,6 @@ $array[$i] = $i++; // may set either index 1 or 2
]]>
</programlisting>
</example>
<example>
<title><literal>+</literal>, <literal>-</literal> and <literal>.</literal> precedence</title>
<programlisting role="php">
<![CDATA[
<?php
$x = 4;
// this line might result in unexpected output:
echo "x minus one equals " . $x-1 . ", or so I hope\n";

// the desired precedence can be enforced by using parentheses:
echo "x minus one equals " . ($x-1) . ", or so I hope\n";

// this is not allowed, and throws a TypeError:
echo (("x minus one equals " . $x) - 1) . ", or so I hope\n";
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
-1, or so I hope
-1, or so I hope
Fatal error: Uncaught TypeError: Unsupported operand types: string - int
]]>
</screen>
</example>
<example>
<title>Prior to PHP 8, <literal>+</literal>, <literal>-</literal> and <literal>.</literal> had the same precedence</title>
<programlisting role="php" annotations="non-interactive">
Expand All @@ -414,16 +388,43 @@ echo "x minus one equals " . ($x-1) . ", or so I hope\n";
?>
]]>
</programlisting>
&example.outputs;
&example.outputs.71;
<screen>
<![CDATA[
Warning: A non-numeric value encountered in script on line 4
-1, or so I hope

Warning: A non-numeric value encountered in script on line 7
-1, or so I hope
x minus one equals 3, or so I hope
]]>
</screen>
&example.outputs.8;
<screen>
<![CDATA[
x minus one equals 3, or so I hope

Fatal error: Uncaught TypeError: Unsupported operand types: string - int in script:7
Stack trace:
#0 {main}
thrown in script on line 7
]]>
</screen>
</example>
</para>
<simpara>
As of PHP 7.4.0 the first line also emits
<literal>Deprecated: The behavior of unparenthesized expressions containing
both '.' and '+'/'-' will change in PHP 8: '+'/'-' will take a higher
precedence</literal>.
</simpara>
<simpara>
As of PHP 8.0.0 the pitfall is gone, because <literal>-</literal> now binds
tighter than <literal>.</literal>.
The second line, which spells out the grouping that used to apply, throws a
<exceptionname>TypeError</exceptionname> instead, so the third line never
runs.
</simpara>
<note>
<para>
Although <literal>=</literal> has a lower precedence than
Expand Down
5 changes: 4 additions & 1 deletion language/operators/type.xml
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ $c = fopen('/tmp/', 'r');
var_dump($a instanceof stdClass); // $a is an integer
var_dump($b instanceof stdClass); // $b is NULL
var_dump($c instanceof stdClass); // $c is a resource

// Prior to PHP 7.3.0, using a constant would trigger a compile-time fatal error with the following message:
// instanceof expects an object instance, constant given
var_dump(FALSE instanceof stdClass);
?>
]]>
Expand All @@ -188,7 +191,7 @@ var_dump(FALSE instanceof stdClass);
bool(false)
bool(false)
bool(false)
PHP Fatal error: instanceof expects an object instance, constant given
bool(false)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, but we need to retain the error message. Perhaps split it into two outputs per version? Or just add a code comment on var_dump(FALSE instanceof stdClass); saying it would throw with this error message?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Took the code comment. A split would mislead here: prior to 7.3 this is a compile-time error, so 7.2 prints the fatal line and nothing else — none of the three bool(false) above it ever run. The screen that was here, three bools followed by the fatal error, was never any version's output.

That's why the comment says "so nothing above ran". The 7.3 boundary itself is already covered by the example directly below, which uses &example.outputs.73;.

]]>
</screen>
</example>
Expand Down
4 changes: 2 additions & 2 deletions language/predefined/backedenum/from.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ $b = Suit::from('B');
?>
]]>
</programlisting>
&example.outputs;
&example.outputs.similar;
<screen>
<![CDATA[
enum(Suit::Hearts)

Fatal error: Uncaught ValueError: "B" is not a valid backing value for enum "Suit" in /file.php:15
Fatal error: Uncaught ValueError: "B" is not a valid backing value for enum Suit in script:14
]]>
</screen>
</example>
Expand Down
5 changes: 3 additions & 2 deletions reference/mbstring/functions/mb-detect-encoding.xml
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,8 @@ string(5) "ASCII"
// 'áéóú' encoded in ISO-8859-1
$str = "\xE1\xE9\xF3\xFA";

// The string is not valid ASCII or UTF-8, but UTF-8 is considered a closer match
// The string is valid in neither encoding: non-strict reports the closest
// match, strict returns false
var_dump(mb_detect_encoding($str, ['ASCII', 'UTF-8'], false));
var_dump(mb_detect_encoding($str, ['ASCII', 'UTF-8'], true));

Expand All @@ -191,7 +192,7 @@ var_dump(mb_detect_encoding($str, ['ASCII', 'UTF-8', 'ISO-8859-1'], true));
&example.outputs;
<screen>
<![CDATA[
string(5) "UTF-8"
string(5) "ASCII"
bool(false)
string(10) "ISO-8859-1"
string(10) "ISO-8859-1"
Expand Down
86 changes: 64 additions & 22 deletions reference/reflection/reflectionclass/tostring.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ echo $reflectionClass->__toString();
?>
]]>
</programlisting>
&example.outputs;
&example.outputs.similar;
<screen>
<![CDATA[
Class [ <internal:Core> class Exception ] {
Class [ <internal:Core> class Exception implements Stringable, Throwable ] {

- Constants [0] {
}
Expand All @@ -58,50 +58,92 @@ Class [ <internal:Core> class Exception ] {
}

- Properties [7] {
Property [ <default> protected $message ]
Property [ <default> private $string ]
Property [ <default> protected $code ]
Property [ <default> protected $file ]
Property [ <default> protected $line ]
Property [ <default> private $trace ]
Property [ <default> private $previous ]
Property [ protected $message = '' ]
Property [ private string $string = '' ]
Property [ protected $code = 0 ]
Property [ protected string $file = '' ]
Property [ protected int $line = 0 ]
Property [ private array $trace = [] ]
Property [ private ?Throwable $previous = NULL ]
}

- Methods [10] {
Method [ <internal:Core> final private method __clone ] {
- Methods [11] {
Method [ <internal:Core> private method __clone ] {

- Parameters [0] {
}
- Return [ void ]
}

Method [ <internal:Core, ctor> public method __construct ] {

- Parameters [3] {
Parameter #0 [ <optional> $message ]
Parameter #1 [ <optional> $code ]
Parameter #2 [ <optional> $previous ]
Parameter #0 [ <optional> string $message = "" ]
Parameter #1 [ <optional> int $code = 0 ]
Parameter #2 [ <optional> ?Throwable $previous = null ]
}
}

Method [ <internal:Core> final public method getMessage ] {
Method [ <internal:Core> public method __wakeup ] {

- Parameters [0] {
}
- Tentative return [ void ]
}

Method [ <internal:Core> final public method getCode ] {
Method [ <internal:Core, prototype Throwable> final public method getMessage ] {

- Parameters [0] {
}
- Return [ string ]
}

Method [ <internal:Core> final public method getFile ] {
Method [ <internal:Core, prototype Throwable> final public method getCode ] {

- Parameters [0] {
}
}

Method [ <internal:Core, prototype Throwable> final public method getFile ] {

- Parameters [0] {
}
- Return [ string ]
}

Method [ <internal:Core> final public method getLine ] {
Method [ <internal:Core, prototype Throwable> final public method getLine ] {

- Parameters [0] {
}
- Return [ int ]
}

Method [ <internal:Core> final public method getTrace ] {
Method [ <internal:Core, prototype Throwable> final public method getTrace ] {

- Parameters [0] {
}
- Return [ array ]
}

Method [ <internal:Core> final public method getPrevious ] {
Method [ <internal:Core, prototype Throwable> final public method getPrevious ] {

- Parameters [0] {
}
- Return [ ?Throwable ]
}

Method [ <internal:Core> final public method getTraceAsString ] {
Method [ <internal:Core, prototype Throwable> final public method getTraceAsString ] {

- Parameters [0] {
}
- Return [ string ]
}

Method [ <internal:Core> public method __toString ] {
Method [ <internal:Core, prototype Stringable> public method __toString ] {

- Parameters [0] {
}
- Return [ string ]
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,23 @@ int
<![CDATA[
<?php

$reflection2 = new ReflectionFunction('array_merge');
$reflection2 = new ReflectionFunction('fopen');

var_dump($reflection2->getReturnType());
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
null
NULL
]]>
</screen>
</example>
</para>
<para>
This is because many internal functions do not have types specified for their
parameters or return values. It is therefore best to avoid using this
method on built-in functions.
</para>
<simpara>
Internal functions that return a resource have no declared return type,
because <literal>resource</literal> cannot be used in a type declaration.
</simpara>
</refsect1>

<refsect1 role="seealso">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ bool(true)
<![CDATA[
<?php
$reflection2 = new ReflectionFunction('array_merge');
$reflection2 = new ReflectionFunction('fopen');
var_dump($reflection2->hasReturnType());
]]>
Expand Down