# RFC: Warnings for PHP 8.5

- Status: Implemented (PHP 8.5)
- Authors: Gina Peter Banyard girgias@php.net
- Date: 2025-07-14
- Version: 0.2
- Target: PHP 8.5
- Implementation: 8.5 Warn when non-representable floats are coerced to int Warn when coercing NAN to other types Warn when destructuring non-array values
- Original: https://wiki.php.net/rfc/warnings-php-8-5
- Page: https://externals.io/rfc/warnings-php-8-5
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Warn when coercing NAN to other types? (closed)

Yes: 20 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (Yes), bwoebi (Yes), derick (Yes), dharman (Yes), dunglas (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), lufei (Yes), mauricio (Yes), nicolasgrekas (Yes), ocramius (Yes), remi (Yes), sergey (Yes), theodorejb (Yes), thorstenr (Yes)

### Warn when casting out of range floats to int? (closed)

Yes: 17 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), ayesh (Yes), brzuchal (Yes), bukka (Yes), bwoebi (Yes), derick (Yes), dharman (Yes), girgias (Yes), lufei (Yes), mauricio (Yes), nicolasgrekas (Yes), ocramius (Yes), remi (Yes), theodorejb (Yes), thorstenr (Yes)

### Warn when destructuring non-array values? (closed)

Yes: 16 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), ayesh (Yes), brzuchal (Yes), bwoebi (Yes), derick (Yes), dharman (Yes), girgias (Yes), lufei (Yes), mauricio (Yes), nicolasgrekas (Yes), ocramius (Yes), remi (Yes), theodorejb (Yes), thorstenr (Yes)

### Warn when using offsets on non-container values in isset()/empty()? (closed)

Yes: 10 · No: 6

Voters: alcaeus (No), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (No), bwoebi (No), derick (No), dharman (Yes), girgias (Yes), mauricio (Yes), nicolasgrekas (No), nielsdos (No), ocramius (Yes), remi (Yes), theodorejb (Yes), thorstenr (Yes)

### Warn when using invalid offset types when checking string offsets with isset()/empty()? (closed)

Yes: 10 · No: 6

Voters: alcaeus (No), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (No), bwoebi (No), derick (No), dharman (No), girgias (Yes), mauricio (Yes), nicolasgrekas (Yes), nielsdos (No), ocramius (Yes), remi (Yes), theodorejb (Yes), thorstenr (Yes)

## Discussions on the mailing list

- [\[RFC\] Warnings for PHP 8.5](https://externals.io/message/128040.md) — started on 2025-07-14, 23 messages
- [\[RFC\] \[VOTE\] Warnings for PHP 8.5](https://externals.io/message/128290.md) — started on 2025-07-29, 3 messages

---

## Introduction

The RFC proposes to add a few warnings when encountering certain edge cases in PHP 8.5, and promote those to error in PHP 9.

The following list provides a short overview of the warnings being introduced, while more detailed explanation is provided in the Proposal section:

- Coercing `NAN` to other types
- Casting out of range `floats` to `int`
- Destructuring non-`array` values
- Using offsets on non-container values in `isset()`/`empty()`
- Using invalid offset types when checking string offsets with `isset()`/`empty()`

## Proposal

Each proposed warning is voted separately and requires a 2/3 majority.

### Coercing NAN to other types

- Author: Gina Peter Banyard <girgias@php.net>

The floating point value `NAN` is returned by functions to indicate some sort of error.

However, `NAN` can be coerced to other types without error and hide bugs (except for functions requiring an `int`). More concerning is that the value `NAN` is considered truthy and will be coerced to the value `true`, except when using an explicit `(int)` cast, in which case it is coerced to `0` which is falsy.

As having a `NAN` value is unlikely and points to some sort of bug in the code, we propose to emit the following warning when `NAN` is coerced (be that implicitly or explicitly) to another type:

> Warning: unexpected NAN value was coerced to TYPE

This affects passing `NAN` as an argument to parameters which do not declare `float` as a type, all casting operators, logical operators, if statements, and ternary operator.

**Vote: Warn when coercing NAN to other types?** — Yes: 20 · No: 0 (closed)

### Casting out of range floats to int

- Author: Gina Peter Banyard <girgias@php.net>

Floating point value outside the range of a PHP integer behave in extremely confusing ways.

For example, values that are slightly larger than the maximal integer value can be cast to negative numbers:

```php
var_dump(PHP_INT_MAX);
$a = PHP_INT_MAX + 25;
var_dump($a);
var_dump((int) $a);
```

outputs:

```php
int(9223372036854775807)
float(9.223372036854776E+18)
int(-9223372036854775808)
```

Similarly, values that are slightly lower than the smallest representable integer value can be cast to positive numbers:

```php
var_dump(PHP_INT_MIN);
$b = PHP_INT_MIN - 4874;
var_dump($b);
var_dump((int) $b);
```

outputs:

```php
int(-9223372036854775808)
float(-9.22337203685478E+18)
int(9223372036854771712)
```

And more confusing the values `INF` and `-INF` when cast to int produce the integer `0`:

```php
$p = 255**255;
var_dump($p);
var_dump((int) $p);
 
$m = -255**255;
var_dump($m);
var_dump((int) $m);
```

outputs:

```php
float(INF)
int(0)
float(-INF)
int(0)
```

As this behaviour is extremely confusing and bug prone, we propose to emit the following warning when out of range floats are cast to int:

> Warning: non-representable float was cast to int

**Vote: Warn when casting out of range floats to int?** — Yes: 17 · No: 0 (closed)

### Destructuring non-array values

- Author: Gina Peter Banyard <girgias@php.net>

The `list($v1, $v2) = $array` or `[$v1, $v2] = $array` language construction allows destructing array values into their own variables.

When attempting to destructure an object, the following `Error` is thrown:

> Error: Cannot use object of type stdClass as array

However, when using scalar values (`bool`, `int`, `float`, `string`), `null`, or `resource`no `Error` is thrown, and each variable is assigned `null`.

We propose to emit the following warning when destructuring non-array values:

> Warning: Cannot use TYPE as array

We do not propose to warn when using `null` as destructuring can be done in a conditional, and while doing so can be seen as a dubious practice until better language features, such as the declined [Destructuring Coalesce](https://externals.io/rfc/destructuring_coalesce)are available this should still be permitted.

**Vote: Warn when destructuring non-array values?** — Yes: 16 · No: 0 (closed)

### Using offsets on non-container values in isset()/empty()

- Author: Gina Peter Banyard <girgias@php.net>

This is lifted from the [Improve language coherence for the behaviour of offsets and containers](https://externals.io/rfc/container-offset-behaviour) RFC as it is time-sensitive.

When attempting to check if an offset exists or is empty on objects that do not implement `ArrayOffset`(or the relevant C object handlers) then the following error is thrown:

> Error: Cannot use object of type TYPE as array

However, when using scalar values (`bool`, `int`, `float`, `string`), `null`, or `resource`no `Error` is thrown and `false` is returned for `isset()` and `true` is returned for `empty()`.

As this points to some code expectation being violated, we propose to emit the following warning when using a scalar value or a `resource` as a container:

> Warning: Cannot use TYPE as array

We do not propose to warn when using `null` as a container, as `null` supports auto-vivification to array, and can be used as a sentinel value.

**Vote: Warn when using offsets on non-container values in isset()/empty()?** — Yes: 10 · No: 6 (closed)

### Using invalid offset types when checking string offsets with isset()/empty()

- Author: Gina Peter Banyard <girgias@php.net>

This is lifted from the [Improve language coherence for the behaviour of offsets and containers](https://externals.io/rfc/container-offset-behaviour) RFC as it is time-sensitive.

When attempting to check an array offset with `isset()` or `empty()`, with an object or array as the offset, the following `TypeError` is thrown:

> TypeError: Illegal offset type in isset or empty

This is similar to a `TypeError` being thrown by the `ArrayAccess::offsetExists()` (/the equivalent C object handler) for some internal classes like `SplFixedArray`.

However, when using a string as a container (e.g. `$string[$offset]`) invalid offsets are ignored and `false` is returned for `isset()` and `true` is returned for `empty()`. This behaviour is even stranger, as the null-coalescing operator *does* throw the following `TypeError`, using the following code snippet as an example:

```php
$s = 'abcdefg';
$o = new stdClass();
var_dump(isset($s[$o]));
var_dump($s[$o] ?? 'z');
```

we get the following:

```php
bool(false)
Fatal error: Uncaught TypeError: Cannot access offset of type stdClass on string
```

As this likely points to a bug, and to normalize the behaviour with the null coalesced operator, we propose to emit the following warning when using an invalid offset type for a string offset:

> Warning: Cannot access offset of type TYPE on string

**Vote: Warn when using invalid offset types when checking string offsets with isset()/empty()?** — Yes: 10 · No: 6 (closed)

## Backward Incompatible Changes

For PHP 8.5 additional warnings will be emitted. The promotions of warnings to the appropriate `Error` will happen no earlier than PHP 9.
