A cast like (int) "123abc" gives you 123, with PHP quietly dropping the abc. This RFC from Alexandre Daubois and Nicolas Grekas calls these "fuzzy casts" and would deprecate them in PHP 8.6, then make them throw a TypeError in PHP 9.0. It also makes one change in the other direction: strict mode would accept Stringable objects for string parameters.

Why change it

Type declarations are already stricter than casts. Since PHP 7.0, passing "123abc" to an int parameter throws a TypeError, but the cast lets the same value through. That means something like "19.99corrupted" can turn into 19 without any warning.

The authors say this pushes people to cast values just to satisfy strict types, and the code ends up looser than it looks.

Stringable is the other half. An object that implements it promises it can be safely converted to a string, yet strict mode still rejects it for a string parameter today.

Show me

// Still fine
(int) "123";       // 123
(int) "  42  ";    // 42
(float) "1e3";     // 1000.0

// Deprecated in 8.6, TypeError in 9.0
(int) "123abc";    // returns 123 for now
(int) "abc";       // returns 0 for now
(object) 42;       // returns stdClass for now

And the Stringable change, where $user is an object that implements Stringable:

declare(strict_types=1);

function greet(string $name): string { return "Hello, $name!"; }

greet($user);  // PHP 8.5: TypeError, PHP 8.6: "Hello, John!"

What it means for existing code

Code like (int) $_POST['quantity'] will emit a deprecation in PHP 8.6 when the value isn't a valid number, and the same goes for intval(), floatval() and settype(). You can validate the value first with is_numeric() or filter_var(). For (object) 42, switch to an array cast like (object) ['value' => 42].

Some casts are unaffected. (bool) casts behave the same, and so do array-to-object casts.

The authors tested the change against Symfony and it raised only a few dozen deprecations. Code that depends on strict mode rejecting Stringable would need updating, but the RFC expects that to be rare.

Where it stands

The RFC is under discussion on the internals mailing list, and no voting dates are set. It would need a two-thirds majority to pass.