Skip to content

Report PHP language deprecations from PHP 7.3 to 8.5 - #6913

Open
ondrejmirtes wants to merge 13 commits into
2.3.xfrom
php-language-deprecations
Open

ondrejmirtes wants to merge 13 commits into
2.3.xfrom
php-language-deprecations

Conversation

@ondrejmirtes

Copy link
Copy Markdown
Member

Adds rules for PHP language deprecations and errors from PHP 7.3 through 8.5 that weren't reported until now. Each one is gated by a new PhpVersion method, so it only fires when the analysed PHP version is affected. Where the rewrite provably keeps the current behaviour, the error is fixable with --fix.

One commit per deprecation:

PHP Reported Fix
7.3 continue targeting a switch (compile-time warning) break, only when no loop encloses the switch. Inside a loop the tip suggests the continue N that reaches the nearest loop.
8.1 Assigning to, destructuring into, incrementing, unsetting, iterating into or referencing $GLOBALS itself (compile-time error) –
8.1 current(), pos(), key(), next(), prev(), reset(), end() on objects, respecting the rule level for unions –
8.1 Calling static methods and accessing static properties directly on a trait –
8.2 HTML-ENTITIES, BASE64, UUENCODE, Quoted-Printable (and aliases) as the encoding of mbstring functions –
8.3 get_class() / get_parent_class() without arguments; get_class() without arguments outside of a class (throws an Error) self::class / parent::class (only when a parent class is known)
8.4 trigger_error() / user_error() with E_USER_ERROR –
8.4 Power of base 0 and negative exponent (**, **=, pow()) fpow(), which returns the same IEEE 754 result, for int and float operands
8.4 fgetcsv(), fputcsv(), str_getcsv(), SplFileObject::setCsvControl() without $escape Passes the current default explicitly
8.4 _ as a class, interface, trait or enum name –
8.5 __debugInfo() returning null, explicitly or implicitly return [];
8.5 ord() with a string that is not exactly one byte long Passes the first byte
8.5 $context passed to finfo_buffer() / finfo::buffer() Removes the argument

Fixes are not offered where they would drop side effects, for example return $this->log(); in __debugInfo() or context: stream_context_create().

I ran every test fixture on real PHP runtimes (8.5.8, and 8.4 for older behaviour). The reported lines match exactly where PHP emits the deprecation, and each .fixed file prints the same output with the fixed deprecations gone. That run also shaped a few edge cases:

  • A named argument that skips over $escape counts as passing it, so that call is not reported.
  • SplFileObject::fgetcsv() and fputcsv() are left out, because an earlier setCsvControl() call silences them.
  • Encoding lists in $from_encoding never trigger the mbstring deprecation, so they are excluded.
  • Under strict_types, ord(12) is a TypeError that the argument type check already reports, so this rule skips it.

Since PHP 7.3, continue targeting a switch emits a compile-time warning
because it behaves like break. Outside of an enclosing loop the error
is fixable by replacing it with break. Inside a loop the tip suggests
the continue level that reaches the nearest loop.

Amp-Thread-ID: https://ampcode.com/threads/T-01a19c16-abb2-754f-b615-8cf680c7b5a2
Since PHP 8.1, assigning to, unsetting, incrementing, destructuring
into or taking a reference of the $GLOBALS variable itself is
a compile-time error. Only its elements can be modified.
Since PHP 8.1, calling current(), pos(), key(), next(), prev(), reset()
and end() on an object is deprecated. Arguments that may be objects are
reported according to the rule level, the same as argument types.
Since PHP 8.1, calling a static method or accessing a static property
directly on a trait is deprecated. They should only be accessed on
a class using the trait.
Since PHP 8.2, passing HTML-ENTITIES, BASE64, UUENCODE or
Quoted-Printable (or their aliases) as the encoding of an mbstring
function is deprecated. The tip names the dedicated function to use
instead.

Amp-Thread-ID: https://ampcode.com/threads/T-01a19c16-abb2-754f-b615-8cf680c7b5a2
Since PHP 8.3, calling them without arguments is deprecated. The error
is fixable by replacing the call with self::class, or with
parent::class when the class is known to have a parent.

Calling get_class() without arguments outside of a class throws an
Error and is reported regardless of the PHP version.
Since PHP 8.4, passing E_USER_ERROR to trigger_error() or user_error()
is deprecated in favour of throwing an exception or calling exit().
Since PHP 8.4, raising zero to a negative power with the ** operator or
pow() is deprecated. For int and float operands the error is fixable by
calling fpow(), which returns the same IEEE 754 result.
Since PHP 8.4, calling fgetcsv(), fputcsv(), str_getcsv() and
SplFileObject::setCsvControl() without passing $escape is deprecated
because its default value will change. The error is fixable by passing
the current default explicitly.
Since PHP 8.4, declaring a class, interface, trait or enum named "_"
is deprecated.
Since PHP 8.5, returning null from __debugInfo(), explicitly or
implicitly, is deprecated. Returning null, a variable or nothing is
fixable by returning an empty array.

Amp-Thread-ID: https://ampcode.com/threads/T-01a19c16-abb2-754f-b615-8cf680c7b5a2
Since PHP 8.5, passing an empty string or a string longer than one byte
to ord() is deprecated. When the string is known to be longer, the
error is fixable by passing its first byte explicitly.
Since PHP 8.5, passing the unused $context parameter to finfo_buffer()
and finfo::buffer() is deprecated. The error is fixable by removing the
argument when doing so does not drop any side effects.
@ondrejmirtes
ondrejmirtes force-pushed the php-language-deprecations branch from 326aff7 to 612cd1f Compare November 2, 2026 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant