Take the State of PHP 2026 Survey →

Stricter type checks for arithmetic/bitwise operators View as Markdown

Implemented (PHP 8.0)
Authors
Nikita Popov nikic@php.net
Date
2020-04-02
Target
PHP 8.0
Implementation
https://github.com/php/php-src/pull/5331
Source
wiki.php.net/rfc/arithmetic_operator_type_checks

Vote

Add stricter type checks for arithmetic/bitwise operators? closed
yes
57
no
0
57 voters
ajf yes 2020-04-16 20:42
alcaeus yes 2020-04-20 11:17
asgrim yes 2020-04-16 14:57
ashnazg yes 2020-04-23 21:43
brzuchal yes 2020-04-16 10:43
bwoebi yes 2020-04-16 10:38
carusogabriel yes 2020-04-23 13:46
cmb yes 2020-04-16 10:42
colinodell yes 2020-04-16 11:15
daverandom yes 2020-04-23 22:33
derick yes 2020-04-16 10:36
dmitry yes 2020-04-20 06:55
duncan3dc yes 2020-04-18 22:02
duodraco yes 2020-04-28 20:58
ekin yes 2020-04-20 13:10
galvao yes 2020-04-19 21:46
gasolwu yes 2020-04-16 13:34
girgias yes 2020-04-16 12:01
jasny yes 2020-04-22 23:57
jbnahan yes 2020-04-21 06:15
jhdxr yes 2020-04-25 16:00
jmcastagnetto yes 2020-04-16 16:32
kelunik yes 2020-04-19 20:19
kguest yes 2020-04-21 08:00
klaussilveira yes 2020-04-21 12:54
kocsismate yes 2020-04-16 10:41
lcobucci yes 2020-04-23 13:31
malukenho yes 2020-04-23 07:50
marandall yes 2020-04-16 13:19
marcio yes 2020-04-17 02:16
mariano yes 2020-04-16 10:45
mbeccati yes 2020-04-16 11:10
mcmic yes 2020-04-16 14:09
mike yes 2020-04-21 11:45
narf yes 2020-04-29 17:51
nicolasgrekas yes 2020-04-16 10:49
nikic yes 2020-04-16 10:32
ocramius yes 2020-04-16 12:47
petk yes 2020-04-23 09:10
pmmaga yes 2020-04-20 11:21
pollita yes 2020-04-20 12:58
rasmus yes 2020-04-19 23:26
reywob yes 2020-04-17 07:30
royopa yes 2020-04-16 11:45
ruudboon yes 2020-04-20 05:42
salathe yes 2020-04-16 10:47
sammyk yes 2020-04-18 18:38
sebastian yes 2020-04-16 10:57
sergey yes 2020-04-20 11:20
sirsnyder yes 2020-04-17 01:08
stas yes 2020-04-16 16:43
svpernova09 yes 2020-04-16 16:02
tandre yes 2020-04-16 16:35
trowski yes 2020-04-21 19:24
wyrihaximus yes 2020-04-19 16:24
yunosh yes 2020-04-17 14:46
zimt yes 2020-04-27 12:53

Discussions on the mailing list

[RFC] Stricter type-checks for arithmetic/bitwise operators
by Nikita Popov · 10 messages
[VOTE] Stricter type-checks for arithmetic/bitwise operators
by Nikita Popov · 2 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:51 UTC

Introduction

This RFC proposes to throw a TypeError when an arithmetic or bitwise operator is applied to an array, resource or (non-overloaded) object. The behavior of scalar operands (like null) remains unchanged

I think we can all agree that this is not reasonable behavior:

var_dump([] % [42]);
// int(0)
// WTF?

Let's fix it.

Proposal

Current Behavior

This section describes the current behavior, limited only to the cases where one operand is an array, resource or object. The object cases always assume that no operator or cast overloading is involved. If operator/cast overloading is used, then those overloads apply.

Operators +, -, *, /, **:

  • Throw Error exception on array operand. (Excluding + if both operands are array.)
  • Silently convert a resource operand to the resource ID as an integer.
  • Convert an object operand to integer one, while throwing a notice.

Operators %, <<, >>, &, |, ^:

  • Silently convert an array operand to integer zero if empty or integer one if non-empty.
  • Silently convert a resource operand to the resource ID as an integer.
  • Convert an object operand to integer one, while throwing a notice.

Operator ~:

  • Throw an Error exception for array, resource and object operands.

Operators ++ and --:

  • Silently do nothing if the operand is an array, resource or object.

Proposed Behavior

The proposed behavior is the same for all the arithmetic/bitwise operators +, -, *, /, **, %, <<, >>, &, |, ^, ~, ++, --:

  • Throw a TypeError exception for array, resource and object operands.

Of course, the case of addition with two array operands remains legal.

Unchanged Behavior

The behavior of operands of type null, bool, int, float and string remains the same.

While it is questionable whether true / 17 really is a sensible operation, the handling of scalar values in general can likely not be changed unconditionally, and as such is left to a proposal like the strict operators directive.

The changes proposed here are intended to be entirely uncontroversial.

Backward Incompatible Changes

Using an array, resource or object in an arithmetic/bitwise operation will now consistently throw, while it previously produced a non-sensical value.

Future Scope

In the future, we may wish to go one step further:

  • Make non-numeric string operands throwing. Non-numeric here means not starting with a digit (optionally preceded by whitespace). This would not apply to operators that have special behavior for strings (string increment and bitwise and/or/xor).
  • Make overflowing float values throwing for operators that expect an integer (%, <<, >>, &, |, ^).

This would have the advantage of aligning the semantics with parameter type checks in coercive mode, for the types int and int|float depending on operator. The only discrepancy would be in the handling of null, which is already not as strictly enforced.

I'm leaving this potential improvement out of this RFC, because it requires more consideration regarding backwards compatibility and overall language integration.

Vote

Voting started 2020-04-16 and ends 2020-04-30.

Vote: Add stricter type checks for arithmetic/bitwise operators? — yes: 57 · no: 0 (closed)