PHP 8.0: New ValueError
Error Exception
\ValueError
is a new Exception type that extends \Exception
class, and from PHP 8.0, you will be seeing lots of them! \ValueError
exception is thrown when a value encountered is of correct type, but it cannot be used to continue the operation.
What about other exceptions?
PHP already has exceptions such as \InvalidArgumentException
, \OutOfRangeException
and \LengthException
exceptions that convey a more precise error message.
However, exceptions is the keyword here: The new \ValueError
exception extends \Error
, instead of \Exception
. While you can throw \ValueError
exceptions in user-land code, PHP core functions will throw \ValueError
exceptions except for a few specific cases (such as sprintf()
function throwing \ArgumentCountError
exceptions instead of the legacy Warning: sprintf(): Too few arguments
warning).
Throwable
├── Error
│ ├── TypeError
│ ├── ValueError
│
└── Exception
├── LogicException
├── DomainException
├── InvalidArgumentException
├── LengthException
└── OutOfRangeException
This is a simplified chart of PHP core \Error
and \Exception
. You can take a look at full PHP Exception hierarchy in this post.
From PHP 8.0 and forward, \ValueError
errors will be thrown when the value passed to a function is of a valid type, but is not valid for the operation.
Examples
-
strpos()
attempting to set a offset longer than the haystack lengthBefore PHP 8.0:
$a = strpos("s", "small", 16); // Warning: strpos(): Offset not contained in string in ... on line ... var_dump($a); // bool(false)
From PHP 8.0
$a = strpos("s", "small", 16); // Uncaught ValueError: Offset not contained in string in ...:...
-
range()
with non-positive stepsBefore PHP 8.0:
$a = range(1, 2, 0); // Warning: range(): step exceeds the specified range in ... on line ... var_dump($a); // bool(false)
From PHP 8.0
$a = range(1, 2, 0); // Uncaught ValueError: Step exceeds the specified range ...:...
-
array_rand()
with an empty arrayBefore PHP 8.0:
$a = array_rand(array(), 0); // Warning: array_rand(): Array is empty in ... on line ... var_dump($a); // NULL
From PHP 8.0
$a = array_rand(array(), 0); // Uncaught ValueError: Array is empty in ...:...
But why?
The new \ValueError
exception is introduced as part of the major change Internal function warnings now throw TypeError
and ValueError
exceptions, where you can find detailed information.
Polyfill
It is possible to polyfill this exception class by simply declaring a user-land class with the same name.
if (!class_exists('\ValueError')) {
class ValueError extends \Error {
}
}
Note that this will not make internal PHP functions throw \ValueError
exceptions when appropriate. However, if you have user-land code that needs to throw \ValueError
exceptions, it is now possible with the polyfill.
Backwards compatibility impact
\ValueError
is a new class, and unless you have user-land implementations, there should be no BC impact.