Skip to content

PHP 8.5: Soft deprecate __sleep / __wakeup#1972

Open
afilina wants to merge 17 commits intoPHPCompatibility:developfrom
afilina:soft-deprecate-sleep-wakeup
Open

PHP 8.5: Soft deprecate __sleep / __wakeup#1972
afilina wants to merge 17 commits intoPHPCompatibility:developfrom
afilina:soft-deprecate-sleep-wakeup

Conversation

@afilina
Copy link
Copy Markdown
Contributor

@afilina afilina commented Oct 29, 2025

Part of this effort: #1849

Adding a new sniff for deprecated/removed magic methods, currently used for __sleep and __wakeup soft deprecation.

  • Message for soft deprecation adapted from RFC. Example: Magic method __wakeup() is maintained for backward compatibility since PHP 8.5. Use __unserialize instead.
  • Using SoftDeprecated error code. Other codes are Deprecated and Removed.
  • Applies to classes, anonymous classes, and traits.
  • Interfaces were excluded because the value is debatable, since no behavior change will occur.
  • Assumed 10.0.0 target release
  • Included references in the sniff above each magic method entry. It seemed useful.

@afilina
Copy link
Copy Markdown
Contributor Author

afilina commented Oct 29, 2025

@jrfnl Here is the sniff we discussed earlier today. Happy to chat for feedback, since this is my first proper sniff contribution.

@afilina afilina marked this pull request as draft October 31, 2025 13:48
@afilina
Copy link
Copy Markdown
Contributor Author

afilina commented Oct 31, 2025

Same comment about documentation for these kinds of sniffs: #1975 (comment)

@afilina afilina marked this pull request as ready for review October 31, 2025 15:38
@afilina afilina changed the title Soft deprecate __sleep / __wakeup PHP 8.5: Soft deprecate __sleep / __wakeup Nov 14, 2025
@afilina
Copy link
Copy Markdown
Contributor Author

afilina commented Dec 4, 2025

@jrfnl Onto which branch should I rebase my PRs for errors in unrelated files to go away?

Edit: I sifted through the conversation on another PR and saw that it was develop. I did the same here.

Only detecting the presence now. Need other cases and supporting sniff code.
There is no need to show a warning when __serialize is implemented in the same class as __sleep, because the first would take precedence, so no behavior change will occur in that context.

Add tests to cover scopes in which these methods are actual magic methods. Currently, these are classes, anonymous classes, and traits. Interfaces were excluded because the value of adding our warning is debatable, since no behavior change will occur.
- Since token numbers can be 0, the `!` can coerce it to false and break the sniff.
- Remove single-use variables where it wouldn't impact readability much.
- Comments on test cases/fixtures are now more detailed to make it easier to reason about and maintain the test.
- Capture a variety of syntaxes where the target function names and the word "function" are present, but it's not the _syntax_ we want.
- Renumber all the tests case lines
- __wakeup targeting incorrect line number
- Scan the entire file for false positives
- False positives now target the same version as the main test
- Hardcode version numbers to make tests easier to read
@afilina afilina force-pushed the soft-deprecate-sleep-wakeup branch from f82bea1 to 529412a Compare December 4, 2025 17:51
@jrfnl
Copy link
Copy Markdown
Member

jrfnl commented Dec 4, 2025

@jrfnl Onto which branch should I rebase my PRs for errors in unrelated files to go away?

develop is where development happens, so feel free to rebase on that.

@afilina
Copy link
Copy Markdown
Contributor Author

afilina commented Dec 4, 2025

@jrfnl It looks like the CI is giving me mutually-exclusive requirements. One job wants me to add visibility to class constants, but if I do that, other jobs will complain about invalid syntax on older PHP versions. Unless I'm not seeing something obvious, there's no way to resolve from my end other than not using class constants in my sniff.

@afilina
Copy link
Copy Markdown
Contributor Author

afilina commented Dec 4, 2025

@jrfnl I untangled this! I can't seem to find proof in Actions, but I definitely saw a PHPCS 3 in there and a whole bunch of failures (something about PHP 5.5 even). This all went away when I rebased. Then I could add constant visibility.

So it was just bad luck due to the timing of my PR relative to the PHPCS 3 drop. I'll rebase any remaining open PRs right away to avoid this.

@afilina
Copy link
Copy Markdown
Contributor Author

afilina commented Dec 4, 2025

@jrfnl Ready for review. To recap my changes:

  • Matched test structure (files, method names, comments, whether we test the whole file or per-line, etc.) to what we did in the previous PR you merged.
  • Fixed target versions for various tests, as here it's a deprecated feature instead of a new feature.
  • Rebased and fixed any CS issues.

@jrfnl
Copy link
Copy Markdown
Member

jrfnl commented Dec 6, 2025

@afilina Thank you for your work on this. I'm nearly done reviewing the PR, but before I post my review, I want to have a discussion about whether this sniff should exist (at this time).

As a rule of thumb, PHPCompatibility flags changes in behaviour in PHP and a soft deprecation does not yield any change in the behaviour in PHP.

While PHPCompatibility does contain a few exceptions to that rule (for example: reserved namespaces), this soft deprecation of _sleep() and __wakeup() doesn't feel like one which should qualify for such an exception.

Background of the deprecation in PHP:

  • Originally it was proposed and accepted to hard deprecate _sleep() and __wakeup() in PHP 8.5.
  • Once some of the bigger projects started looking into this, they found that the information provided in the original RFC was misleading and that the costs of mitigating the deprecation would likely be much higher than anticipated.
  • Additionally, the complexity of mitigating the deprecation also means that the mitigation would carry a high risk of bugs, especially in projects with less experienced developers.
  • As a result of this real-world experience, a late PHP 8.5 RFC was proposed and accepted to change the hard deprecation (with notice at runtime) to a soft deprecation (no notice at runtime, documentation only deprecation).

Now, if PHP itself has made the choice not to hard drive this deprecation via a notice due to the cost and complexity, why should PHPCompatibility now start driving this change by flagging the methods anyway ?

/cc @MarkMaldaba

@MarkMaldaba
Copy link
Copy Markdown
Contributor

/cc @MarkMaldaba

I agree with this assessment. If the code running on PHP 8.5 gives functionally identical behaviour and outputs as earlier versions then there is not a compatibility issue to be reported.

@afilina
Copy link
Copy Markdown
Contributor Author

afilina commented Dec 9, 2025

@jrfnl @MarkMaldaba The long-term plan is to still deprecate and remove these magic methods. As someone who creates long-term modernization roadmaps for customers, it's always of huge help to have early heads-up on practices that should be discontinued. It gives more time to address issues and prevents new code from introducing future incompatibilities. The effort needed to fix an incompatibility is irrelevant. And if someone isn't ready to address an issue in their code, they can always suppress a sniff via config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants