Skip to content

Add unserialize() throw type extension - #6528

Merged
ondrejmirtes merged 1 commit into
2.2.xfrom
unserialize-throw-type
Sep 22, 2026
Merged

ondrejmirtes merged 1 commit into
2.2.xfrom
unserialize-throw-type

Conversation

@ondrejmirtes

Copy link
Copy Markdown
Member

PhpStorm stubs now declare @throws \TypeError and @throws \ValueError on unserialize(), so every call became an explicit throw point.

On PHP 8.0+, unserialize() throws:

  • TypeError / ValueError for invalid $options:
    • allowed_classes that is not array|bool;
    • an allowed_classes entry that is not a valid class name (8.4+);
    • max_depth that is not an int, or is negative.
  • TypeError when the data does not fit a typed property (Cannot assign string to property R::$x of type int), whatever the options.

PHP 7 only warns.

The extension decides on native types:

  • Without $options, or with a constant options array that is valid: TypeError only.
    • Valid means: allowed_classes is absent, a bool, or a list of constant class-name strings; and max_depth is absent or int<0, max>.
  • allowed_classes set to false or []: VoidType. Objects then become __PHP_Incomplete_Class, so no typed property can reject the data (checked on PHP 8.5).
  • Anything else, including non-constant options: the declared TypeError|ValueError.

Tests are in CatchWithUnthrownExceptionRuleTest, with separate expectations for PHP 8.0+ and for PHP < 8.0, where every catch is dead. Both fail without the extension; the < 8.0 expectations were verified locally on PHP 7.4.

The PRs for array_chunk(), get_class(), hash(), array_fill() and unserialize() are all based on 2.2.x. They add their test methods at different places in CatchWithUnthrownExceptionRuleTest, so they merge cleanly in any order (checked).

🤖 Generated with Claude Code

https://claude.ai/code/session_01Dhb4ssXuKVWcVBcNFpsdn7

PhpStorm stubs now declare @throws \TypeError and \ValueError on
unserialize(), which made every call an explicit throw point. Both are thrown
for invalid $options, which a call without them or with a constant valid
array cannot have, and PHP 7 only warns. TypeError is also thrown when the
data does not fit a typed property, so it stays unless no class is allowed:
then objects become __PHP_Incomplete_Class. The decisions read native types.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dhb4ssXuKVWcVBcNFpsdn7
@ondrejmirtes
ondrejmirtes merged commit 8f4a43c into 2.2.x Sep 22, 2026
875 of 890 checks passed
@ondrejmirtes
ondrejmirtes deleted the unserialize-throw-type branch September 22, 2026 11:09
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