Introduction
This is the PHP error messages database: a reference collecting every error, warning, notice, and deprecation message that the PHP engine can emit, each with a plain-language explanation of what it means and why PHP raised it. PHP’s own output is often terse — a single line pointing at a line number, with no context on the underlying rule being broken. This book exists to close that gap, one message at a time.
The database is maintained by Exakat, the static analysis engine for PHP, and draws on the same body of knowledge Exakat uses to detect issues in real codebases before they reach production. Where relevant, each entry links back to the PHP language construct involved, notes which PHP version introduced or changed the behavior, and points to further reading in the official manual or RFCs.
You can reach any message in two ways. If you already have the exact error text — copied straight from a stack trace or log file — search for it directly; messages are indexed verbatim, including printf-style placeholders such as %s and %d. If you’re exploring more broadly, browse by syntax error, by tag (deprecation, type error, visibility, and so on), or by feature to see every message associated with a given PHP language construct.
This book tracks PHP’s evolution release by release: deprecation notices that will become fatal errors in future versions are flagged as such, so you can fix them ahead of an upgrade rather than after one breaks production.
Contributions
Contributions are welcomed, by submitting PR to the repository
- New or missing error messages to be added, preferably with their reproduction code
- Extra links to external resources
- Documentation complements
- Checks on the related notions and thesaurus
Syntax Errors
Syntax errors
Here is a list of classic syntax errors, met in every day code. Some common solutions are listed with them, so as to help anyone meeting them.
- Invalid numeric literal
- syntax error, unexpected \)\, expecting \=\
- syntax error, unexpected ), expecting | or variable (T_VARIABLE)
- syntax error, unexpected ), expecting variable (T_VARIABLE)
- syntax error, unexpected ,
- syntax error, unexpected -, expecting =
- syntax error, unexpected ::, expecting (
- syntax error, unexpected :: (T_PAAMAYIM_NEKUDOTAYIM), expecting ; or ,
- syntax error, unexpected ;, expecting [
- syntax error, unexpected ;, expecting {
- syntax error, unexpected [, expecting ; or ,
- syntax error, unexpected elseif
- syntax error, unexpected match
- syntax error, unexpected throw (T_THROW)
- syntax error, unexpected {
- syntax error, unexpected |, expecting variable (T_VARIABLE)
- syntax error, unexpected end of file
- syntax error, unexpected fully qualified name %s, expecting function or const
- syntax error, unexpected fully qualified name %s, expecting function
- syntax error, unexpected fully qualified name %s, expecting {
- syntax error, unexpected fully qualified name %s
- syntax error, unexpected identifier %s, expecting (
- syntax error, unexpected identifier %s, expecting )
- syntax error, unexpected identifier %s, expecting , or ;
- syntax error, unexpected identifier %s, expecting ; or {
- syntax error, unexpected identifier %s, expecting ]
- syntax error, unexpected identifier %s, expecting function or const
- syntax error, unexpected identifier %s, expecting function
- syntax error, unexpected identifier %s, expecting {
- syntax error, unexpected identifier %s, expecting variable or $
- syntax error, unexpected identifier %s, expecting variable
- syntax error, unexpected identifier %s
- syntax error, unexpected identifier readonly, expecting function or const
- syntax error, unexpected integer %s, expecting )
- syntax error, unexpected namespaced name %s, expecting function
- syntax error, unexpected single quoted string %s, expecting )
- syntax error, unexpected string content
- syntax error, unexpected token #[, expecting )
- syntax error, unexpected token #[, expecting , or ;
- syntax error, unexpected token #[, expecting ]
- syntax error, unexpected token %
- syntax error, unexpected token %s, expecting identifier
- syntax error, unexpected token &, expecting end of file
- syntax error, unexpected token &
- syntax error, unexpected token (, expecting ::
- syntax error, unexpected token (, expecting identifier or variable or { or $
- syntax error, unexpected token (, expecting variable
- syntax error, unexpected token (
- syntax error, unexpected token (int)
- syntax error, unexpected token ), expecting =
- syntax error, unexpected token ), expecting function or fn or static or #[
- syntax error, unexpected token ), expecting variable
- syntax error, unexpected token )
- syntax error, unexpected token *
- syntax error, unexpected token ,, expecting )
- syntax error, unexpected token ,, expecting ]
- syntax error, unexpected token ,, expecting variable or $
- syntax error, unexpected token ,, expecting variable
- syntax error, unexpected token ,
- syntax error, unexpected token \\, expecting {
- syntax error, unexpected token ->, expecting , or ;
- syntax error, unexpected token ->
- syntax error, unexpected token :, expecting )
- syntax error, unexpected token :, expecting ]
- syntax error, unexpected token :
- syntax error, unexpected token ::, expecting , or ;
- syntax error, unexpected token ::, expecting :
- syntax error, unexpected token ::, expecting ]
- syntax error, unexpected token ::
- syntax error, unexpected token ;, expecting (
- syntax error, unexpected token ;, expecting )
- syntax error, unexpected token ;, expecting , or )
- syntax error, unexpected token ;, expecting -> or ?-> or [
- syntax error, unexpected token ;, expecting -> or ?-> or { or [
- syntax error, unexpected token ;, expecting ]
- syntax error, unexpected token ;, expecting function or fn or static or #[
- syntax error, unexpected token ;, expecting {
- syntax error, unexpected token ;, expecting identifier
- syntax error, unexpected token ;
- syntax error, unexpected token <<
- syntax error, unexpected token =, expecting identifier or variable or { or $
- syntax error, unexpected token =, expecting identifier
- syntax error, unexpected token =, expecting variable
- syntax error, unexpected token =
- syntax error, unexpected token >
- syntax error, unexpected token ?, expecting identifier
- syntax error, unexpected token ?
- syntax error, unexpected token ?->, expecting , or ;
- syntax error, unexpected token ?->
- syntax error, unexpected token ??
- syntax error, unexpected token ]
- syntax error, unexpected token __NAMESPACE__, expecting (
- syntax error, unexpected token as
- syntax error, unexpected token break
- syntax error, unexpected token class, expecting-]
- syntax error, unexpected token const
- syntax error, unexpected token continue
- syntax error, unexpected token exit
- syntax error, unexpected token extends, expecting {
- syntax error, unexpected token extends, expecting identifier
- syntax error, unexpected token extends
- syntax error, unexpected token final, expecting (
- syntax error, unexpected token if, expecting )
- syntax error, unexpected token if, expecting ]
- syntax error, unexpected token if
- syntax error, unexpected token implements
- syntax error, unexpected token match, expecting (
- syntax error, unexpected token match
- syntax error, unexpected token namespace, expecting {
- syntax error, unexpected token namespace
- syntax error, unexpected token new, expecting )
- syntax error, unexpected token private, expecting (
- syntax error, unexpected token private, expecting )
- syntax error, unexpected token private, expecting =
- syntax error, unexpected token private, expecting {
- syntax error, unexpected token protected, expecting {
- syntax error, unexpected token public, expecting ]
- syntax error, unexpected token public, expecting {
- syntax error, unexpected token public
- syntax error, unexpected token use, expecting , or ;
- syntax error, unexpected token use, expecting {
- syntax error, unexpected token use
- syntax error, unexpected token {, expecting )
- syntax error, unexpected token {, expecting , or ;
- syntax error, unexpected token {, expecting ;
- syntax error, unexpected token {, expecting variable
- syntax error, unexpected token {
- syntax error, unexpected token }, expecting ; or {
- syntax error, unexpected token }
- syntax error, unexpected variable $%s, expecting )
- syntax error, unexpected variable $task, expecting )
- syntax error, unexpected variable $this, expecting ; or {
- syntax error, unexpected variable %s, expecting (
- Unclosed (
- Unclosed [
- Unclosed {
- Unmatched )
- Unmatched ]
- Unmatched }
Tags
Tag index
- algorithm
- argument
- %s(): argument #%d%s%s%s cannot be passed by reference
- calling dba_fetch() with $dba at the 3rd parameter is deprecated
- calling intlcalendar::set() with more than 2 arguments is deprecated,
- calling intlgregoriancalendar::__construct() with more than 2 arguments is deprecated,
- calling ldap_connect() with oracle specific arguments is deprecated
- calling ldap_exop() with more than 4 arguments is deprecated, use ldap_exop_sync() instead
- too few arguments to function %s%s%s(), %d passed and %s %d expected
- too few arguments to function %s%s%s(), %d passed and %s %d
- usage of ldap_connect with two arguments is deprecated
- argument-value
- array
- arrays
- attribute
- autoload
- bug
- bzip2
- callable
- callback
- catch
- changed behavior
- accessing static trait property %s::$%s is deprecated
- calling static trait method %s::%s is deprecated
- cannot use 'mixed' as class name as it is reserved
- cannot use 'never' as class name as it is reserved
- cannot use ::class with dynamic class name
- cannot use the abstract modifier on a property
- power of base 0 and negative exponent is deprecated
- syntax error, unexpected token “(”
- undefined variable
- unparenthesized `a ? b : c ? d : e` is not supported.
- unparenthesized `a ? b : c ?: d` is not supported.
- unparenthesized `a ?: b ? c : d` is not supported.
- chr
- class
- class constant
- classic
- closure
- cannot bind method %s::%s() to object of class %s, this will be an error in php 9
- cannot combine nullsafe operator with closure creation
- cannot create closure as attribute argument
- cannot rebind scope of closure created from function, this will be an error in php 9
- cannot rebind scope of closure created from method, this will be an error in php 9
- cannot unbind $this of closure using $this, this will be an error in php 9
- cannot unbind $this of method, this will be an error in php 9
- cannot use variable $%ps twice
- closures
- coercion
- collision
- compile error
- configuration
- confusion
- const
- constant
- “static::” is not allowed in compile time constants
- define(): argument #3 ($case_insensitive) is ignored and treated as false since declaration of case insensitive constants is no longer supported, passing the argument explicitly is unnecessary
- define(): argument #3 ($case_insensitive) is ignored since declaration of case insensitive constants is no longer supported, this will be an error in php 9.0
- undefined constant “%s
- constructor
- calling dateperiod::__construct(string $isostr, int $options = 0) is deprecated,
- calling intlgregoriancalendar::__construct() with more than 2 arguments is deprecated,
- cannot override final %s::__construct() with %s::__construct()
- intllistformatter object is already constructed
- making a constructor a generator is deprecated
- returning a value from a constructor is deprecated
- crash
- csv
- ctype
- date
- datetime
- debug
- debugging
- declare
- decrement
- default value
- define
- define(): argument #3 ($case_insensitive) is ignored and treated as false since declaration of case insensitive constants is no longer supported, passing the argument explicitly is unnecessary
- define(): argument #3 ($case_insensitive) is ignored since declaration of case insensitive constants is no longer supported, this will be an error in php 9.0
- deprecated
- auto_detect_line_endings is deprecated
- calling %s() with 2 arguments is deprecated,
- calling dba_fetch() with $dba at the 3rd parameter is deprecated
- calling ffi::cast() statically is deprecated
- calling ffi::new() statically is deprecated
- calling ffi::type() statically is deprecated
- calling intlcalendar::set() with more than 2 arguments is deprecated,
- calling intlgregoriancalendar::__construct() with more than 2 arguments is deprecated,
- calling ldap_connect() with oracle specific arguments is deprecated
- calling ldap_exop() with more than 4 arguments is deprecated, use ldap_exop_sync() instead
- calling pg_fetch_result() with 2 arguments is deprecated,
- calling reflectionmethod::__construct() with 1 argument is deprecated,
- calling stream_context_set_option() with 2 arguments is deprecated,
- function libxml_disable_entity_loader() is deprecated since 8.0, as external entity loading is disabled by default
- looking up the dsn from a uri is deprecated due to possible security concerns with dsns coming from remote uris
- passing the $mode parameter is deprecated since 8.4, as it has been ignored since 8.1
- the (real) cast is deprecated, use (float) instead
- usage of ldap_connect with two arguments is deprecated
- deprecation
- %s(): implicitly marking parameter $%s as nullable is deprecated, the explicit nullable type
- %s(): optional parameter $%s declared before required parameter $%s
- %s implements the serializable interface
- argument of type %s will be interpreted as string in the future
- [callables of the form “%s
- calling %ps() for static method %ps::%ps() does not need an object parameter
- calling %ps() with a 1st argument which is not null or an object is deprecated
- calling %ps() with a given object that is not an instance of the class this property was declared in is deprecated
- calling %ps() with a single argument is deprecated
- calling %s(resource $stub
- calling a function “readonly” is deprecated
- cannot bind method %s::%s() to object of class %s, this will be an error in php 9
- cannot rebind scope of closure created from function, this will be an error in php 9
- cannot rebind scope of closure created from method, this will be an error in php 9
- cannot unbind $this of closure using $this, this will be an error in php 9
- cannot unbind $this of method, this will be an error in php 9
- constant %s is deprecated
- constant %s::%s is deprecated
- creation of dynamic property %s::$“ zend_long_fmt “ is deprecated
- declaring %s constant called namespace is deprecated
- decrement on empty string is deprecated as non numeric
- decrement on non numeric string has no effect and is deprecated
- function %s() is deprecated%s
- implicit conversion from float string “%s “ to int loses precision
- instantiation of mysqli_stmt without providing the $query parameter is deprecated
- making a constructor a generator is deprecated
- making a destructor a generator is deprecated
- object values within argument #1 $data to http_build_query() being interpreted as arrays is deprecated,
- passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs
- passing a seed of a type other than int is deprecated because it is ignored
- passing a seed of a type other than int is deprecated because it is the same as setting the seed to 0
- passing an object for argument #%“ priu32 “ $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead
- passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead
- passing an object for argument #1 $array to array_walk_recursive() is deprecated, call get_object_vars() first instead
- passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead
- passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead
- passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead
- passing an object for filter parameters for %s is deprecated, call get_object_vars() first instead
- passing an object for filter parameters for bzip2.compress is deprecated, call get_object_vars() first instead
- passing an object for filter parameters for bzip2.decompress is deprecated, call get_object_vars() first instead
- passing bool is deprecated, use 1 or 1 instead
- providing a value not in between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. the value used will be constrained using %% 256
- providing an object to argument #1 ($sessionhandler) which does not have the create_sid() method defined is deprecated
- providing an object to argument #1 ($sessionhandler) which does not have the validateid() method defined is deprecated
- reflectionclass::getconstant() for a non existent constant is deprecated,
- reflectionproperty::getdefaultvalue() for a property without a default value is deprecated,
- returning a value from a constructor is deprecated
- returning a value from a destructor is deprecated
- returning from a finally block is deprecated
- returning null from %s::__debuginfo() is deprecated, make the return type non nullable and return an empty array instead
- returning null from %s::__debuginfo() is deprecated, return an empty array instead
- the $escape parameter must be provided, as its default value will change, either explicitly or via splfileobject::setcsvcontrol()
- the “ssl_method “ option is deprecated. use “ssl “ stream context options instead
- the driver_version property is deprecated
- the filter.default ini setting is deprecated
- the mt_rand_php variant of mt19937 is deprecated
- the pdo::fetch_serialize mode is deprecated
- trait %s used by %s is deprecated%s
- usage of session.trans_sid_hosts ini setting is deprecated
- usage of session.trans_sid_tags ini setting is deprecated
- use of “parent “ in callables is deprecated
- use of “self “ in callables is deprecated
- use of “static “ in callables is deprecated
- use of iconv.input_encoding is deprecated
- use of iconv.internal_encoding is deprecated
- use of iconv.output_encoding is deprecated
- using array_key_exists() on objects is deprecated.
- using more than “ zend_long_fmt “ filters in a php: filter url is deprecated
- using more than %d filters in a php: filter url is deprecated
- using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated,
- destructor
- digest
- directive
- dnf
- dynamic-call
- dynamic-property
- edge case
- ellipsis
- encoding
- enum
- exception
- exceptions
- execution
- access level to %s::%s must be %s (as in %s %s)%s
- cannot call constructor
- cannot override final property hook %s::%s()
- duplicate value in enum %s for cases %s and %s
- illegal offset type in isset or empty
- illegal offset type in unset
- illegal offset type
- never returning function must not implicitly return
- trait method %s::%s has not been applied as %s::%s
- execution only
- extension
- ffi api is restricted by “ffi.enable” configuration directive
- function libxml_disable_entity_loader() is deprecated since 8.0, as external entity loading is disabled by default
- module “%s” is already loaded
- must not contain empty strings
- security level must be one of “noauthnopriv”, “authnopriv”, or “authpriv
- extension-loading
- fetch
- file
- filesystem
- filter
- final
- finally
- forbidden
- foreach
- fully-qualified-name
- function
- funny
- garbage-collection
- gd
- gem
- generator
- gmp
- goto
- hash
- passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs
- passing a seed of a type other than int is deprecated because it is ignored
- passing a seed of a type other than int is deprecated because it is the same as setting the seed to 0
- unknown digest algorithm: %s
- iconv
- implicit
- ini
- ini-setting
- interface
- internal
- intersection
- intl
- datetimezone object is unconstructed
- intllistformatter object is already constructed
- must be a valid normalization form
- must be either spoofchecker::ltr or spoofchecker::rtl
- must be no longer than %d characters
- must be one of intlnumberrangeformatter::identity_fallback_single_value, ::identity_fallback_approximately_or_single_value, ::identity_fallback_approximately, or ::identity_fallback_range
- passing bool is deprecated, use 1 or 1 instead
- iterator
- keyword
- late-static-binding
- lazy-objects
- limits
- lint
- lint-wont-execute
- list
- locale
- lower-case-name
- magic-method
- making a constructor a generator is deprecated
- making a destructor a generator is deprecated
- returning a value from a constructor is deprecated
- returning a value from a destructor is deprecated
- returning null from %s::__debuginfo() is deprecated, make the return type non nullable and return an empty array instead
- returning null from %s::__debuginfo() is deprecated, return an empty array instead
- math
- mbstring
- modernisation
- mysqli
- instantiation of mysqli_stmt without providing the $query parameter is deprecated
- must be mysqli_init_command, mysqli_set_charset_name, mysqli_server_public_key, or one of the mysqli_opt_* constants
- passing the $mode parameter is deprecated since 8.4, as it has been ignored since 8.1
- the driver_version property is deprecated
- name
- named-parameter
- namespace
- nan
- networking
- has a malformed ipv6 address, closing square bracket missing
- must be a combination of msg_oob, msg_peek, msg_waitall, msg_dontwait, msg_errqueue, and msg_cmsg_cloexec for af_packet sockets
- must be a valid context engine id
- must be of type array when argument #3 ($option) is mcast_leave_group, %s given
- must be of type array when argument #3 ($option) is mcast_leave_source_group, %s given
- must be of type string when argument #3 ($option) is fil_attach or fil_detach, %s given
- must be of type string when argument #3 ($option) is so_acceptfilter, %s given
- must be of type string when argument #3 ($option) is so_bindtodevice, %s given
- must be of type string when argument #3 ($option) is tcp_congestion, %s given
- must be of type string when argument #3 ($option) is tcp_function_blk, %s given
- must contain a type for object id %s
- must contain a value for object id %s
- must not be empty when passed as an array
- no generation
- no-closing-tag
- syntax error, unexpected end of file
- syntax error, unexpected string content
- [syntax error, unexpected token “;”, expecting “function” or “fn” or “static” or “#“
- no-code
- no-opening-tag
- non-instantiable
- not generated
- classes must be first marked as attribute before being able to be registered as internal attribute class
- enum “%s” not found
- failed to open stream from socketpair
- failed to update the scheme
- failed to update the userinfo
- generated salt too short
- is an unsupported rounding mode
- only internal classes can be registered as compiler attribute
- static function %s%s%s() cannot be abstract
- unknown parser
- not-recommended
- null
- nullable
- number-formatting
- object
- offset
- old behavior
- opcache
- openssl
- operators
- optional-parameter
- overloaded signature
- overloaded-signature
- p
- parameter
- parameter value error
- partial-application
- partial-function-application
- partial-lint
- password
- pdo
- %s(): return value of the authorizer callback must be of type int, %s returned
- %s(): return value of the collation callback must be of type int, %s returned
- cannot change default fetch mode while fetching
- the pdo extension must be loaded first in order to load pdo drivers
- the pdo::fetch_serialize mode is deprecated
- pgsql
- phar
- php://filter
- polling
- posix
- precision
- printf
- property
- property hook
- %s hook of property %s::$%s must accept exactly one parameters
- get hook of backed property %s::%s with set hook may not return by reference
- get hook of property %s::$%s must not have a parameter list
- parameter $%s of %s hook %s::$%s must not be pass by reference
- parameter $%s of %s hook %s::$%s must not be variadic
- parameter $%s of %s hook %s::$%s must not have a default value
- unknown hook “%s “ for property %s::$%s
- property-hook
- random
- readonly
- redeclare
- reference
- reflection
- calling %ps() for static method %ps::%ps() does not need an object parameter
- calling %ps() with a 1st argument which is not null or an object is deprecated
- calling %ps() with a given object that is not an instance of the class this property was declared in is deprecated
- calling %ps() with a single argument is deprecated
- calling reflectionmethod::__construct() with 1 argument is deprecated,
- cannot use %s() on dynamic property %ps::$%ps
- cannot use %s() on internal class %ps
- cannot use %s() on static property %ps::$%ps
- cannot use %s() on virtual property %ps::$%ps
- function %ps() does not exist
- method %ps::%ps() does not exist
- reflectionclass::getconstant() for a non existent constant is deprecated,
- reflectionproperty::getdefaultvalue() for a property without a default value is deprecated,
- value for class is not a string
- relative-types
- removed
- removed feature
- removed message
- reserved
- reserved-word
- return
- return-type
- rsa
- salt
- scope
- cannot bind method %s::%s() to object of class %s, this will be an error in php 9
- cannot rebind scope of closure created from function, this will be an error in php 9
- cannot rebind scope of closure created from method, this will be an error in php 9
- cannot unbind $this of closure using $this, this will be an error in php 9
- cannot unbind $this of method, this will be an error in php 9
- security
- cannot disable function %s()
- looking up the dsn from a uri is deprecated due to possible security concerns with dsns coming from remote uris
- maximum depth of %d exceeded. the depth limit can be changed using the max_depth unserialize() option
- using more than %d filters in a php: filter url is deprecated
- serialization
- serialize
- session
- class %s implementing sessionhandlerinterface is missing the create_sid() method which will be required in php 9.0
- class %s implementing sessionhandlerinterface is missing the validateid() method which will be required in php 9.0
- usage of session.trans_sid_hosts ini setting is deprecated
- usage of session.trans_sid_tags ini setting is deprecated
- shutdown
- signature
- silent-cast
- snmp
- soap
- sockets
- must be a combination of msg_oob, msg_peek, msg_waitall, msg_dontwait, msg_errqueue, and msg_cmsg_cloexec for af_packet sockets
- must be of type array when argument #3 ($option) is mcast_leave_group, %s given
- must be of type array when argument #3 ($option) is mcast_leave_source_group, %s given
- must be of type string when argument #3 ($option) is fil_attach or fil_detach, %s given
- must be of type string when argument #3 ($option) is so_acceptfilter, %s given
- must be of type string when argument #3 ($option) is so_bindtodevice, %s given
- must be of type string when argument #3 ($option) is tcp_congestion, %s given
- must be of type string when argument #3 ($option) is tcp_function_blk, %s given
- sodium
- special case
- spl
- spoofchecker
- sqlite
- ssl
- static
- static-property
- stream
- stream-filter
- streams
- calling stream_context_set_option() with 2 arguments is deprecated,
- io poll handle cannot be implemented by user classes
- must be a concrete class
- stream context option error_mode must be of type streamerrormode
- stream context option error_store must be of type streamerrorstore
- stream error handler must be a valid callback, %s
- stream filter %s is never seekable
- stream filter %s is seekable only to start position
- stream filter seeking for %s failed
- using more than “ zend_long_fmt “ filters in a php: filter url is deprecated
- strict check
- strict_types
- string
- decrement on empty string is deprecated as non numeric
- decrement on non numeric string has no effect and is deprecated
- illegal string offset
- providing a string that is not one byte long is deprecated. use ord($str[0]) instead
- providing a value not in between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. the value used will be constrained using %% 256
- strings
- surprise
- %s “ is not a supported builtin type and will be interpreted as a class name. write “ %s “%s to suppress this warning
- %s “ will be interpreted as a class name. did you mean “%s “? write “ %s “%s to suppress this warning
- %s and %s define the same constant (%s) in the composition of %s. however, the definition differs and is considered incompatible. class was composed
- %s and %s define the same property ($%s) in the composition of %s. however, the definition differs and is considered incompatible. class was composed
- surprising
- syntax-error
- invalid numeric literal
- syntax error, unexpected ')', expecting '='
- syntax error, unexpected ')', expecting '|' or variable (t_variable)
- syntax error, unexpected ')', expecting variable (t_variable)
- syntax error, unexpected ','
- syntax error, unexpected ' ', expecting '='
- syntax error, unexpected '::', expecting '('
- syntax error, unexpected '::' (t_paamayim_nekudotayim), expecting ';' or ','
- [syntax error, unexpected ';', expecting ''
- syntax error, unexpected ';', expecting '{'
- [syntax error, unexpected '', expecting ';' or ','
- syntax error, unexpected 'elseif'
- syntax error, unexpected 'match'
- syntax error, unexpected 'throw' (t_throw)
- syntax error, unexpected '{'
- syntax error, unexpected '|', expecting variable (t_variable)
- syntax error, unexpected end of file
- syntax error, unexpected fully qualified name “%s”, expecting “function” or “const”
- syntax error, unexpected fully qualified name “%s”, expecting “function”
- syntax error, unexpected fully qualified name “%s”, expecting “{”
- syntax error, unexpected fully qualified name “%s”
- syntax error, unexpected identifier “%s”, expecting “(”
- syntax error, unexpected identifier “%s”, expecting “)”
- syntax error, unexpected identifier “%s”, expecting “,” or “;”
- syntax error, unexpected identifier “%s”, expecting “;” or “{”
- [syntax error, unexpected identifier “%s”, expecting “]”](messages/syntax-error,-unexpected-identifier-ps,-expecting-].html)
- syntax error, unexpected identifier “%s”, expecting “function” or “const”
- syntax error, unexpected identifier “%s”, expecting “function”
- syntax error, unexpected identifier “%s”, expecting “{”
- syntax error, unexpected identifier “%s”, expecting variable or “$”
- syntax error, unexpected identifier “%s”, expecting variable
- syntax error, unexpected identifier “%s”
- syntax error, unexpected identifier “readonly”, expecting “function” or “const”
- syntax error, unexpected integer “%s”, expecting “)”
- syntax error, unexpected namespaced name “%s”, expecting “function”
- syntax error, unexpected single quoted string “%s”, expecting “)”
- syntax error, unexpected string content
- [syntax error, unexpected token “#“, expecting “)”
- [syntax error, unexpected token “#“, expecting “,” or “;”
- syntax error, unexpected token “#[”, expecting “]”
- syntax error, unexpected token “%”
- syntax error, unexpected token “%s”, expecting identifier
- syntax error, unexpected token “&”, expecting end of file
- syntax error, unexpected token “&”
- syntax error, unexpected token “(”, expecting “::”
- syntax error, unexpected token “(”, expecting identifier or variable or “{” or “$”
- syntax error, unexpected token “(”, expecting variable
- syntax error, unexpected token “(”
- syntax error, unexpected token “(int)”
- syntax error, unexpected token “)”, expecting “=”
- [syntax error, unexpected token “)”, expecting “function” or “fn” or “static” or “#“
- syntax error, unexpected token “)”, expecting variable
- syntax error, unexpected token “)”
- syntax error, unexpected token “*”
- syntax error, unexpected token “,”, expecting “)”
- [syntax error, unexpected token “,”, expecting “]”](messages/syntax-error,-unexpected-token-,,-expecting-].html)
- syntax error, unexpected token “,”, expecting variable or “$”
- syntax error, unexpected token “,”, expecting variable
- syntax error, unexpected token “,”
- syntax error, unexpected token “ “, expecting “{”
- syntax error, unexpected token “ >“, expecting “,” or “;”
- syntax error, unexpected token “ >“
- syntax error, unexpected token “:”, expecting “)”
- [syntax error, unexpected token “:”, expecting “]”](messages/syntax-error,-unexpected-token-:,-expecting-].html)
- syntax error, unexpected token “:”
- syntax error, unexpected token “::”, expecting “,” or “;”
- syntax error, unexpected token “::”, expecting “:”
- [syntax error, unexpected token “::”, expecting “]”](messages/syntax-error,-unexpected-token-::,-expecting-].html)
- syntax error, unexpected token “::”
- syntax error, unexpected token “;”, expecting “(”
- syntax error, unexpected token “;”, expecting “)”
- syntax error, unexpected token “;”, expecting “,” or “)”
- [syntax error, unexpected token “;”, expecting “ >“ or “? >” or ““
- [syntax error, unexpected token “;”, expecting “ >“ or “? >” or “{” or ““
- [syntax error, unexpected token “;”, expecting “]”](messages/syntax-error,-unexpected-token-;,-expecting-].html)
- [syntax error, unexpected token “;”, expecting “function” or “fn” or “static” or “#“
- syntax error, unexpected token “;”, expecting “{”
- syntax error, unexpected token “;”, expecting identifier
- syntax error, unexpected token “;”
- syntax error, unexpected token “<<”
- syntax error, unexpected token “=”, expecting identifier or variable or “{” or “$”
- syntax error, unexpected token “=”, expecting identifier
- syntax error, unexpected token “=”, expecting variable
- syntax error, unexpected token “=”
- syntax error, unexpected token “>”
- syntax error, unexpected token “?”, expecting identifier
- syntax error, unexpected token “?”
- syntax error, unexpected token “? >”, expecting “,” or “;”
- syntax error, unexpected token “? >”
- syntax error, unexpected token “??”
- [syntax error, unexpected token “]”](messages/syntax-error,-unexpected-token-].html)
- syntax error, unexpected token “namespace”, expecting “(”
- syntax error, unexpected token “as”
- syntax error, unexpected token “break”
- [syntax error, unexpected token “class”, expecting “]”](messages/syntax-error,-unexpected-token-class,-expecting-].html)
- syntax error, unexpected token “const”
- syntax error, unexpected token “continue”
- syntax error, unexpected token “exit”
- syntax error, unexpected token “extends”, expecting “{”
- syntax error, unexpected token “extends”, expecting identifier
- syntax error, unexpected token “extends”
- syntax error, unexpected token “final”, expecting “(”
- syntax error, unexpected token “if”, expecting “)”
- [syntax error, unexpected token “if”, expecting “]”](messages/syntax-error,-unexpected-token-if,-expecting-].html)
- syntax error, unexpected token “if”
- syntax error, unexpected token “implements”
- syntax error, unexpected token “match”, expecting “(”
- syntax error, unexpected token “match”
- syntax error, unexpected token “namespace”, expecting “{”
- syntax error, unexpected token “namespace”
- syntax error, unexpected token “new”, expecting “)”
- syntax error, unexpected token “private”, expecting “(”
- syntax error, unexpected token “private”, expecting “)”
- syntax error, unexpected token “private”, expecting “=”
- syntax error, unexpected token “private”, expecting “{”
- syntax error, unexpected token “protected”, expecting “{”
- [syntax error, unexpected token “public”, expecting “]”](messages/syntax-error,-unexpected-token-public,-expecting-].html)
- syntax error, unexpected token “public”, expecting “{”
- syntax error, unexpected token “public”
- syntax error, unexpected token “use”, expecting “,” or “;”
- syntax error, unexpected token “use”, expecting “{”
- syntax error, unexpected token “use”
- syntax error, unexpected token “{”, expecting “)”
- syntax error, unexpected token “{”, expecting “,” or “;”
- syntax error, unexpected token “{”, expecting “;”
- syntax error, unexpected token “{”, expecting variable
- syntax error, unexpected token “{”
- syntax error, unexpected token “}”, expecting “;” or “{”
- syntax error, unexpected token “}”
- syntax error, unexpected variable “$%s”, expecting “)”
- syntax error, unexpected variable “$task”, expecting “)”
- syntax error, unexpected variable “$this”, expecting “;” or “{”
- syntax error, unexpected variable “%s”, expecting “(”
- unclosed '('
- [unclosed ''
- unclosed '{'
- unmatched ')'
- [unmatched ']'](messages/unmatched-\]\.html)
- unmatched '}'
- tls
- trait
- %s and %s define the same hooked property ($%s) in the composition of %s. conflict resolution between hooked properties is currently not supported. class was composed
- cannot use “abstract “ as method modifier in trait alias
- cannot use “static “ as method modifier in trait alias
- required trait %s wasn't added to %s
- try
- type
- call to a member function %s() on %s
- cannot use %s as value for class constant %s::%s of type %s
- class constant %s::%s cannot have type %s
- default value for property of type %s may not be null. use the nullable type %s to allow null default value
- implicit conversion from float string “%s “ to int loses precision
- must be of type countable|array, %s given
- never can only be used as a standalone type
- null cannot be marked as nullable
- parameter must be an array or an object that implements countable
- property %s::$%s cannot have type %s
- set type of %s::$%s must be supertype of %s (as in %s %s)
- type %s cannot be part of an intersection type
- type %s contains both object and a class type
- type %s is redundant as it is more restrictive than type %s
- type %s is redundant with type %s
- type mixed can only be used as a standalone type
- type of %s::%s must be compatible with %s::%s of type %s
- type of parameter $%s of hook %s::$%s::set must be compatible with property type
- void can only be used as a standalone type
- weakmap key must be an object
- type-juggling
- typed-properties
- types
- typo
- undefined
- unicode
- unserialize
- uri
- cannot set a userinfo without having a host
- must be a list of %s
- the specified %s is malformed%s%s%s
- the specified %s is malformed
- the specified scheme is malformed
- the specified uri is malformed
- the specified url cannot have password
- the specified url cannot have port
- the specified url cannot have username
- the specified userinfo is malformed
- use
- validation
- argument #1 ($start) must be a single byte string if
- cannot be 0
- cannot deserialize arrayobject with iterator class %s; this class is not derived from arrayiterator
- cannot use %s() on dynamic property %ps::$%ps
- cannot use %s() on internal class %ps
- cannot use %s() on static property %ps::$%ps
- cannot use %s() on virtual property %ps::$%ps
- elements must be between %d and %d
- has a malformed ipv6 address, closing square bracket missing
- internal function %s%s%s() does not accept named variadic arguments
- must be a bitmask of posix_f_ok, posix_r_ok, posix_w_ok, and posix_x_ok
- must be a combination of msg_oob, msg_peek, msg_waitall, msg_dontwait, msg_errqueue, and msg_cmsg_cloexec for af_packet sockets
- must be a concrete class
- must be a valid context engine id
- must be a valid normalization form
- must be between 1 and %lu
- must be either case_lower or case_upper
- must be either spoofchecker::ltr or spoofchecker::rtl
- must be less than 4294967295 bytes
- must be less than argument #2 ($max)
- must be mysqli_init_command, mysqli_set_charset_name, mysqli_server_public_key, or one of the mysqli_opt_* constants
- must be no longer than %d characters
- must be odd if argument #1 ($num) is negative
- must be of type array when argument #3 ($option) is mcast_leave_group, %s given
- must be of type array when argument #3 ($option) is mcast_leave_source_group, %s given
- must be of type string when argument #3 ($option) is fil_attach or fil_detach, %s given
- must be of type string when argument #3 ($option) is so_acceptfilter, %s given
- must be of type string when argument #3 ($option) is so_bindtodevice, %s given
- must be of type string when argument #3 ($option) is tcp_congestion, %s given
- must be of type string when argument #3 ($option) is tcp_function_blk, %s given
- must be one of array_filter_use_value, array_filter_use_key, or array_filter_use_both
- must be one of intlnumberrangeformatter::identity_fallback_single_value, ::identity_fallback_approximately_or_single_value, ::identity_fallback_approximately, or ::identity_fallback_range
- must be one of the pathinfo_* constants
- must be one of the scandir_sort_ascending, scandir_sort_descending, or scandir_sort_none constants
- must be only one of the pathinfo_* constants
- must be openssl_encoding_der or openssl_encoding_pem
- must be smaller than or equal to argument #3 ($max)
- must contain a type for object id %s
- must contain a value for object id %s
- must have a length less than or equal to %u
- must not be empty, use str_split() to split a string into characters
- must not be empty when passed as an array
- must not be empty
- must not be nan
- must not exceed %d bytes
- partial application of %s() expects %s %d arguments, %d given
- partial application of %s() expects at most %d arguments, %d given
- setlocale() expects exactly 2 arguments when argument #2 ($locales) is an array, %d given
- stream context option error_mode must be of type streamerrormode
- stream context option error_store must be of type streamerrorstore
- stream error handler must be a valid callback, %s
- stream filter %s is never seekable
- stream filter %s is seekable only to start position
- stream filter seeking for %s failed
- the maximum representable range is 2_147_483_647 seconds (roughly 68 years)
- the maximum representable range is 9_223_372_035 seconds (roughly 292 years)
- value must be between 0 and %d
- variadic
- visibility
- weakmap
- weakreference
- zend
Features
Features index
- $argv
- $globals
- $http_response_header
- $this
- PHP_INT_MAX
- PHP_INT_MIN
- ReturnTypeWillChange
- __callStatic
- __debuginfo
- __halt_compiler
- __invoke
- __set_state
- __sleep
- %s“ returned as member variable from __sleep() but does not exist
- %s “ is returned from __sleep() multiple times
- %s::__sleep() should return an array only containing the names of instance variables to serialize
- __sleep should return an array only containing the names of instance variables to serialize.
- the __sleep() serialization magic method has been deprecated.
- the __wakeup() serialization magic method has been deprecated.
- __toString
- __tostring
- __wakeup
- absolute-name
- abstract
- %s %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining method%s (
- %s %s must implement %d abstract method%s (
- %s function %s::%s() cannot be declared private
- %s function %s::%s() cannot contain body
- %s method %s::%s() must not be abstract
- abstract property %s::$%s must specify at least one abstract hook
- abstract property hook cannot have body
- anonymous class method %s() must not be abstract
- can't inherit abstract function %s::%s() (previously declared abstract in %s)
- cannot declare promoted property in an abstract constructor
- cannot make non abstract method %s::%s() abstract in class %s
- cannot use “abstract” as method modifier in trait alias
- cannot use 'abstract' as constant modifier
- cannot use 'abstract' as method modifier
- cannot use the %s modifier on a %s
- cannot use the abstract modifier on a property hook
- cannot use the abstract modifier on a property
- cannot use the final modifier on an abstract class
- class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods
- class %s declares abstract method %s() and must therefore be declared abstract
- interface %s cannot contain non abstract method %s()
- interface method %s::%s() must not be final
- non abstract method %s::%s() must contain body
- non abstract property hook must have a body
- only hooked properties may be declared abstract
- property hook cannot be both abstract and final
- property hook cannot be both abstract and private
- property in interface cannot be explicitly abstract.
- static function %s%s%s() cannot be abstract
- syntax error, unexpected identifier “%s”, expecting “;” or “{”
- syntax error, unexpected token “}”, expecting “;” or “{”
- syntax error, unexpected variable “$this”, expecting “;” or “{”
- abstract-method
- addition
- alias
- an alias (%s) was defined for method %s(), but this method does not exist
- an alias was defined for %s::%s but this method does not exist
- cannot use “abstract” as method modifier in trait alias
- cannot use %s as %s because %s is a special class name
- cannot use 'abstract' as method modifier
- cannot use 'final' as method modifier
- cannot use 'static' as method modifier
- allowdynamicproperties
- cannot apply #[allowdynamicproperties] to enum %s
- cannot apply #[allowdynamicproperties] to interface %s
- cannot apply #[allowdynamicproperties] to readonly class %s
- cannot apply #[allowdynamicproperties] to trait %s
- creation of dynamic property %s::$“ zend_long_fmt “ is deprecated
- creation of dynamic property %s::$%s is deprecated
- and
- anonymous-catch
- anonymous-class
- append
- archive
- argument
- %s%s%s(): argument #%d%s%s%s must be passed by reference, value given
- %s() expects exactly 0 arguments, %d given
- %s(): argument #%d%s%s%s could not be passed by reference
- `%s' is not a valid mode for fopen
- argument #%d ($%s) must be of type %s, %s given
- argument #2 ($end) must be a single byte string if
- calling get_parent_class() without arguments is deprecated
- func_get_arg() cannot be called from the global scope
- func_get_args() cannot be called from the global scope
- func_num_args() must be called from a function context
- method %s::%s() must take exactly 1 argument
- method %s::%s() must take exactly 2 arguments
- only variables can be passed by reference
- only variables should be passed by reference
- parameter %d must be passed by reference
- too few arguments to function %s%s%s(), %d passed in %s on line %d and %s %d expected
- array
- [] operator not supported for strings
- array and string offset access syntax with curly braces is deprecated
- array and string offset access syntax with curly braces is no longer supported
- array to string conversion
- array_key_exists(): argument #2 ($array) must be of type array, %s given
- automatic conversion of false to array is deprecated
- calling %s() on an object is deprecated
- can only flip string and integer values, entry skipped
- cannot append to weakmap
- cannot assign to array(), use [] instead in %s
- cannot unpack array with string keys
- cannot unset offset in a non array variable
- cannot use “%s” as a type name as it is reserved
- cannot use %s as array
- cannot use [] for reading
- cannot use object of type %s as array
- cannot use object of type stdclass as array
- foreach() argument must be of type array|object
- illegal offset type in isset or empty
- illegal offset type in unset
- illegal offset type
- implicit conversion from float string “%s” to int loses
- index invalid or out of range
- indirect modification of overloaded element of %s has no effect
- indirect modification of overloaded property %s::$%s has no effect
- is an invalid offset
- must be a list array
- must be of type countable|array, %s given
- must contain at least one element
- only arrays and traversables can be unpacked
- only arrays can be unpacked in constant expression
- parameter must be an array or an object that implements countable
- passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead
- passing an object for argument #1 $array to array_walk_recursive() is deprecated, call get_object_vars() first instead
- syntax error, unexpected ')', expecting '='
- syntax error, unexpected '{'
- syntax error, unexpected token “{”, expecting “)”
- syntax error, unexpected token “{”, expecting “;”
- syntax error, unexpected token “{”
- syntax error, unexpected token “}”
- type %s contains both iterable and array
- undefined array key
- undefined offset
- weakmap key must be an object
- array-callable
- array-filter-mode
- array-syntax
- [] operator not supported for strings
- cannot use string offset as an array
- [syntax error, unexpected '', expecting ';' or ','
- syntax error, unexpected single quoted string “%s”, expecting “)”
- [syntax error, unexpected token “,”, expecting “]”](messages/syntax-error,-unexpected-token-,,-expecting-].html)
- [syntax error, unexpected token “::”, expecting “]”](messages/syntax-error,-unexpected-token-::,-expecting-].html)
- [syntax error, unexpected token “if”, expecting “]”](messages/syntax-error,-unexpected-token-if,-expecting-].html)
- [syntax error, unexpected token “public”, expecting “]”](messages/syntax-error,-unexpected-token-public,-expecting-].html)
- using an object as a backing array for %s is deprecated, as it allows violating class constraints and invariants
- array_change_key_case
- array_key_exists
- array_merge
- arrayaccess
- arrayobject
- arrow-function
- arrow functions on the right hand side of |> must be parenthesized
- cannot bind method %s::%s() to object of class %s
- cannot rebind scope of closure created from method
- instantiation of class closure is not allowed
- [syntax error, unexpected token “)”, expecting “function” or “fn” or “static” or “#“
- [syntax error, unexpected token “;”, expecting “function” or “fn” or “static” or “#“
- as
- ascii
- assertion
- assignation
- asymmetric-property
- asymmetric-visibility
- %s virtual property %s::$%s must not specify asymmetric visibility
- cannot override final property %s::$%s
- multiple access type modifiers are not allowed
- set access level of %s::$%s must be %s (as in class %s)%s
- static property may not have asymmetric visibility
- visibility of property %s::$%s must not be weaker than set visibility
- attribute
- %s::$%s has #[ override] attribute
- %s::%s() has #[ override] attribute, but no matching parent method exists
- %s::%s has #[ override] attribute
- attribute “%s” cannot target %s (allowed targets: %s)
- cannot apply attributes to multiple constants at once
- cannot create closure as attribute argument
- cannot use unpacking in attribute argument list
- has #[ override] attribute, but no matching parent method exists
- syntax error, unexpected fully qualified name “%s”, expecting “function” or “const”
- [syntax error, unexpected identifier “%s”, expecting “]”](messages/syntax-error,-unexpected-identifier-ps,-expecting-].html)
- syntax error, unexpected namespaced name “%s”, expecting “function”
- [syntax error, unexpected token “#“, expecting “)”
- [syntax error, unexpected token “#“, expecting “,” or “;”
- syntax error, unexpected token “#[”, expecting “]”
- syntax error, unexpected token “)”, expecting variable
- syntax error, unexpected token “;”
- [syntax error, unexpected token “class”, expecting “]”](messages/syntax-error,-unexpected-token-class,-expecting-].html)
- trait %s used by %s is deprecated%s
- autoload
- automagic
- autovivification
- backed-enum
- backedenum
- backtick
- balanced
- [syntax error, unexpected token “,”, expecting “]”](messages/syntax-error,-unexpected-token-,,-expecting-].html)
- syntax error, unexpected token “;”, expecting “)”
- [syntax error, unexpected token “;”, expecting “]”](messages/syntax-error,-unexpected-token-;,-expecting-].html)
- [syntax error, unexpected token “class”, expecting “]”](messages/syntax-error,-unexpected-token-class,-expecting-].html)
- [unclosed '(' does not match ']'](messages/unclosed-\q\-does-not-match-\]\.html)
- base-conversion
- base64
- binary-integer
- bind
- cannot bind method %s::%s() to object of class %s, this will be an error in php 9
- cannot rebind scope of closure created from function, this will be an error in php 9
- cannot rebind scope of closure created from method, this will be an error in php 9
- cannot unbind $this of closure using $this, this will be an error in php 9
- cannot unbind $this of method, this will be an error in php 9
- bitfield
- bitshift-operator
- bitwise-operator
- block
- body
- boolean
- break
- '%s' not in the 'loop' or 'switch' context
- '%s' operator accepts only positive integers
- '%s' operator with non integer operand
- break operator accepts only positive integers
- continue“ targeting switch is equivalent to “break
- syntax error, unexpected token “break”
- syntax error, unexpected token “continue”
- by-reference
- by-value
- byte
- calendar
- call
- %s() expects exactly 0 arguments, %d given
- call to %s %s::%s() from global scope
- never returning function must not implicitly return
- syntax error, unexpected single quoted string “%s”, expecting “)”
- syntax error, unexpected token “if”, expecting “)”
- too few arguments to function %s%s%s(), %d passed and %s %d expected
- too few arguments to function %s%s%s(), %d passed and %s %d
- callable
- [callables of the form “%s
- cannot use dynamic function name in constant expression
- class constant %s::%s cannot have type %s
- failed to create closure from callable: %s
- object of type %s is not callable
- passing non callable strings is deprecated since 8.4
- use of “parent “ in callables is deprecated
- use of “self “ in callables is deprecated
- use of “static “ in callables is deprecated
- value of type %s is not callable
- callback
- %s(): return value of the authorizer callback must be of type int, %s returned
- %s(): return value of the collation callback must be of type int, %s returned
- array callback must have exactly two elements
- cannot change default fetch mode while fetching
- must be a callable, null given
- passing non callable strings is deprecated since 8.4
- session callback must have a return value of type bool, %s returned
- case
- case-sensitivity
- cast
- array to string conversion
- illegal offset type in isset or empty
- illegal offset type in unset
- illegal offset type
- non canonical cast (binary) is deprecated, use the (string) cast instead
- non canonical cast (boolean) is deprecated, use the (bool) cast instead
- non canonical cast (double) is deprecated, use the (float) cast instead
- non canonical cast (integer) is deprecated, use the (int) cast instead
- object casts are not supported in this context
- object of class %s could not be converted to %s
- syntax error, unexpected token “(int)”
- the (real) cast has been removed, use (float) instead
- the (real) cast is deprecated, use (float) instead
- the (unset) cast is no longer supported
- the float %.*h is not representable as an int, cast occurred
- catch
- cgi
- chaining-new-without-parenthesis
- character
- child-class
- cite
- clamp
- class
- %s and %s define the same constant (%s) in the composition of %s. however, the definition differs and is considered incompatible. class was composed
- %s and %s define the same property ($%s) in the composition of %s. however, the definition differs and is considered incompatible. class was composed
- a class constant must not be called class. it is reserved for class name fetching
- an alias was defined for method %s(), which exists in both %s and %s. use %s::%s or %s::%s to resolve the ambiguity
- anonymous class method %s() must not be abstract
- calling get_class() without arguments is deprecated
- cannot apply #[allowdynamicproperties] to enum %s
- cannot apply #[allowdynamicproperties] to interface %s
- cannot apply #[allowdynamicproperties] to readonly class %s
- cannot apply #[allowdynamicproperties] to trait %s
- cannot create dynamic property %s::$%s
- cannot inherit previously inherited or override constant %s from interface %s
- cannot make non abstract method %s::%s() abstract in class %s
- cannot redeclare %s %s (previously declared in %s:%d)
- cannot redeclare %s %s
- cannot redeclare %s::$%s
- cannot redeclare %s::%s()
- cannot redeclare class %s
- cannot redefine class constant %s::%s
- cannot use%s %s as %s because the name is already in use
- cannot use “parent” when current class scope has no parent
- cannot use the final modifier on an abstract class
- class “%s” not found
- class %s cannot extend %s %s
- class %s cannot extend enum %s
- class %s cannot use %s it is not a trait
- illegal class name
- inconsistent insteadof definition. the method %s is to be used from %s
- interface %s cannot extend class %s
- must be a user defined class name, internal class name given
- must be a valid class name, %s given
- syntax error, unexpected identifier “%s”, expecting “function” or “const”
- syntax error, unexpected identifier “%s”, expecting “{”
- syntax error, unexpected identifier “%s”
- syntax error, unexpected token “extends”, expecting identifier
- syntax error, unexpected token “extends”
- syntax error, unexpected token “implements”
- syntax error, unexpected token “private”, expecting “{”
- syntax error, unexpected token “protected”, expecting “{”
- syntax error, unexpected token “public”, expecting “{”
- the modifiers of the trait method %s() are changed, but this method does not exist. error
- value for class is not a string
- class-constant
- “static::” is not allowed in compile time constants
- %s %s inherits both %s::%s and %s::%s
- %s and %s define the same constant (%s) in the composition of %s. however, the definition differs and is considered incompatible. class was composed
- %s::%s has #[ override] attribute
- (expression)::class cannot be used in constant expressions
- cannot access %s const %s::%s
- cannot access %s constant %s::%s
- cannot assign %s to class constant %s::%s of type
- cannot be a class constant
- cannot inherit previously inherited or override constant %s from interface %s
- cannot redefine class constant %s::%s
- cannot redefine class constant
- cannot use %s as value for class constant %s::%s of type %s
- cannot use 'abstract' as constant modifier
- cannot use 'final' as constant modifier
- cannot use 'static' as constant modifier
- cannot use the %s modifier on a %s
- class constant %s::%s cannot have type %s
- constant %s::%s is deprecated
- static:: “ is not allowed in compile time constants
- static::class cannot be used for compile time class name resolution
- syntax error, unexpected fully qualified name “%s”, expecting “function” or “const”
- syntax error, unexpected identifier “%s”, expecting “function” or “const”
- syntax error, unexpected namespaced name “%s”, expecting “function”
- syntax error, unexpected token “?”, expecting identifier
- syntax error, unexpected token “private”, expecting “=”
- traits cannot have constants
- type of %s::%s must be compatible with %s::%s of type %s
- undefined class constant '%s::%s'
- undefined constant %s::%s
- class-operator
- clone
- close-tag
- closure
- cannot bind an instance to a static closure, this will be an error in php 9
- cannot bind an instance to a static closure
- cannot bind method %s::%s() to object of class %s, this will be an error in php 9
- cannot bind method %s::%s() to object of class %s
- cannot combine nullsafe operator with closure creation
- cannot create closure as attribute argument
- cannot create closure for new expression
- cannot rebind scope of closure created from function, this will be an error in php 9
- cannot rebind scope of closure created from method, this will be an error in php 9
- cannot rebind scope of closure created from method
- cannot unbind $this of closure using $this, this will be an error in php 9
- cannot unbind $this of method, this will be an error in php 9
- cannot use(…) variables in constant expression
- cannot use $this as lexical variable
- cannot use dynamic method name in constant expression
- cannot use variable $%ps twice
- cannot use variable $%s twice
- closures in constant expressions must be static
- current function is not a closure
- failed to create closure from callable: %s
- illegal method name
- instantiation of class closure is not allowed
- passing non callable strings is deprecated since 8.4
- syntax error, unexpected token “(”
- [syntax error, unexpected token “)”, expecting “function” or “fn” or “static” or “#“
- [syntax error, unexpected token “;”, expecting “function” or “fn” or “static” or “#“
- syntax error, unexpected token “as”
- syntax error, unexpected token “final”, expecting “(”
- use of “parent” in callables is deprecated
- use of “self” in callables is deprecated
- use of “static” in callables is deprecated
- closure-class
- coalesce
- only arrays and traversables can be unpacked
- only arrays can be unpacked in constant expression
- strlen(): passing null to parameter #1 ($string) of type string is deprecated
- syntax error, unexpected token “??”
- typed property %ps::$%ps must not be accessed before initialization
- typed property %s::$%s must not be accessed before initialization
- typed static property %s::$%s must not be accessed before initialization
- codepoint
- coercion
- colon
- comma
- comment
- [syntax error, unexpected token “)”, expecting “function” or “fn” or “static” or “#“
- [syntax error, unexpected token “;”, expecting “function” or “fn” or “static” or “#“
- unterminated comment starting line %
- unterminated comment starting line %d
- compact
- comparison
- compatibility
- cannot make non static method %s::%s() static in class %s
- cannot make static method %s::%s() non static in class %s
- could not check compatibility between %s and %s, because class %s is not available
- declaration of %s must be compatible with %s
- declaration of %s::%s() must be compatible with %s::%s()
- set type of %s::$%s must be supertype of %s (as in %s %s)
- type of %s::$%s must be %s%s (as in class %s)
- type of %s::$%s must not be defined (as in class %s)
- compile-time
- compression
- passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead
- passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead
- passing an object for filter parameters for %s is deprecated, call get_object_vars() first instead
- passing an object for filter parameters for bzip2.compress is deprecated, call get_object_vars() first instead
- passing an object for filter parameters for bzip2.decompress is deprecated, call get_object_vars() first instead
- concatenation
- conditional-structure
- connection
- const
- constant
- “static::” is not allowed in compile time constants
- %s(): argument #%d%s%s%s cannot be passed by reference
- cannot apply attributes to multiple constants at once
- cannot declare self referencing constant
- constant %s already defined
- constant %s is deprecated
- define(): argument #3 ($case_insensitive) is ignored and treated as false since declaration of case insensitive constants is no longer supported, passing the argument explicitly is unnecessary
- define(): argument #3 ($case_insensitive) is ignored since declaration of case insensitive constants is no longer supported, this will be an error in php 9.0
- define(): argument #3 ($case_insensitive) is ignored since declaration of case insensitive constants is no longer supported
- define(): declaration of case insensitive constants is deprecated
- dynamic class names are not allowed in compile time class constant references
- instanceof expects an object instance, constant given
- reflectionclass::getconstant() for a non existent constant is deprecated,
- syntax error, unexpected ' ', expecting '='
- syntax error, unexpected token “&”, expecting end of file
- syntax error, unexpected token “=”
- syntax error, unexpected token “?”, expecting identifier
- syntax error, unexpected token “const”
- undefined constant “%s
- constant-combinaison
- constant-expression
- constant-in-trait
- constant-scalar-expression
- constructor
- cannot call constructor
- cannot change default fetch mode while fetching
- cannot declare promoted property in an abstract constructor
- cannot directly construct directory, use dir() instead
- cannot modify readonly object of class %s
- cannot override final %s::__construct() with %s::__construct()
- constructor %s::%s() cannot declare a return type
- datetimezone object is unconstructed
- intllistformatter object is already constructed
- making a constructor a generator is deprecated
- method %s::%s() cannot declare a return type
- method %s::%s cannot be #[ nodiscard]
- method %s::__construct() cannot declare a return type
- methods with the same name as their class will not be constructors in a future version of php; %s has a deprecated constructor
- must be empty when class provided in argument #1 ($class) does not have a constructor
- must be empty when class provided in argument #2 ($class) does not have a constructor
- object not initialized
- object of type %s has not been correctly initialized by calling parent::__construct() in its constructor
- returning a value from a constructor is deprecated
- the parent constructor was not called: the object is in an invalid state
- continue
- '%s' not in the 'loop' or 'switch' context
- '%s' operator accepts only positive integers
- '%s' operator with non integer operand
- continue“ targeting switch is equivalent to “break
- continue operator accepts only positive integers
- syntax error, unexpected token “break”
- syntax error, unexpected token “continue”
- control-flow
- count
- countable
- csv
- ctype
- curl
- curly-bracket
- database
- date
- datetime
- dba
- declaration
- declare
- declare(%s) value must be a literal
- encoding declaration pragma must be
- no code may exist outside of namespace {}
- syntax error, unexpected token “)”, expecting “=”
- syntax error, unexpected token “;”, expecting “,” or “)”
- syntax error, unexpected token “=”, expecting identifier
- syntax error, unexpected token “namespace”
- unsupported declare '%s'
- decrement
- default
- default-value
- define
- definition
- delimiter
- deprecated
- deprecation
- depth
- destructor
- destructuring
- dir
- directive
- %s() has been disabled for security reasons
- assert.active ini setting is deprecated
- assert.bail ini setting is deprecated
- assert.exception ini setting is deprecated
- assert.warning ini setting is deprecated
- directive 'report_memleaks' is deprecated
- disabling session.use_only_cookies ini setting is deprecated
- enabling session.use_trans_sid ini setting is deprecated
- session.sid_bits_per_character ini setting is deprecated
- session.sid_length ini setting is deprecated
- the filter.default ini setting is deprecated
- usage of session.referer_check ini setting is deprecated
- usage of session.trans_sid_hosts ini setting is deprecated
- usage of session.trans_sid_tags ini setting is deprecated
- use of iconv.input_encoding is deprecated
- use of iconv.internal_encoding is deprecated
- use of iconv.output_encoding is deprecated
- use of mbstring.http_input is deprecated
- use of mbstring.http_output is deprecated
- use of mbstring.internal_encoding is deprecated
- disable_functions
- division
- dnf-type
- do-while
- double-quote
- dsn
- duration
- dynamic
- dynamic-call
- dynamic-constant
- dynamic-property
- each
- echo
- ellipsis
- empty
- empty-string
- encoding
- calling mb_check_encoding() without argument is deprecated
- charset “%s” is not supported, assuming utf 8
- encoding declaration pragma must be
- must be a valid charset
- must be a valid encoding, “%s” given
- passing a negative integer to argument #3 ($width) is deprecated
- passing an object for argument #%“ priu32 “ $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead
- passing the encoding as third parameter is deprecated. use an explicit zero offset
- syntax error, unexpected token “=”, expecting identifier
- the connection has no charset associated
- unexpected character in input: ' ' (ascii=92)
- unsupported declare '%s'
- wrong encoding, conversion from “%s” to “%s” is not allowed
- entity
- enum
- %s %s must implement %d abstract method%s (
- %s method %s::%s() must not be abstract
- %s::%s has #[ override] attribute
- cannot apply #[allowdynamicproperties] to enum %s
- cannot create dynamic property %s::$%s
- cannot instantiate enum %s
- cannot redeclare %s %s (previously declared in %s:%d)
- cannot redeclare %s %s
- cannot redeclare %s::%s()
- cannot use trait %s
- case %s of backed enum %s must have a value
- case %s of non backed enum %s must not have a value
- case can only be used in enums
- class %s cannot extend enum %s
- duplicate value in enum %s for cases %s and %s
- enum %s cannot implement the serializable interface
- enum %s cannot include magic method %s
- enum %s cannot include properties
- enum backing type must be int or string
- enum case type %s does not match enum backing type %s
- enums are not compatible with %s
- fetching properties on non enums in constant expressions is not allowed
- non enum class %s cannot implement interface %s
- syntax error, unexpected token “implements”
- syntax error, unexpected token “private”, expecting “{”
- syntax error, unexpected token “protected”, expecting “{”
- syntax error, unexpected token “public”, expecting “{”
- trying to clone an uncloneable object of class %s
- unbacked enum %s cannot be converted to a string
- enum-case
- error
- escape-data
- escape-sequence
- exception
- %s %s cannot implement interface %s, extend exception or error instead
- can only throw objects
- cannot throw objects that do not implement throwable
- cannot use try without catch or finally
- passing e_user_error to trigger_error() is deprecated since 8.4, throw an exception or call exit with a string message instead
- use of warnings for sqlite3 is deprecated
- execution-time
- exit
- explode
- exponent
- exponential
- expression
- cannot use isset() on the result of an expression (you can use “null !== expression” instead)
- cannot use isset() on the result of an expression
- cannot use list() as standalone expression
- cannot use temporary expression in write context
- syntax error, unexpected 'throw' (t_throw)
- syntax error, unexpected token “if”
- extends
- cannot use “parent” when current class scope has no parent
- class %s cannot extend final class %s
- interface %s cannot extend class %s
- interface %s cannot implement itself
- syntax error, unexpected identifier “%s”, expecting “{”
- syntax error, unexpected token “extends”, expecting “{”
- syntax error, unexpected token “extends”, expecting identifier
- syntax error, unexpected token “extends”
- the sqlite3 object has not been correctly initialised or is already closed
- extension
- false
- ffi
- file
- couldn't open stream %s
- couldn't open stream: %s
- failed to open stream: too many open files
- filename cannot be empty
- no such file or directory
- open_basedir restriction in effect. file(%s) is not within the allowed path(s): (%s)
- path cannot be empty
- path must not be empty
- write of %zu bytes failed with errno=%d %s
- file-mode
- file_put_contents
- filter
- final
- %s::%s cannot override final constant %s::%s
- cannot override final %s::%s() with %s::%s()
- cannot override final %s::__construct() with %s::__construct()
- cannot override final property %s::$%s
- cannot override final property hook %s::%s()
- cannot use 'final' as constant modifier
- cannot use the %s modifier on a %s
- cannot use the final modifier on a parameter
- cannot use the final modifier on a property
- cannot use the final modifier on an abstract class
- class %s cannot extend %s %s
- class %s cannot extend final class %s
- interface method %s::%s() must not be final
- multiple final modifiers are not allowed
- private constant %s::%s cannot be final as it is not visible to other classes
- private methods cannot be final as they are never overridden by other classes
- property cannot be both final and private
- property hook cannot be both abstract and final
- property hook cannot be both final and private
- property in interface cannot be final
- the “generator” class is reserved for internal use and cannot be manually instantiated
- finally
- finfo
- first-class-callable
- array callback has to contain indices 0 and 1
- cannot call %ps() dynamically
- cannot combine nullsafe operator with closure creation
- cannot create closure as attribute argument
- cannot create closure for new expression
- cannot create closure for parent property hook call
- cannot use dynamic method name in constant expression
- illegal method name
- instantiation of class closure is not allowed
- float
- foreach
- an iterator cannot be used with foreach by reference
- cannot create reference to property %s::$%s
- cannot use list as key element
- foreach() argument must be of type array|object
- invalid argument supplied for foreach()
- syntax error, unexpected identifier “%s”, expecting variable
- syntax error, unexpected token “as”
- the each() function is deprecated. this message will be suppressed on further calls
- format
- fully-qualified-name
- function
- %s(): returning by reference from a void function is deprecated
- a never returning function must not return
- call to undefined function %s()
- call to undefined function each()
- call to undefined function
- cannot use “parent” when no class scope is active
- func_get_arg() cannot be called from the global scope
- func_get_args() cannot be called from the global scope
- func_num_args() must be called from a function context
- function %s() is deprecated%s
- function libxml_disable_entity_loader() is deprecated since 8.0, as external entity loading is disabled by default
- must be sodium_crypto_pwhash_saltbytes bytes long
- must be sodium_crypto_pwhash_scryptsalsa208sha256_saltbytes bytes long
- syntax error, unexpected identifier “%s”, expecting “(”
- syntax error, unexpected identifier “%s”, expecting “function”
- syntax error, unexpected token “)”, expecting variable
- syntax error, unexpected token “=”, expecting variable
- syntax error, unexpected token “final”, expecting “(”
- syntax error, unexpected variable “$%s”, expecting “)”
- syntax error, unexpected variable “$task”, expecting “)”
- syntax error, unexpected variable “%s”, expecting “(”
- the “salt “ option has been ignored, since providing a custom salt is no longer supported
- function-subscripting
- generator
- cannot rewind a generator that was already run
- cannot use “yield from “ inside a by reference generator
- class %s cannot extend final class %s
- generator return type must be a supertype of generator
- generators cannot return values using “return”
- making a constructor a generator is deprecated
- making a destructor a generator is deprecated
- the “generator” class is reserved for internal use and cannot be manually instantiated
- the “yield “ expression can only be used inside a function
- trying to clone an uncloneable object of class %s
- get_class
- global
- gmp
- goto
- handler
- hash
- must be a list array
- passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs
- passing a seed of a type other than int is deprecated because it is ignored
- passing a seed of a type other than int is deprecated because it is the same as setting the seed to 0
- unknown digest algorithm: %s
- hashing
- heredoc
- hexadecimal-integer
- html-entities
- html-entity
- htmlentities
- http
- iconv
- identifier
- if-then
- syntax error, unexpected ','
- syntax error, unexpected 'elseif'
- syntax error, unexpected token “;”
- syntax error, unexpected token “if”, expecting “)”
- [syntax error, unexpected token “if”, expecting “]”](messages/syntax-error,-unexpected-token-if,-expecting-].html)
- syntax error, unexpected token “if”
- image
- image-filter
- implements
- %s %s cannot implement previously implemented interface %s
- %s cannot implement %s it is not an interface
- class %s cannot implement both iterator and iteratoraggregate at the same time
- interface %s cannot extend class %s
- interface method %s::%s() must not be final
- syntax error, unexpected identifier “%s”, expecting “{”
- syntax error, unexpected token “extends”, expecting “{”
- syntax error, unexpected token “implements”
- include
- increment
- index
- index-array
- cannot mix keyed and unkeyed array entries in assignments
- cannot unpack array with string keys
- index invalid or out of range
- is an invalid offset
- undefined array key
- using null as an array offset is deprecated, use an empty string instead
- using null as the key parameter for array_key_exists() is deprecated, use an empty string instead
- infinite
- inheritance
- %s %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining method%s (
- %s class %s cannot extend %s class %s
- access level to %s::$%s must be %s (as in class %s)%s
- cannot declare promoted property in an abstract constructor
- cannot inherit previously inherited or override constant %s from interface %s
- cannot make non abstract method %s::%s() abstract in class %s
- cannot redeclare %s%s::$%s as %s%s::$%s
- cannot redefine class constant
- cannot use “parent “ when current class scope has no parent
- cannot use “parent “ when no class scope is active
- non readonly class %s cannot extend readonly class %s
- readonly class %s cannot extend non readonly class %s
- set access level of %s::$%s must be %s (as in class %s)%s
- type of %s::%s must be compatible with %s::%s of type %s
- initialisation
- instance
- instanceof
- insteadof
- integer
- a non numeric value encountered
- cannot decrement property %s::$%s of type int past its minimal value
- cannot increment property %s::$%s of type int past its maximal value
- division of php_int_min by 1 is not an integer
- must be greater than 0
- the float %.*h is not representable as an int, cast occurred
- the float string “%s “ is not representable as an int, cast occurred
- interface
- %s %s cannot implement previously implemented interface %s
- %s %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining method%s (
- %s %s inherits both %s::%s and %s::%s
- %s %s must implement %d abstract method%s (
- %s %s must implement interface %s as part of either %s or %s
- %s function %s::%s() cannot contain body
- %s method %s::%s() must not be abstract
- access type for interface constant %s::%s must be public
- access type for interface method %s::%s() must be public
- cannot apply #[allowdynamicproperties] to interface %s
- cannot inherit previously inherited or override constant %s from interface %s
- cannot instantiate interface %s
- cannot redeclare %s %s (previously declared in %s:%d)
- cannot redeclare %s %s
- cannot use traits inside of interfaces. %s is used in %s
- class %s cannot implement previously implemented interface %s
- class %s implementing sessionhandlerinterface is missing the create_sid() method which will be required in php 9.0
- class %s implementing sessionhandlerinterface is missing the validateid() method which will be required in php 9.0
- class %s must implement interface %s as part of either %s or %s
- datetimeinterface can't be implemented by user classes
- interface “%s” not found
- interface %s cannot contain non abstract method %s()
- interface %s cannot extend class %s
- interface %s cannot implement itself
- interface method %s::%s() must not be final
- interfaces may not include properties
- non enum class %s cannot implement interface %s
- property hook cannot be both abstract and final
- property in interface cannot be explicitly abstract.
- property in interface cannot be protected or private
- return type of %s::%s() should either be compatible with %s::%s(): mixed
- set type of %s::$%s must be supertype of %s (as in %s %s)
- syntax error, unexpected identifier “%s”
- syntax error, unexpected token “extends”, expecting identifier
- syntax error, unexpected token “extends”
- syntax error, unexpected token “private”, expecting “{”
- syntax error, unexpected token “protected”, expecting “{”
- syntax error, unexpected token “public”, expecting “{”
- unknown named parameter $%s
- interpolation
- intersection-type
- intl
- is_object
- isset
- cannot access offset of type %s in isset or empty
- cannot use isset() on the result of an expression (you can use “null !== expression” instead)
- cannot use isset() on the result of an expression
- typed property %ps::$%ps must not be accessed before initialization
- typed property %s::$%s must not be accessed before initialization
- typed static property %s::$%s must not be accessed before initialization
- iterable
- iterator
- jit
- keyword
- never cannot be used as a parameter type
- syntax error, unexpected 'match'
- syntax error, unexpected token “%s”, expecting identifier
- syntax error, unexpected token “ “, expecting “{”
- syntax error, unexpected token “::”, expecting “:”
- syntax error, unexpected token “::”
- syntax error, unexpected token “final”, expecting “(”
- syntax error, unexpected token “match”, expecting “(”
- syntax error, unexpected token “private”, expecting “=”
- label
- late-static-binding
- lazy-objects
- ldap
- lexical
- list
- cannot assign reference to non referenceable value
- cannot assign to array(), use [] instead in %s
- cannot mix [] and list()
- cannot mix keyed and unkeyed array entries in assignments
- cannot use %s as array
- cannot use empty array elements in arrays
- cannot use empty array entries in keyed array assignment
- cannot use empty list
- cannot use empty list
- cannot use list() as standalone expression
- cannot use list as key element
- must be a list array
- must be a list of %s
- spread operator is not supported in assignments
- syntax error, unexpected ')', expecting '='
- syntax error, unexpected ','
- syntax error, unexpected token “,”, expecting variable or “$”
- syntax error, unexpected token “,”, expecting variable
- the each() function is deprecated. this message will be suppressed on further calls
- undefined array key
- literal
- locale
- loop
- magic-constant
- magic-method
- %s implements the serializable interface
- %s::%s(): return type must be %s when declared
- call to %s %s::%s() from invalid
- call to %s method %s::%s() from %s%s
- call to undefined method %s::%s()
- cannot use the final modifier on a property
- enum %s cannot include magic method %s
- method %s::%s() cannot be static
- method %s::%s() must take exactly 1 argument
- method %s::%s() must take exactly 2 arguments
- method %s::%s cannot be #[ nodiscard] error_type
- method %s::%s cannot be #[ nodiscard]
- property cannot be both final and private
- property hook cannot be both final and private
- returning null from %s::__debuginfo() is deprecated, make the return type non nullable and return an empty array instead
- returning null from %s::__debuginfo() is deprecated, return an empty array instead
- serialization of %s is not allowed, override __serialize() and __unserialize() to implement it
- the magic method %s::%s() must have public visibility
- unserialization of %s is not allowed, override __serialize() and __unserialize() to implement it
- match
- '%s' not in the 'loop' or 'switch' context
- match expressions may only contain one default arm
- syntax error, unexpected ','
- syntax error, unexpected '::', expecting '('
- syntax error, unexpected 'match'
- syntax error, unexpected token “break”
- syntax error, unexpected token “continue”
- syntax error, unexpected token “match”, expecting “(”
- syntax error, unexpected token “match”
- unhandled match case %s
- math
- max_execution_time
- max_memory_limit
- mbstring
- calling mb_check_encoding() without argument is deprecated
- handling base64 via mbstring is deprecated; use base64_encode base64_decode instead
- handling html entities via mbstring is deprecated; use htmlspecialchars, htmlentities, or mb_encode_numericentity mb_decode_numericentity instead
- handling html entities via mbstring is deprecated; use htmlspecialchars, htmlentities, or mb_encode_numericentity mb_decode_numericentity
- handling qprint via mbstring is deprecated; use quoted_printable_encode quoted_printable_decode instead
- handling qprint via mbstring is deprecated; use quoted_printable_encode quoted_printable_decode
- handling uuencode via mbstring is deprecated; use convert_uuencode convert_uudecode instead
- must be a valid encoding, “%s” given
- must be contained in argument #1 ($haystack)
- offset not contained in string.
- passing a negative integer to argument #3 ($width) is deprecated
- use of mbstring.http_input is deprecated
- use of mbstring.http_output is deprecated
- use of mbstring.internal_encoding is deprecated
- memory
- memory_limit
- message-digest
- method
- %s(): returning by reference from a void function is deprecated
- %s function %s::%s() cannot be declared private
- %s function %s::%s() cannot contain body
- a precedence rule was defined for %s::%s but this method does not exist
- an alias (%s) was defined for method %s(), but this method does not exist
- an alias was defined for %s::%s but this method does not exist
- an alias was defined for method %s(), which exists in both %s and %s. use %s::%s or %s::%s to resolve the ambiguity
- call to %s %s::%s() from invalid
- call to %s method %s::%s() from %s%s
- call to undefined method %s::%s()
- can't inherit abstract function %s::%s() (previously declared abstract in %s)
- cannot make non static method %s::%s() static in class %s
- cannot make static method %s::%s() non static in class %s
- cannot redeclare %s::%s()
- cannot use 'readonly' as %s modifier
- cannot use 'readonly' as method modifier
- inconsistent insteadof definition. the method %s is to be used from %s
- method name must be a string
- must be a valid method name
- non static method %s::%s() cannot be called statically
- non static method %s::%s() should not be called statically
- syntax error, unexpected identifier “%s”, expecting “(”
- syntax error, unexpected identifier “%s”, expecting “;” or “{”
- syntax error, unexpected identifier “%s”, expecting “function” or “const”
- syntax error, unexpected token “(”, expecting identifier or variable or “{” or “$”
- syntax error, unexpected token “(”, expecting variable
- syntax error, unexpected token “(”
- syntax error, unexpected token “)”, expecting variable
- syntax error, unexpected token “public”
- syntax error, unexpected token “}”, expecting “;” or “{”
- syntax error, unexpected variable “$%s”, expecting “)”
- syntax error, unexpected variable “$task”, expecting “)”
- syntax error, unexpected variable “$this”, expecting “;” or “{”
- syntax error, unexpected variable “%s”, expecting “(”
- the modifiers of the trait method %s() are changed, but this method does not exist. error
- the sqlite3 object has not been correctly initialised or is already closed
- too few arguments to function %s%s%s(), %d passed and %s %d expected
- too few arguments to function %s%s%s(), %d passed and %s %d
- trying to invoke %s method %s::%s() from scope %s
- mixed
- modifier
- modulo
- multi-byte
- multicast
- multiplication
- mysql
- mysqli
- name
- cannot declare const %s because
- cannot redeclare %s() (previously declared in %s:%d)
- cannot redeclare function %s() (previously declared in %s:%d)
- cannot use%s %s as %s because the name is already in use
- cannot use “abstract” as method modifier in trait alias
- cannot use %s as %s because %s is a special class name
- cannot use 'abstract' as method modifier
- cannot use 'final' as method modifier
- cannot use 'static' as method modifier
- cannot use dynamic function name in constant expression
- illegal class name
- illegal function name
- method name must be a string
- syntax error, unexpected token “extends”, expecting identifier
- named-parameter
- %s%s%s() does not accept unknown named parameters
- array_merge() does not accept unknown named parameters
- cannot combine named arguments and argument unpacking
- cannot use argument unpacking after named arguments
- duplicate named parameter $%s
- internal function %s%s%s() does not accept named variadic arguments
- optional parameter $%s declared before required parameter $%s is implicitly treated as a required parameter
- syntax error, unexpected identifier “%s”, expecting “)”
- [syntax error, unexpected identifier “%s”, expecting “]”](messages/syntax-error,-unexpected-identifier-ps,-expecting-].html)
- syntax error, unexpected integer “%s”, expecting “)”
- syntax error, unexpected single quoted string “%s”, expecting “)”
- syntax error, unexpected token “,”
- syntax error, unexpected token “:”, expecting “)”
- [syntax error, unexpected token “:”, expecting “]”](messages/syntax-error,-unexpected-token-:,-expecting-].html)
- syntax error, unexpected token “:”
- syntax error, unexpected token “new”, expecting “)”
- the $escape parameter must be provided as its default value will change
- unknown named parameter $%s
- namespace
- call to undefined function
- cannot mix bracketed namespace declarations
- cannot redeclare function %s() (previously declared as local import)
- cannot use '%s' as namespace name
- cannot use 'namespace' as namespace name
- declaring %s constant called namespace is deprecated
- namespace %s is an invalid class name
- namespace declaration statement has to be
- namespace declarations cannot be nested
- no code may exist outside of namespace {}
- syntax error, unexpected ';', expecting '{'
- syntax error, unexpected fully qualified name “%s”, expecting “{”
- syntax error, unexpected fully qualified name “%s”
- syntax error, unexpected token “ “, expecting “{”
- syntax error, unexpected token “;”, expecting “{”
- syntax error, unexpected token “namespace”, expecting “{”
- syntax error, unexpected token “namespace”
- syntax error, unexpected token “use”, expecting “{”
- the use statement with non compound name '%s'
- namespaced-name
- nan
- native
- native-type
- nesting
- network
- never
- %s(): never returning %s must not implicitly return
- %s(): never returning function must not implicitly return
- a never returning %s does not return a value
- a never returning %s must not return
- a never returning function must not return
- a never returning method must not return
- cannot use 'never' as class name as it is reserved
- class constant %s::%s cannot have type %s
- never can only be used as a standalone type
- never cannot be used as a parameter type
- never returning function must not implicitly return
- new
- new-in-initializer
- new-line
- nodiscard
- a never returning %s does not return a value
- a void %s does not return a value
- method %s::%s cannot be #[ nodiscard] error_type
- method %s::%s cannot be #[ nodiscard]
- the return value of function %s() should either be used or intentionally ignored by casting it as (void)%s code
- the return value of function %s() should either be used or intentionally ignored by casting it as (void)%s
- the return value of method %s::%s() should either be used or intentionally ignored by casting it as (void)%s
- non-instantiable
- normalisation
- null
- %s(): passing null to parameter #%
- attempt to assign property “%s” on null
- attempt to read property “%s” on %s
- can't use nullsafe operator in write context
- cannot use %s as array
- decrement on type null has no effect, this will change in the next major version of php
- must be a callable, null given
- must be empty when class provided in argument #1 ($class) does not have a constructor
- must be empty when class provided in argument #2 ($class) does not have a constructor
- must be of type countable|array, %s given
- null cannot be marked as nullable
- parameter must be an array or an object that implements countable
- passing null is deprecated, instead the last opened directory stream should be provided
- strlen(): passing null to parameter #1 ($string) of type string is deprecated
- trying to access array offset on %s
- using null as an array offset is deprecated, use an empty string instead
- using null as the key parameter for array_key_exists() is deprecated, use an empty string instead
- nullable
- %s(): implicitly marking parameter $%s as nullable is deprecated, the explicit nullable type
- default value for property of type %s may not be null. use the nullable type %s to allow null default value
- null cannot be marked as nullable
- returning null from %s::__debuginfo() is deprecated, make the return type non nullable and return an empty array instead
- type mixed cannot be marked as nullable since mixed already includes null
- nullsafe
- nullsafe-object-operator
- numeric-separator
- numeric-string
- object
- attempt to read property “%s” on %s
- calling %s() on an object is deprecated
- cannot use object of type %s as array
- cannot use object of type stdclass as array
- direct instantiation of weakreference is not allowed, use weakreference::create instead
- object %s#%d not contained in weakmap
- object of type %s is not callable
- type %s contains both object and a class type
- using an object as a backing array for %s is deprecated, as it allows violating class constraints and invariants
- weakmap key must be an object
- object-lifecycle
- object-syntax
- octal-integer
- offset
- oop
- opcache
- open-tag
- open_basedir
- openssl
- operand
- operator
- optional-parameter
- output-buffering
- override
- overwrite
- pack
- parameter
- %s(): implicitly marking parameter $%s as nullable is deprecated, the explicit nullable type must be used instead
- %s(): optional parameter $%s declared before required parameter $%s
- cannot use %s as default value for parameter $%s of type %s
- cannot use %s as default value for property %s::$%s of type %s
- cannot use lexical variable %s as a parameter name
- cannot use the final modifier on a parameter
- cannot use the static modifier on a parameter
- default value for parameters with a %s type can only be %s or null
- duplicate parameter name $%s for function %s%s%s()
- func_get_arg() cannot be called from the global scope
- func_get_args() cannot be called from the global scope
- func_num_args() must be called from a function context
- get_defined_functions(): the $exclude_disabled parameter has no effect since php 8.0
- named parameter $%s overwrites previous argument
- only the last parameter can be variadic
- optional parameter $%s declared before required parameter $%s is implicitly treated as a required parameter
- parameter must have a name
- parameter uses 'parent' as type hint although class does not have a parent!
- redefinition of parameter $%s
- required parameter $%s follows optional parameter $%s
- syntax error, unexpected token “=”, expecting variable
- variadic parameter cannot have a default value
- parameter-removal
- parent
- ' %s' is an invalid class name
- cannot access parent:: when current class scope has no parent
- cannot access parent:: when no class scope is active
- cannot use “%s” when no class scope is active
- cannot use “parent” when current class scope has no parent
- cannot use “parent” when no class scope is active
- object of type %s has not been correctly initialized by calling parent::__construct() in its constructor
- parameter uses 'parent' as type hint although class does not have a parent!
- the sqlite3 object has not been correctly initialised or is already closed
- parenthesis
- syntax error, unexpected ','
- syntax error, unexpected token “)”
- syntax error, unexpected token “,”, expecting “)”
- syntax error, unexpected token “if”
- [unclosed '(' does not match ']'](messages/unclosed-\q\-does-not-match-\]\.html)
- [unclosed '(' on line %s does not match ']'](messages/unclosed-\q\-on-line-ps-does-not-match-\]\.html)
- unclosed '('
- unmatched ')'
- [unmatched ']'](messages/unmatched-\]\.html)
- unparenthesized `a ? b : c ? d : e` is not supported.
- unparenthesized `a ? b : c ?: d` is not supported.
- unparenthesized `a ?: b ? c : d` is not supported.
- partial-application
- partial-function
- password
- path
- pathinfo
- pattern-matching
- pdo
- %s(): return value of the authorizer callback must be of type int, %s returned
- %s(): return value of the collation callback must be of type int, %s returned
- cannot change default fetch mode while fetching
- the pdo extension must be loaded first in order to load pdo drivers
- the pdo::fetch_serialize mode is deprecated
- pgsql
- phar
- php-variable
- php.ini
- php://filter
- php_int_max
- pipe-operator
- pipeline
- poll-api
- positive-integer
- posix
- precision
- printf
- private
- %s function %s::%s() cannot be declared private
- cannot use the final modifier on a property
- private constant %s::%s cannot be final as it is not visible to other classes
- private methods cannot be final as they are never overridden by other classes
- property cannot be both final and private
- property hook cannot be both abstract and private
- property hook cannot be both final and private
- promoted-property
- cannot declare promoted property in an abstract constructor
- cannot declare promoted property outside a constructor
- cannot declare variadic promoted property
- cannot indirectly modify readonly property %s::$%s
- syntax error, unexpected token “private”, expecting “(”
- syntax error, unexpected token “private”, expecting “)”
- property
- %s and %s define the same property ($%s) in the composition of %s. however, the definition differs and is considered incompatible. class was composed
- %s::$%s has #[ override] attribute
- access level to %s::$%s must be %s (as in class %s)%s
- accessing static trait property %s::$%s is deprecated
- attempt to assign property “%s” on null
- cannot access %s property %s::$%s
- cannot acquire reference to $globals
- cannot acquire reference to readonly property %s::$%s
- cannot assign %s to property %s::$%s of type %s
- cannot assign %s to reference held by property %s::$%s of type %s
- cannot auto initialize an array inside property %s::$%s of type %s
- cannot declare variadic promoted property
- cannot decrement property %s::$%s of type int past its minimal value
- cannot increment property %s::$%s of type int past its maximal value
- cannot redeclare %s%s::$%s as %s%s::$%s
- cannot redeclare %s property %s::$%s as %s %s::$%s
- cannot redeclare %s::$%s
- cannot use the final modifier on a parameter
- default value for property of type int may not be null. use the nullable type ?int to allow null default value
- enum %s cannot include properties
- interfaces may not include properties
- property %s does not exist
- property %s::$%s cannot have type %s
- property %s::$%s does not exist
- property in interface cannot be explicitly abstract.
- property in interface cannot be final
- property in interface cannot be protected or private
- reflectionproperty::getdefaultvalue() for a property without a default value is deprecated,
- syntax error, unexpected identifier “%s”, expecting “function” or “const”
- syntax error, unexpected token “(”, expecting variable
- syntax error, unexpected token “,”, expecting variable or “$”
- syntax error, unexpected token “,”, expecting variable
- syntax error, unexpected token “=”, expecting identifier or variable or “{” or “$”
- type of %s::$%s must be %s%s (as in class %s)
- type of %s::$%s must be omitted to match the parent definition in class %s
- type of %s::$%s must not be defined (as in class %s)
- undefined property %s::$%s
- property-hook
- %s%s%s(): return value must be of type %s, %s returned
- %s and %s define the same hooked property ($%s) in the composition of %s. conflict resolution between hooked properties is currently not supported. class was composed
- %s hook of property %s::$%s must accept exactly one parameters
- abstract property %s::$%s must specify at least one abstract hook
- abstract property hook cannot have body
- cannot create closure for parent property hook call
- cannot create reference to property %s::$%s
- cannot declare hooks for static property
- cannot override final property hook %s::%s()
- cannot redeclare property hook “%s
- cannot redeclare property hook
- cannot specify default value for virtual hooked property %s::$%s
- cannot unset hooked property %s::$%s
- cannot use %s() on virtual property %ps::$%ps
- cannot use the abstract modifier on a property hook
- cannot use the abstract modifier on a property
- cannot use the final modifier on a property
- cannot use the static modifier on a property hook
- get hook of backed property %s::%s with set hook may not return by reference
- get hook of property %s::$%s must not have a parameter list
- hooked properties cannot be readonly
- indirect modification of %s::$%s is not allowed
- interfaces may not include properties
- interfaces may only include hooked properties
- must not use parent::$%s::%s() in a different property ($%s)
- must not use parent::$%s::%s() in a different property hook (%s)
- must not use parent::$%s::%s() outside a property hook
- non abstract property hook must have a body
- only hooked properties may be declared abstract
- parameter $%s of %s hook %s::$%s must not be pass by reference
- parameter $%s of %s hook %s::$%s must not be variadic
- parameter $%s of %s hook %s::$%s must not have a default value
- property cannot be both final and private
- property hook cannot be both abstract and final
- property hook cannot be both abstract and private
- property hook cannot be both final and private
- property in interface cannot be explicitly abstract.
- property in interface cannot be final
- property in interface cannot be protected or private
- set type of %s::$%s must be supertype of %s (as in %s %s)
- syntax error, unexpected token “{”, expecting “,” or “;”
- type of parameter $%s of hook %s::$%s::set must be compatible with property type
- unknown hook “%s” for property %s::$%s, expected “get” or “set”
- unknown hook “%s “ for property %s::$%s
- query-string
- quoted-printable
- random
- range
- reading
- readonly
- %s class %s cannot extend %s class %s
- calling a function “readonly” is deprecated
- cannot %s readonly property %s::$%s from %s%s
- cannot acquire reference to $globals
- cannot acquire reference to readonly property %s::$%s
- cannot apply #[allowdynamicproperties] to readonly class %s
- cannot create dynamic property %s::$%s
- cannot indirectly modify readonly property %s::$%s
- cannot modify readonly object of class %s
- cannot modify readonly property %s::$%s
- cannot redeclare %s property %s::$%s as %s %s::$%s
- cannot unset readonly property %s::$%s
- cannot use 'readonly' as %s modifier
- cannot use 'readonly' as method modifier
- hooked properties cannot be readonly
- multiple readonly modifiers are not allowed
- non readonly class %s cannot extend readonly class %s
- readonly class %s cannot extend non readonly class %s
- readonly class %s cannot use trait with a non readonly property %s::$%s
- readonly property %s::$%s cannot have default value
- readonly property %s::$%s must have type
- static property %s::$%s cannot be readonly
- syntax error, unexpected identifier “readonly”, expecting “function” or “const”
- recursion
- recursive-array
- reference
- %s%s%s(): argument #%d%s%s%s must be passed by reference, value given
- %s(): argument #%d%s%s%s cannot be passed by reference
- %s(): argument #%d%s%s%s could not be passed by reference
- an iterator cannot be used with foreach by reference
- cannot acquire reference to $globals
- cannot acquire reference to readonly property %s::$%s
- cannot assign %s to reference held by property %s::$%s of type %s
- cannot assign reference to non referenceable value
- cannot create reference to property %s::$%s
- cannot indirectly modify readonly property %s::$%s
- cannot pass parameter %d by reference
- cannot take reference of a nullsafe chain
- cannot use result of built in function in write context
- cannot use variable $%s twice
- indirect modification of %s::$%s is not allowed
- only variable references should be returned by reference
- only variable references should be yielded by reference
- only variables can be passed by reference
- only variables should be passed by reference
- parameter %d must be passed by reference
- recursion detected
- returning by reference from a void function is deprecated
- [syntax error, unexpected ';', expecting ''
- syntax error, unexpected token “&”, expecting end of file
- syntax error, unexpected token “&”
- [syntax error, unexpected token “;”, expecting “ >“ or “? >” or ““
- [syntax error, unexpected token “;”, expecting “ >“ or “? >” or “{” or ““
- reflection
- attribute class “%s” not found
- calling %ps() for static method %ps::%ps() does not need an object parameter
- calling %ps() with a 1st argument which is not null or an object is deprecated
- calling %ps() with a given object that is not an instance of the class this property was declared in is deprecated
- calling %ps() with a single argument is deprecated
- calling reflectionmethod::__construct() with 1 argument is deprecated,
- cannot be null when argument #1 ($objectormethod) is an object
- cannot use %s() on dynamic property %ps::$%ps
- cannot use %s() on internal class %ps
- cannot use %s() on static property %ps::$%ps
- cannot use %s() on virtual property %ps::$%ps
- case %s::%s does not exist
- class %s does not have a property named %s
- function %ps() does not exist
- method %ps::%ps() does not exist
- must be a valid method name
- reflectionclass::getconstant() for a non existent constant is deprecated,
- reflectionproperty::getdefaultvalue() for a property without a default value is deprecated,
- regex
- relative-types
- relaxed-syntax
- reserved-name
- cannot use “%s “ as %s
- syntax error, unexpected token “::”, expecting “:”
- syntax error, unexpected token “final”, expecting “(”
- [syntax error, unexpected token “public”, expecting “]”](messages/syntax-error,-unexpected-token-public,-expecting-].html)
- using “_” as %s is deprecated since 8.4
- resource
- return
- %s%s%s(): return value must be of type %s, %s returned
- %s(): never returning %s must not implicitly return
- %s(): never returning function must not implicitly return
- a %s with return type must return a value
- a function with return type must return a value
- a never returning %s must not return
- a never returning method must not return
- a void %s must not return a value
- destructors cannot declare a return type
- generators cannot return values using “return”
- never returning function must not implicitly return
- only variable references should be returned by reference
- returning a value from a constructor is deprecated
- returning a value from a destructor is deprecated
- return-type
- %s%s%s(): return value must be of type %s, %s returned
- %s::%s(): return type must be %s when declared
- %s::__tostring() must return a string
- a %s with return type must return a value
- a function with return type must return a value
- constructor %s::%s() cannot declare a return type
- division of php_int_min by 1 is not an integer
- method %s::%s() cannot declare a return type
- method %s::__construct() cannot declare a return type
- return value of %s%s%s() must %s%s%s, %s%s returned
- returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero
- returning bool from comparison function is deprecated
- returning null from %s::__debuginfo() is deprecated, make the return type non nullable and return an empty array instead
- rewind
- rounding
- scalar-type
- scandir-sort-order
- scope
- call to %s %s::%s() from global scope
- cannot access parent:: when current class scope has no parent
- cannot bind an instance to a static closure, this will be an error in php 9
- cannot bind an instance to a static closure
- cannot bind method %s::%s() to object of class %s, this will be an error in php 9
- cannot modify readonly property %s::$%s
- cannot rebind scope of closure created from function, this will be an error in php 9
- cannot rebind scope of closure created from method, this will be an error in php 9
- cannot unbind $this of closure using $this, this will be an error in php 9
- cannot unbind $this of method, this will be an error in php 9
- the $context parameter has no effect for finfo_buffer()
- use of “parent” in callables is deprecated
- use of “self” in callables is deprecated
- use of “static” in callables is deprecated
- scope-resolution-operator
- cannot use “::class “ on %s
- syntax error, unexpected '::', expecting '('
- syntax error, unexpected '::' (t_paamayim_nekudotayim), expecting ';' or ','
- [syntax error, unexpected token “:”, expecting “]”](messages/syntax-error,-unexpected-token-:,-expecting-].html)
- [syntax error, unexpected token “::”, expecting “]”](messages/syntax-error,-unexpected-token-::,-expecting-].html)
- self
- self-reference
- semicolon
- case statements followed by a semicolon (;) are deprecated, use a colon (:) instead
- syntax error, unexpected end of file
- [syntax error, unexpected token “,”, expecting “]”](messages/syntax-error,-unexpected-token-,,-expecting-].html)
- syntax error, unexpected token “;”, expecting “)”
- [syntax error, unexpected token “;”, expecting “]”](messages/syntax-error,-unexpected-token-;,-expecting-].html)
- syntax error, unexpected token “use”, expecting “,” or “;”
- separator
- serializable
- serialization
- %s “ is returned from __sleep() multiple times
- %s implements the serializable interface
- cannot deserialize arrayobject with iterator class %s; this class is not derived from arrayiterator
- error at offset %zd of %zd
- extra data starting at offset %d of %zd bytes
- serialization of %s is not allowed, override __serialize() and __unserialize() to implement it
- the pdo::fetch_serialize mode is deprecated
- unserialization of %s is not allowed, override __serialize() and __unserialize() to implement it
- unserializing the 's' format is deprecated
- session
- class %s implementing sessionhandlerinterface is missing the create_sid() method which will be required in php 9.0
- class %s implementing sessionhandlerinterface is missing the validateid() method which will be required in php 9.0
- disabling session.use_only_cookies ini setting is deprecated
- enabling session.use_trans_sid ini setting is deprecated
- providing an object to argument #1 ($sessionhandler) which does not have the create_sid() method defined is deprecated
- providing an object to argument #1 ($sessionhandler) which does not have the validateid() method defined is deprecated
- providing individual callbacks instead of an object implementing sessionhandlerinterface is deprecated
- session callback must have a return value of type bool, %s returned
- session.sid_bits_per_character ini setting is deprecated
- session.sid_length ini setting is deprecated
- usage of session.referer_check ini setting is deprecated
- usage of session.trans_sid_hosts ini setting is deprecated
- usage of session.trans_sid_tags ini setting is deprecated
- shell_exec
- short-assignation
- short-tag
- shutdown
- signature
- silent
- single-quote
- snmp
- soap
- socket
- socket-options
- must be of type string when argument #3 ($option) is fil_attach or fil_detach, %s given
- must be of type string when argument #3 ($option) is so_acceptfilter, %s given
- must be of type string when argument #3 ($option) is so_bindtodevice, %s given
- must be of type string when argument #3 ($option) is tcp_congestion, %s given
- must be of type string when argument #3 ($option) is tcp_function_blk, %s given
- sodium
- sort
- spaceship
- spl
- splobjectstorage
- sqlite3
- square-bracket
- [syntax error, unexpected token “]”](messages/syntax-error,-unexpected-token-].html)
- [unclosed '(' does not match ']'](messages/unclosed-\q\-does-not-match-\]\.html)
- [unclosed '(' on line %s does not match ']'](messages/unclosed-\q\-on-line-ps-does-not-match-\]\.html)
- [unclosed ''
- unmatched '}'
- ssl
- static
- “static::” is not allowed in compile time constants
- ' %s' is an invalid class name
- accessing static property %s::$%s as non static
- bad class name in the catch statement
- cannot access static:: when no class scope is active
- cannot make non static method %s::%s() static in class %s
- cannot make static method %s::%s() non static in class %s
- cannot redeclare %s%s::$%s as %s%s::$%s
- cannot redeclare %s property %s::$%s as %s %s::$%s
- cannot use(…) variables in constant expression
- cannot use “%s” when no class scope is active
- cannot use “static” when no class scope is active
- cannot use 'static' as constant modifier
- cannot use 'static' as method modifier
- cannot use the %s modifier on a %s
- cannot use the static modifier on a parameter
- closures in constant expressions must be static
- method %s::%s() must be static
- multiple static modifiers are not allowed
- non static method %s::%s() cannot be called statically
- non static method %s::%s() should not be called statically
- static property %s::$%s cannot be readonly
- syntax error, unexpected token “(”, expecting “::”
- use of “parent” in callables is deprecated
- use of “self” in callables is deprecated
- use of “static” in callables is deprecated
- static-expression
- static-property
- access to undeclared static property %s::$%s
- accessing static trait property %s::$%s is deprecated
- attempt to unset static property %s::$%s
- calling %ps() with a 1st argument which is not null or an object is deprecated
- calling %ps() with a single argument is deprecated
- cannot declare hooks for static property
- static-variable
- stdclass
- stream
- stream-error-handling
- stream-filter
- must be a concrete class
- passing an object for filter parameters for %s is deprecated, call get_object_vars() first instead
- passing an object for filter parameters for bzip2.compress is deprecated, call get_object_vars() first instead
- passing an object for filter parameters for bzip2.decompress is deprecated, call get_object_vars() first instead
- stream filter %s is never seekable
- stream filter %s is seekable only to start position
- stream filter seeking for %s failed
- using more than “ zend_long_fmt “ filters in a php: filter url is deprecated
- stream_context_create
- strict_types
- can only flip string and integer values, entry skipped
- cannot assign %s to property %s::$%s of type %s
- cannot use %s as value for class constant %s::%s of type %s
- implicit conversion from float %.*h to int loses precision
- must be of type %s, %s given
- object of class %s could not be converted to %s
- return value of %s%s%s() must %s%s%s, %s%s returned
- strict_types declaration must be the very first statement in the script
- strict_types declaration must be
- strict_types declaration must have 0 or 1 as its value
- strict_types declaration must not
- syntax error, unexpected token “=”, expecting identifier
- syntax error, unexpected token “namespace”
- unsupported declare '%s'
- string
- [] operator not supported for strings
- a non numeric value encountered
- a non well formed numeric value encountered
- argument #2 ($end) must be a single byte string if
- array and string offset access syntax with curly braces is deprecated
- array and string offset access syntax with curly braces is no longer supported
- cannot assign an empty string to a string offset
- cannot use string offset as an array
- cannot use string offset as an object
- decrement on empty string is deprecated as non numeric
- decrement on non numeric string has no effect and is deprecated
- empty delimiter
- illegal function name
- illegal string offset
- increment on non alphanumeric string is deprecated
- increment on non numeric string is deprecated, use str_increment() instead
- only the first byte will be assigned to the string offset
- providing a string that is not one byte long is deprecated. use ord($str[0]) instead
- providing a value not in between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. the value used will be constrained using %% 256
- [syntax error, unexpected '', expecting ';' or ','
- syntax error, unexpected identifier “%s”, expecting “,” or “;”
- syntax error, unexpected string content
- unbacked enum %s cannot be converted to a string
- uninitialized string offset
- using ${var} in strings is deprecated, use {$var} instead
- value for class is not a string
- string-increment
- stringable
- superglobal
- supertype
- switch
- '%s' not in the 'loop' or 'switch' context
- case statements followed by a semicolon (;) are deprecated, use a colon (:) instead
- switch statements may only contain one default clause
- syntax error, unexpected ','
- syntax error, unexpected token “break”
- syntax error, unexpected token “continue”
- syntax error, unexpected token “match”
- temporary-expression
- ternary
- [syntax error, unexpected token “:”, expecting “]”](messages/syntax-error,-unexpected-token-:,-expecting-].html)
- syntax error, unexpected token “?”
- unparenthesized `a ? b : c ? d : e` is not supported.
- unparenthesized `a ? b : c ?: d` is not supported.
- unparenthesized `a ?: b ? c : d` is not supported.
- throw
- throwable
- tick
- tls
- trailing-comma
- trait
- %s and %s define the same constant (%s) in the composition of %s. however, the definition differs and is considered incompatible. class was composed
- %s and %s define the same hooked property ($%s) in the composition of %s. conflict resolution between hooked properties is currently not supported. class was composed
- %s and %s define the same property ($%s) in the composition of %s. however, the definition differs and is considered incompatible. class was composed
- %s cannot use %s it is not a trait
- a precedence rule was defined for %s::%s but this method does not exist
- accessing static trait property %s::$%s is deprecated, it should only be accessed on a class using the trait
- accessing static trait property %s::$%s is deprecated
- an alias was defined for method %s(), which exists in both %s and %s. use %s::%s or %s::%s to resolve the ambiguity
- call to undefined method %s::%s()
- calling static trait method %s::%s is deprecated
- cannot access trait constant %s::%s directly
- cannot apply #[allowdynamicproperties] to trait %s
- cannot instantiate trait %s
- cannot redeclare %s %s (previously declared in %s:%d)
- cannot redeclare %s %s
- cannot use “abstract “ as method modifier in trait alias
- cannot use “static “ as method modifier in trait alias
- cannot use trait %s
- cannot use traits inside of interfaces. %s is used in %s
- class %s cannot use %s it is not a trait
- class %s is not a trait
- could not find trait %s
- enum “%s” not found
- enum %s cannot include properties
- failed to evaluate a trait precedence (%s). method of trait %s was defined to be excluded multiple times
- get_called_class() must be called from within a class
- inconsistent insteadof definition. the method %s is to be used from %s
- readonly class %s cannot use trait with a non readonly property %s::$%s
- required trait %s wasn't added to %s
- syntax error, unexpected fully qualified name “%s”, expecting “function”
- syntax error, unexpected token “private”, expecting “{”
- syntax error, unexpected token “protected”, expecting “{”
- syntax error, unexpected token “public”, expecting “{”
- the modifiers of the trait method %s() are changed, but this method does not exist. error
- trait “%s” not found
- trait %s used by %s is deprecated%s
- trait method %s::%s has not been applied as %s::%s
- traits cannot have constants
- traversable
- true
- try-catch
- syntax error, unexpected ')', expecting '|' or variable (t_variable)
- [syntax error, unexpected token “#“, expecting “)”
- try-finally
- type
- %s“ will be interpreted as a class name. did you mean “%s”? write “%s”%s to suppress this warning
- %s(): implicitly marking parameter $%s as nullable is deprecated, the explicit nullable type must be used instead
- %s(): implicitly marking parameter $%s as nullable is deprecated, the explicit nullable type
- %s(): return value of the authorizer callback must be of type int, %s returned
- %s(): return value of the collation callback must be of type int, %s returned
- %s “ is not a supported builtin type and will be interpreted as a class name. write “ %s “%s to suppress this warning
- %s “ will be interpreted as a class name. did you mean “%s “? write “ %s “%s to suppress this warning
- %s is not supported on type %s
- argument #%d ($%s) must be of type %s, %s given
- argument #1 ($start) must be a single byte string if
- cannot assign %s to class constant %s::%s of type
- cannot assign %s to property %s::$%s of type %s
- cannot assign %s to reference held by property %s::$%s of type %s
- cannot auto initialize an array inside property %s::$%s of type %s
- cannot use “%s” as a type name as it is reserved
- cannot use %s as default value for parameter $%s of type %s
- cannot use %s as default value for property %s::$%s of type %s
- cannot use %s as value for class constant %s::%s of type %s
- cannot use “%s “ as %s as it is reserved
- default value for parameters with a %s type can only be %s or null
- duplicate type %s is redundant
- implicit conversion from float %.*h to int loses precision
- implicit conversion from float string “%s “ to int loses precision
- is an invalid class name
- must be a valid comparison operator
- must be between 1 and 7
- must be of type %s, %s given
- needle is not a string or an integer
- never can only be used as a standalone type
- readonly property %s::$%s must have type
- syntax error, unexpected token “?”
- type %s contains both object and a class type
- type mixed can only be used as a standalone type
- type mixed cannot be marked as nullable since mixed already includes null
- type of %s::%s must be compatible with %s::%s of type %s
- using array_key_exists() on objects is deprecated.
- void can only be used as a standalone type
- type-juggling
- typed-property
- typo
- underscore
- unicode
- uninitialized
- union-type
- unitenum
- unpacking
- cannot combine named arguments and argument unpacking
- cannot combine partial application and unpacking
- cannot use argument unpacking after named arguments
- cannot use positional argument after argument unpacking
- cannot use positional argument after named argument
- cannot use unpacking in attribute argument list
- keys must be of type int|string during array unpacking
- unserialize
- unset
- attempt to unset static property %s::$%s
- can't use function return value in write context
- can't use method return value in write context
- cannot unset $this
- cannot unset readonly property %s::$%s
- cannot unset string offsets
- cannot use [] for unsetting
- object not initialized
- the (unset) cast is deprecated
- the (unset) cast is no longer supported
- the sqlite3 object has not been correctly initialised or is already closed
- uri
- cannot set a userinfo without having a host
- failed to update the scheme
- failed to update the userinfo
- must be a list of %s
- the specified %s is malformed%s%s%s
- the specified %s is malformed
- the specified scheme is malformed
- the specified uri is malformed
- the specified url cannot have password
- the specified url cannot have port
- the specified url cannot have username
- the specified userinfo is malformed
- uri-class
- uri-extension
- use
- cannot use variable $%ps twice
- syntax error, unexpected identifier “%s”, expecting “,” or “;”
- syntax error, unexpected token “;”, expecting identifier
- syntax error, unexpected token “as”
- syntax error, unexpected token “use”, expecting “{”
- syntax error, unexpected token “use”
- the use statement with non compound name '%s'
- use-alias
- use-trait
- uuencode
- validation
- argument #%d must be greater than or equal to 0
- argument #1 ($value) must contain at least one element
- cannot use multiple endian options
- cannot use multiple word order options
- filter validation failed: filter %s not satisfied by %s
- filter validation failed: not an array (got %s)
- filter validation failed: object of type %s has no __tostring() method
- must be a callable, null given
- must be a multiple of argument #2 ($word_size)
- must be greater than or equal to 1
- passing false or null is deprecated since 8.4
- passing the encoding as third parameter is deprecated. use an explicit zero offset
- security level must be one of “noauthnopriv”, “authnopriv”, or “authpriv
- security protocol must be one of “aes128”, or “aes e_error
- security protocol must be one of “des”, “aes128”, or “aes e_error
- unknown filter with id
- value
- valueerror
- var_dump
- variable
- variable-variable
- variadic
- virtual-property
- visibility
- access level to %s::$%s must be %s (as in class %s)%s
- access level to %s::%s must be %s (as in %s %s)%s
- access type for interface constant %s::%s must be public
- access type for interface method %s::%s() must be public
- call to %s %s::%s() from invalid
- call to %s method %s::%s() from %s%s
- cannot access %s const %s::%s
- cannot access %s constant %s::%s
- cannot access %s property %s::$%s
- multiple access type modifiers are not allowed
- private methods cannot be final as they are never overridden by other classes
- property in interface cannot be protected or private
- set access level of %s::$%s must be %s (as in class %s)%s
- syntax error, unexpected token “public”
- the magic method %s::%s() must have public visibility
- trying to invoke %s method %s::%s() from scope %s
- void
- %s(): returning by reference from a void function is deprecated
- a function with return type must return a value
- a void %s does not return a value
- a void %s must not return a value
- class constant %s::%s cannot have type %s
- property x::$p cannot have type void
- returning by reference from a void function is deprecated
- void can only be used as a standalone type
- void cannot be used as a parameter type
- void-cast
- the return value of function %s() should either be used or intentionally ignored by casting it as (void)%s code
- the return value of function %s() should either be used or intentionally ignored by casting it as (void)%s
- the return value of method %s::%s() should either be used or intentionally ignored by casting it as (void)%s
- weakmap
- weakreference
- while
- wrapper-stream
- writable
- write-context
- writing
- yield
- cannot use “yield from “ inside a by reference generator
- foreach() argument must be of type array|object
- making a constructor a generator is deprecated
- making a destructor a generator is deprecated
- only variable references should be yielded by reference
- the “generator” class is reserved for internal use and cannot be manually instantiated
- the “yield “ expression can only be used inside a function
- the each() function is deprecated. this message will be suppressed on further calls
- yield-from
- zip
- zlib
Index
“static::” is not allowed in compile-time constants
Description
The static keyword is a relative class identifier. It is resolved at execution time, depending on which class is calling the expression.
In the case of constants, such as class constants or default values in parameters or properties, they must be known at compile time, to be usable as soon as the application start.
On the other hand, self and parent are valid relative values, as there can only be one.
Example
<?php
interface I {
const C = static::NAME;
}
class X {
public $c = static::name;
function foo($c = static::NAME) {}
}
?>
Alternatives
- Use self::.
- Set the value dynamically, at execution time.
$GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax
Description
Since PHP 8.1, it is not possible to replace $GLOBALS entirely. It has to be modified at the index level, and not as a whole.
The error message is a bit misleading: on the spot operations with index are still possible, such as ++ or array_map or array_walk.
This means that $GLOBALS['index'] may be written, while $GLOBALS cannot.
$GLOBALS['index'] and $GLOBALS can still be used for reading.
Example
<?php
$GLOBALS = [];
// That is also OK
$x = 3;
echo $GLOBALS['x']++;
?>
Alternatives
- Make a loop over
$GLOBALSand update each index individually. - Avoid updating
$GLOBALS: keep a copy in another variable.
%d arguments are required, %d given
Description
The actual number of arguments of the function is commanded by the first argument: there must be an extra argument for every %s in that argument. In the illustration code, there are 4 expected arguments, on top of the first one, and only 2 arguments, including the first one.
This error message is related to the PHP native functions printf(), vprintf(), sprintf(), fprintf(), vfprintf().
Example
<?php
// count() has one or two arguments
count($array, $recursive, $tooMany);
// printf()'s number of arguments depends on the first one
printf('%s %s %s %s', $variable);
?>
Literal Examples
- 4 arguments are required, 2 given
Alternatives
- Reduce the number of %s in the first argument.
- Add the missing argument in the function call.
- Replace the %s by %%s.
In previous PHP versions, this error message used to be :ref:too-few-arguments.
%s“ returned as member variable from __sleep() but does not exist
Description
The magic method __sleep must return a list of properties of the current class. Any private property defined in the parent are excluded.
The returned array should be an array of strings, with the name of each property, without the initial $ sign.
Example
<?php
class X {
public $p = 1;
function __sleep() {
return ['p', 'q', []];
}
}
serialize(new X);
?>
Literal Examples
- “q” returned as member variable from __sleep() but does not exist
- “Array” returned as member variable from __sleep() but does not exist
Alternatives
- Remove all unknown properties.
- Check the format of the property name, and remove the
$sign. - Check the visibility of the properties: private properties from parents are excluded.
Related error messages
- sleep-should-return-an-array-only-containing-the-names-of-instance-variables-to-serialize.
- %s::__sleep()-should-return-an-array-only-containing-the-names-of-instance-variables-to-serialize
“%s” will be interpreted as a class name. Did you mean “%s”? Write “%s”%s to suppress this warning
Description
PHP offers several native type, such as bool or int. These names may also be confused with boolean and integer, which are not PHP native types. They are valid for custom code usage, including creating classes or interfaces. To avoid such confusion, PHP emits this error message to make sure that integer is confused with int.
boolean, for bool, integer, for int, double, for float, and resource, for \resource, are all subjects to this error.
Example
<?php
function foo() : boolean {}
?>
Literal Examples
- “boolean” will be interpreted as a class name. Did you mean “bool”? Write “\boolean” to suppress this warning
- “resource” will be interpreted as a class name. Did you mean “\resource”?
Alternatives
- Use the PHP native type.
- Create a
usestatement for the actual type. - Add the initial
\with this name.
%s%s%s() does not accept unknown named parameters
Description
printf() and sprintf() take a format string as first argument, and an arbitrary number of arguments after that. Those extra arguments are only positional. Hence, it is not possible to use ellipsis on an array with string keys.
This error also applies to array functions that handles the parameters as a list: in a list, the names are not important.
Example
<?php
printf('%s', ...['a' => 2]);
array_merge([1, 2], a: [3, 4]);
array_intersect([1, 2], a: [3, 4]);
array_diff_key([1, 2], [3, 4], a: [5, 6]);
?>
Literal Examples
- printf() does not accept unknown named parameters
- array_merge() does not accept unknown named parameters
- array_diff_key() does not accept unknown named parameters
- array_intersect() does not accept unknown named parameters
Alternatives
- Use array_values() on the array, before the ellipsis.
%s%s%s(): Argument #%d%s%s%s must be passed by reference, value given
Description
When a parameter is set to be passed by reference, there is a & character before its name. In that case, the argument must be a data container, such as a variable, a property, a static property, an array index, but it cannot be a literal value, a constant, or the result of an expression.
Example
<?php
function foo(&$a) {}
// invalid cases
foo(1);
foo(1 + 2);
const A = 1;
foo(A);
class X {
const B = 2;
}
foo(X::B);
?>
Literal Examples
- foo(): Argument #1 ($a) must be passed by reference, value given
Alternatives
- Store the value in a variable and passe the variable.
- Remove the reference in the method signature.
Related error messages
In previous PHP versions, this error message used to be :ref:parameter-%d-must-be-passed-by-reference.
%s%s%s(): Return value must be of type %s, %s returned
Description
This error appears when calling a method with a return value, but without an explicit return statement. This means that when the method reachs its end, eventually, it will end without a returned value. Yet, the method signature declares that it will return a specific type.
The error is also emitted for property hooks, in particular the get one: its return type is the same as the type of the property.
A different error message is returned when an empty return statement is used.
Example
<?php
function foo() : int {}
class X {
public int $p {
// The type of the property is the return type of the hook
get => [$this->p];
}
}
?>
Literal Examples
- foo(): Return value must be of type int, none returned
Alternatives
- Add a return call, with a valid value.
- Remove the return type.
- Add a null to the return type, and return it (void is not possible with another type).
Related error messages
%s() expects exactly 0 arguments, %d given
Description
The mentioned method does not accept any argument, and reports it.
This is the case of func_num_args(), get_called_class(), error_get_last(), json_last_error_msg(), mysqli_connect_errno(), mysqli_get_links_stats(), mysqli_connect_error(), DOMDocumentFragment::__construct(), XSLTProcessor::hasExsltSupport(), etc. It is also the case for the property hook get().
Example
<?php
function dump_error(callable $callable) {
try {
var_dump($callable());
} catch (Throwable $e) {
var_dump($e->getMessage());
}
}
?>
Alternatives
- Remove all arguments when calling such method.
%s() has been disabled for security reasons
Description
The function mentioned in the message was disabled with the disable_functions directive. It is not possible to use it, nor to redefine it.
Example
<?php
shell_exec('ls -la');
?>
Literal Examples
- shell_exec() has been disabled for security reasons
Alternatives
- Remove the function from the
disable_functionsdirective. - Find another function with a similar feature.
In more recent PHP versions, this error message is now :ref:call-to-undefined-function-%s().
%s(): Argument #%d%s%s%s cannot be passed by reference
Description
Passing a literal value, a constant or $GLOBALS where a reference is requested leads to this error.
For literal and constants, global or class, this is due to the value that can’t be modified. It must be put in a variable first.
For $GLOBALS, it is to prevent modifications of its values. It makes the error message a bit surprising. This doesn’t apply to other PHP variables.
A reference argument expected a variable, a property, static or not, or an array element. Usually, a variable is the best choice.
Example
<?php
function foo(&$arg) {}
// passing a literal
foo([]);
// passing $GLOBALS
foo($GLOBALS);
// trying to trim spaces on all GLOBALS
array_walk( $GLOBALS, trim(...));
?>
Literal Examples
- array_walk(): Argument #1 $GLOBALS cannot be passed by reference
Alternatives
- Copy
$GLOBALSto a variable and pass this variable. - Copy the constant value to a variable and pass this variable.
- Copy the literal value to a variable and pass this variable.
Related error messages
In previous PHP versions, this error message used to be :ref:cannot-pass-parameter-%d-by-reference.
%s(): Argument #%d%s%s%s could not be passed by reference
Description
Methods arguments may be passed by value or by reference. The first one is the default behavior, and the second one is optional: it is identified with the &, before the name of the argument.
When an argument is passed by reference, the calling context passes a variable, and conserves a handle to the modified variable after the execution of the method. The handle points to a data container, such as a variable, a property, a static property or a array item.
When passing literal values or constants, global or class, this error is emitted, as there cannot be a reference to them. They can only be passed by value.
This error message is emitted when a value is returned, and feed into a reference argument.
Example
<?php
function foo(int &$int) {
// doSomething
}
foo(-3);
?>
Literal Examples
- foo(): Argument #3 ($int) could not be passed by reference
Alternatives
- Store the value in a variable, and pass the variable to the method.
- Remove the reference from the called method signature.
Related error messages
In previous PHP versions, this error message used to be :ref:%s():-argument-#%d%s%s%s-cannot-be-passed-by-reference.
Implicitly marking parameter $%s as nullable is deprecated, the explicit nullable type must be used instead
Description
Until PHP 8.4, it is possible to use a default value of null, on a parameter that is not nullable. This special situation makes the parameter nullable: it may be omitted, or explicitly passed as null. This is a hidden type, as the null type is not explicit, yet it is fully usable.
In PHP 8.4, this is not possible anymore. For consistency reasons, the type must be explicitly displayed. Until then, it was silent.
Example
<?php
function foo(string $s = null) {}
class X {
function foo(string $s = null) {}
}
?>
Literal Examples
- foo(): Implicitly marking parameter $s as nullable is deprecated, the explicit nullable type must be used instead
- X::bar(): Implicitly marking parameter $s as nullable is deprecated, the explicit nullable type must be used instead
Alternatives
- Add
?to the type. - Add
null|to the type. - Use a default value in the range of the specified type.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See implicitNullable
%s(): Implicitly marking parameter $%s as nullable is deprecated, the explicit nullable type
Description
Before union types existed, PHP let a scalar or class-typed parameter become nullable simply by giving it a default value of null, e.g. function foo(int $x = null). The type itself still reads as int, but the engine silently widened it to also accept null, which is easy to miss when skimming a signature.
As of PHP 8.4, relying on this implicit widening emits a deprecation notice; the parameter still behaves as nullable for now, but the behaviour is expected to be dropped in a future version, at which point only an explicit nullable type would accept null.
Example
<?php
// $x has no type-level '?', but a default of null makes it
// implicitly nullable -- this is the deprecated PHP 5 style.
function foo(int $x = null) {
var_dump($x);
}
foo(1);
?>
Literal Examples
- foo(): Implicitly marking parameter $x as nullable is deprecated, the explicit nullable type must be used instead
Alternatives
- Write the nullable type explicitly with a leading question mark: function foo(?int $x = null).
- Or use an explicit union type: function foo(int|null $x = null).
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s(): never-returning %s must not implicitly return
Description
An implicit return is a method reaching the end of its body block, and ending its execution without an explicit return statement. In fact, PHP executes an implicit return statement, et returns the value NULL. In the case of a method, whose return type is never, this should not happen. There must be a call to die, exit, or throw, or any other mean to prevent this function to reach its normal ending.
This error is only reported at execution time.
Example
<?php
function myDeath(): never {
if (rand(0, 1)) {
die();
}
}
myDeath();
?>
Literal Examples
- myDeath(): never-returning function must not implicitly return
Alternatives
- Add a
dieorexitbefore the end of the method. - Add a
throwbefore the end of the method. - Add an infinite loop in the method.
In previous PHP versions, this error message used to be :ref:%s():-never-returning-function-must-not-implicitly-return.
%s(): never-returning function must not implicitly return
Description
A function with the never return type must return anything. This means no return keyword, but also, no possibility to reach the end of the method, as it would trigger automatically a return null;.
Example
<?php
function foo(): never {
if (true) {
throw new Exception('bad');
}
}
foo();
?>
Literal Examples
- foo(): never-returning function must not implicitly return
Alternatives
- Add a
dieat the end of the method. - Add a
throwat the end of the method.
In more recent PHP versions, this error message is now :ref:%s():-never-returning-%s-must-not-implicitly-return.
%s(): Optional parameter $%s declared before required parameter $%s
Description
A parameter with a default value is only truly optional when every parameter that follows it also has one. PHP has always allowed writing an optional parameter before a required one, but silently converted the earlier one into a required parameter as soon as it was actually called – its default value was never reachable. This has been deprecated since PHP 8.0, and, since PHP 8.1, is no longer just a notice: such a parameter is always treated as required – even when called with named arguments – so omitting it raises an ArgumentCountError instead of falling back to the default.
This particular wording, naming the function, is the current one: PHP 8.4 reworded a batch of parameter- and return-value-related deprecations to prefix the message with FunctionName(): , matching the style already used for most other deprecations.
Example
<?php
// $a looks optional (it has a default), but $b after it has none,
// so $a can no longer really be left out.
function foo($a = 1, $b) {
return $a + $b;
}
var_dump(foo(2, 3));
?>
Literal Examples
- foo(): Optional parameter $a declared before required parameter $b is implicitly treated as a required parameter
Alternatives
- Give the earlier parameter’s default to every parameter that needs one, and move genuinely required parameters first.
- If the default is only there for backward compatibility, make the parameter nullable (?Type $a = null) and document that null is not a meaningful value on its own.
- Use named arguments at the call site instead of relying on positional defaults.
Related error messages
In previous PHP versions, this error message used to be :ref:optional-parameter-$%s-declared-before-required-parameter-$%s-is-implicitly-treated-as-a-required-parameter.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.4, the same deprecation was worded “Optional parameter $a declared before required parameter $b is implicitly treated as a required parameter”, without the leading “FunctionName(): “ prefix. Before PHP 8.1, PHP 8.0 used a different wording still: “Required parameter $b follows optional parameter $a”.](Prior to PHP 8.4, the same deprecation was worded “Optional parameter $a declared before required parameter $b is implicitly treated as a required parameter”, without the leading “FunctionName(): “ prefix. Before PHP 8.1, PHP 8.0 used a different wording still: “Required parameter $b follows optional parameter $a”.)
%s(): Passing null to parameter #%d (%s) of type string is deprecated
Description
PHP has been enforcing non-null parameters to PHP native functions. This started in PHP 8.1. Until then, it was possible to use NULL everywhere, and it would have been cast to an empty string or 0. Nowadays, it is a deprecation.
This applies to all PHP native functions, such as, and not limited to: strtolower(), strip_tags(), trim(), addslashes(), strlen(), rtrim(), etc.
Example
<?php
strlen(null);
?>
Literal Examples
- strlen(): Passing null to parameter #1 ($string) of type string is deprecated
- dir(): Passing null to parameter #1 ($path) of type string is deprecated
Alternatives
- Check the value before calling the function.
- Use
??to convert the null into a suitable default value.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See dirWithNull
%s(): Return value of the authorizer callback must be of type int, %s returned
Description
Pdo\Sqlite::setAuthorizer() installs a userland callback that SQLite consults before executing most operations, such as creating a table, reading a column, or attaching a database. The callback receives the action being authorized plus up to four contextual strings, and it must return one of the integer constants Pdo\Sqlite::OK, Pdo\Sqlite::DENY or Pdo\Sqlite::IGNORE.
As of PHP 8.5, PDO strictly checks the type of the returned value. If the callback returns anything that is not an int – a string, a boolean, null, or simply nothing because a return statement was forgotten on some branch – a TypeError is thrown instead of the value being silently coerced.
The equivalent method on the standalone SQLite3 extension, SQLite3::setAuthorizer(), enforces the same strict check.
Example
<?php
$pdo = new Pdo\Sqlite('sqlite::memory:');
$pdo->setAuthorizer(function (int $action, ?string $arg1, ?string $arg2, ?string $arg3, ?string $arg4) {
// Forgot to return an int constant -- this should return Pdo\Sqlite::OK, ::DENY or ::IGNORE
return $action === Pdo\Sqlite::CREATE_TABLE ? 'allow' : 'deny';
});
$pdo->exec('CREATE TABLE test (id INTEGER)');
?>
Literal Examples
- Pdo\Sqlite::setAuthorizer(): Return value of the authorizer callback must be of type int, string returned
Alternatives
- Always return one of the constants
Pdo\Sqlite::OK,Pdo\Sqlite::DENYorPdo\Sqlite::IGNOREfrom the callback. - Add an explicit
returnstatement on every branch of the callback, including the default one. - Declare an
intreturn type on the callback so mismatches are caught as soon as they are written.
Related error messages
- %s():-return-value-of-the-collation-callback-must-be-of-type-int,-%s-returned
- the-sqlite3-object-has-not-been-correctly-initialised-or-is-already-closed
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s(): Return value of the collation callback must be of type int, %s returned
Description
Pdo\Sqlite::createCollation() registers a userland function to be used as an SQL collating sequence. Like strcmp(), the callback receives two strings and must return a negative, zero, or positive int depending on whether the first string sorts before, the same as, or after the second one.
As of PHP 8.5, the return value of the callback is strictly checked. Returning anything that is not an int – for instance a bool from a <=> comparison used incorrectly, or nothing at all because of a missing return – raises a TypeError, instead of the previous behavior where a non-int value silently made the collation undefined.
The legacy PDO::sqliteCreateCollation() method, kept for backward compatibility, is affected by the same strict check.
Example
<?php
$pdo = new Pdo\Sqlite('sqlite::memory:');
$pdo->createCollation('natcmp', function (string $a, string $b) {
// strcmp() convention expected -- negative, zero or positive int
return $a <=> $b ? strnatcasecmp($a, $b) <=> 0 : 0;
});
$pdo->exec('CREATE TABLE test (name TEXT)');
$pdo->query('SELECT name FROM test ORDER BY name COLLATE natcmp');
?>
Literal Examples
- Pdo\Sqlite::createCollation(): Return value of the collation callback must be of type int, bool returned
Alternatives
- Make sure the callback always returns an
int, following thestrcmp()convention of negative/zero/positive. - Use the spaceship operator
<=>directly on the two strings, or on a derived comparable value, since it already returns anint. - Declare an
intreturn type on the callback to catch a wrong return value while writing it.
Related error messages
- %s():-return-value-of-the-authorizer-callback-must-be-of-type-int,-%s-returned
- the-sqlite3-object-has-not-been-correctly-initialised-or-is-already-closed
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s(): Returning by reference from a void function is deprecated
Description
The void type means that the function is not returning anything. So, it doesn’t matter if that nothing is returned by value or by reference.
If the returned value is, nonetheless, collected, it will be null in any case.
Example
<?php
function &foo(): void { }
?>
Literal Examples
- foo(): Returning by reference from a void function is deprecated
Alternatives
- Remove the reference of the function.
- Remove the type void, and return an actual value.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See return_reference_on_void.php
%s" is not a supported builtin type and will be interpreted as a class name. Write "\%s"%s to suppress this warning
Description
resource looks like it should be a builtin type, since it is one of the values returned by gettype(), but it was never turned into an actual type declaration: there is no way to name a specific kind of resource (file handle, curl handle…) in a type.
Since resource is not a reserved word, PHP does not reject it: it silently treats it as the name of a class or interface called resource, which almost never exists, and any call with an actual resource argument then fails with a TypeError.
To help catch the mistake, the compiler emits this warning as soon as it sees the bare word resource in a type position and no class or interface with that name has been imported: it assumes a builtin type was intended. The comparison is case-sensitive, so a capitalized Resource – more plausible as a genuine class name – does not trigger it.
Example
<?php
function readFile(resource $handle): void {
fclose($handle);
}
?>
Literal Examples
- “resource” is not a supported builtin type and will be interpreted as a class name. Write “\resource” to suppress this warning
Alternatives
- Remove the type declaration, or replace it with
mixed, since resources cannot be typed more precisely. - Prefix the name with a backslash, as in
\resource, to tell PHP that a class actually calledresourceis meant, which suppresses the warning. - If a class or interface named
resourceexists in the current namespace, import it with ausestatement so PHP recognizes it, which also suppresses the warning.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s" is returned from __sleep() multiple times
Description
This error is emitted when one of the properties that has to be put to sleep is repeated in the returned array of __sleep(). All the duplicated properties are reported in one pass, although each of them only once. The warning is only triggered when the code is run.
Example
<?php
class X {
private $data;
public function __sleep() {
return ['data', 'data', 'data'];
}
}
// Create an instance and serialize it
$example = new Example('test');
$serialized = serialize($example);
?>
Literal Examples
- data“ is returned from __sleep() multiple time
Alternatives
- Make sure the properties names are all unique in the returned array.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s" will be interpreted as a class name. Did you mean "%s"? Write "\%s"%s to suppress this warning
Description
boolean, integer and double are the names PHP itself uses internally, and returns from gettype(), for the bool, int and float types. They look like legitimate type names, but they were never made valid type declarations; only the short forms are.
Because none of these three words is reserved, PHP does not reject them in a type position: it treats the declaration as the name of a class or interface instead, one that essentially never exists, so any call passes a value of the intended scalar type and still fails with a TypeError.
To catch this common mistake, the compiler recognizes exactly these three words – and only these three, compared case-sensitively, so Boolean or INTEGER are assumed to be genuine class names and do not trigger it – and emits this warning, naming the short form that was probably intended. It only fires when no class or interface with that exact name has been imported in the current file.
Example
<?php
function toggle(boolean $flag): integer {
return $flag ? 1 : 0;
}
?>
Literal Examples
- “boolean” will be interpreted as a class name. Did you mean “bool”? Write “\boolean” to suppress this warning
- “integer” will be interpreted as a class name. Did you mean “int”? Write “\integer” to suppress this warning
- “double” will be interpreted as a class name. Did you mean “float”? Write “\double” to suppress this warning
Alternatives
- Replace the alias with the actual scalar type:
boolinstead ofboolean,intinstead ofinteger,floatinstead ofdouble. - Prefix the name with a backslash, as in
\boolean, to tell PHP that a class actually calledbooleanis meant, which suppresses the warning. - If a class or interface with that exact name exists in the current namespace, import it with a
usestatement so PHP recognizes it, which also suppresses the warning.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s %s cannot implement interface %s, extend Exception or Error instead
Description
Throwable is a PHP native and reserved interface. It may be used for typing, such as with catch or parameter typing, but cannot be used directly.
As the message suggest, the best is to extends an existing class that already implements Throwable, such as Error, Exception or any of their children classes.
Several interfaces are reserved by PHP: UnitEnum, BackedEnum, Throwable.
Example
<?php
class X implements Throwable {}
?>
Literal Examples
- Class X cannot implement interface Throwable, extend Exception or Error instead
Alternatives
- Extends
Exceptionclass. - Extends
Errorclass. - Extends any of the
ExceptionorErrorclasses.
%s %s cannot implement previously implemented interface %s
Description
This error reports that an interface has already been implemented by a parent, and, as such, should not be implemented again.
For enumerations, it applies to BackEnum and UnitEnum, as enumerations don’t have parents.
For interfaces and classes, it applies to repetitions of interfaces in the implements list.
It doesn’t apply to duplicate implements between a parent and a child class or interface.
It doesn’t apply to trait, that have no relationship with interfaces.
Example
<?php
enum X implements UnitEnum {}
interface J extends I, I {}
class X implements I {}
// This is OK
// It is also duplicate and useless, but valid.
class Y extends X implements I {}
?>
Literal Examples
- Enum x cannot implement previously implemented interface UnitEnum
Alternatives
- Remove duplicate interfaces from the
implementskeyword on classes. - Remove duplicate interfaces from the
extendskeyword on interfaces. - Remove
BackEnumandUnitEnumfrom theimplementskeyword on an enumeration.
Related error messages
%s %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining method%s (
Description
A class (or a trait, once it is used in a class) that does not provide a body for one or more of its abstract methods – inherited from a parent class, or required by an implemented interface – must itself be declared abstract. Otherwise PHP has no concrete implementation to call when the method is invoked, and it stops with a fatal error while linking the class.
The message lists every abstract method that is still missing a concrete implementation, up to three of them; when there are more, the list ends with ....
This is the templated, general-purpose version of the message: the first %s is replaced by the kind of structure (Class or Interface), the second by its name.
Since PHP 8.5, enums and anonymous classes no longer use this message: they get the dedicated %s %s must implement %d abstract method%s (...) message instead, since neither of them can be declared abstract.
Example
<?php
interface Colorful {
function color();
}
class Suit implements Colorful {
}
?>
Literal Examples
- Class Suit contains 1 abstract method and must therefore be declared abstract or implement the remaining method (Colorful::color)
Alternatives
- Implement the missing method(s), with a body, in the class.
- Declare the class
abstract. - Remove the
implements/extendsclause that brings in the abstract method.
Related error messages
- class-%s-contains-%d-abstract-method%s-and-must-therefore-be-declared-abstract-or-implement-the-remaining-methods
- class-%s-declares-abstract-method-%s()-and-must-therefore-be-declared-abstract
- %s-%s-must-implement-%d-abstract-method%s-(
- anonymous-class-method-%s()-must-not-be-abstract
- non-abstract-method-%s::%s()-must-contain-body
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See abstractMethodMessageSplit85
%s %s inherits both %s::%s and %s::%s
Description
PHP reports duplicate constant definitions in different interfaces.
This is very unusual occurrence, reported at linting time. It may also lead to quite a set back when one has to untangle these definitions.
So, shall we always give unique names across interfaces? Or just avoid multiple interfaces with constants on the same class?
There is no ‘use’ expression to solve the conflict. The same applies to traits, though they can resolve conflicts with the use expression.
Also, multiple same methods in different interface are OK.
Example
<?php
interface Test1 {
const FOO = 10;
}
interface Test2 {
const FOO = 10;
}
class Test implements Test1, Test2 {
}
echo Done\n;
?>
Literal Examples
- class test inherits both test1::FOO and test2::FOO
Alternatives
- Remove one of the constant definition.
- Rename one of the interface constant.
- Define the conflicted constant in the class.
- Remove one of the interfaces.
Related error messages
%s %s must implement %d abstract method%s (
Description
An enum, or an anonymous class, that does not provide a body for one or more of its abstract methods – inherited via an implemented interface – must implement all of them, since, unlike an ordinary class, neither an enum nor an anonymous class can be declared abstract to defer the implementation.
The message lists every abstract method that is still missing a concrete implementation, up to three of them; when there are more, the list ends with ....
This is the templated, general-purpose version of the message: the first %s is replaced by the kind of structure (Enum or Class, the latter for anonymous classes), the second by its name.
Before PHP 8.5, anonymous classes used the generic %s %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining method%s (...) message instead of this one, since only enums had this dedicated message. Also, before PHP 8.5, the wording for enums included the word ‘private’ (must implement %d abstract private method%s), which was corrected.
Example
<?php
interface Colorful {
function color();
}
enum Suit implements Colorful {
case Hearts;
}
?>
Literal Examples
- Enum Suit must implement 1 abstract method (Colorful::color)
- Class Colorful@anonymous must implement 1 abstract method (Colorful::color)
Alternatives
- Implement the missing method(s), with a body, in the enum or the anonymous class.
- Remove the
implementsclause that brings in the abstract method.
Related error messages
- %s-%s-contains-%d-abstract-method%s-and-must-therefore-be-declared-abstract-or-implement-the-remaining-method%s-(
- class-%s-contains-%d-abstract-method%s-and-must-therefore-be-declared-abstract-or-implement-the-remaining-methods
- anonymous-class-method-%s()-must-not-be-abstract
- %s-method-%s::%s()-must-not-be-abstract
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See abstractMethodMessageSplit85
%s %s must implement interface %s as part of either %s or %s
Description
It is not possible to implement directly the mentioned interface. That interface is actually implemented by a selection of PHP native classes: these classes may be extended, and, as such, the children classes also implements the initial interface.
This error message is applicable to a few PHP native interfaces, such as Throwable (via Error and Exception) and Traversable (via Iterator and IteratorAggregate).
Example
<?php
enum E implements Traversable {}
class X implements Throwable {}
?>
Literal Examples
- Enum Foo must implement interface Traversable as part of either Iterator or IteratorAggregate
- Class X cannot implement interface Throwable, extend Exception or Error instead
Alternatives
- Extends one of the classes mentioned in the error message.
- Remove the implementations and its interface.
In previous PHP versions, this error message used to be :ref:class-%s-must-implement-interface-%s-as-part-of-either-%s-or-%s.
%s and %s define the same constant (%s) in the composition of %s. However, the definition differs and is considered incompatible. Class was composed
Description
There is not conflict resolution, when a class and a trait defined the same constant. Both constants must be identical, or face the above error message.
In order to be compatible, the constants in the class AND in the trait must have the same name, the same value (after eventual resolution of the expression), same visibility and the same type.
In the case that the constant is defined in a parent class as private, the trait may defined it again without conflict.
Example
<?php
class X {
private const A = 2;
}
trait T {
protected const null|int A = 1 + 1;
public const null|int B = 1;
public const null|int C = 1 + 2;
}
class Y extends X {
protected const int B = 2;
public const ?int C = 3;
use T;
}
?>
Literal Examples
- y and t define the same constant (B) in the composition of y. However, the definition differs and is considered incompatible. Class was composed
Alternatives
- Synchronise the constants to make them compatible.
- Remove the constant from the class.
- Remove the constant from the trait.
Related error messages
- %s-and-%s-define-the-same-hooked-property-($%s)-in-the-composition-of-%s.-conflict-resolution-between-hooked-properties-is-currently-not-supported.-class-was-composed
- %s-and-%s-define-the-same-property-($%s)-in-the-composition-of-%s.-however,-the-definition-differs-and-is-considered-incompatible.-class-was-composed
- cannot-use-trait-%s
%s and %s define the same hooked property ($%s) in the composition of %s. Conflict resolution between hooked properties is currently not supported. Class was composed
Description
When a class and a trait it uses both declare hooks for a property of the same name, PHP cannot merge the two definitions, even when the hooks are effectively identical.
For plain properties, a trait property is simply overridden by an identically named property in the using class, as long as the two are type-compatible. For methods, name clashes between traits can be settled with the insteadof and as operators. Hooked properties have neither mechanism: there is no way to tell PHP which of the two conflicting sets of hooks (get/set) should win, so the compiler always raises a fatal error instead of picking one silently.
The same restriction applies when two different traits, both used by the same class, declare hooks for a property with the same name.
Example
<?php
trait T {
public $prop {
get { echo __METHOD__, PHP_EOL; }
set { echo __METHOD__, PHP_EOL; }
}
}
class C {
use T;
public $prop {
get { echo __METHOD__, PHP_EOL; }
set { echo __METHOD__, PHP_EOL; }
}
}
?>
Literal Examples
- C and T define the same hooked property ($prop) in the composition of C. Conflict resolution between hooked properties is currently not supported. Class was composed
Alternatives
- Rename the property in the trait or in the class so that they no longer collide.
- Remove the hooks from the property in the class, and rely solely on the trait’s hooks.
- Remove the hooks from the property in the trait, and only declare hooks in the class.
- Move the shared behaviour into a method that both the trait and the class hooks can call, instead of duplicating the hooks.
Related error messages
- %s-and-%s-define-the-same-constant-(%s)-in-the-composition-of-%s.-however,-the-definition-differs-and-is-considered-incompatible.-class-was-composed
- cannot-redeclare-property-hook
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s and %s define the same property ($%s) in the composition of %s. However, the definition differs and is considered incompatible. Class was composed
Description
There is no conflict resolution for properties: when two traits used by the same class declare a property with the same name, the property must be defined identically in both, or PHP raises this error while composing the class.
To be considered compatible, the property must have the same visibility, the same type, the same default value, and the same readonly/static modifiers in every trait it comes from.
Unlike methods, property conflicts cannot be settled with an insteadof or as rule in the use block: the only way out is to make the definitions match, or to remove the property from all but one trait.
Example
<?php
trait A {
public int $count = 0;
}
trait B {
protected int $count = 1;
}
class C {
use A, B;
}
?>
Literal Examples
- A and B define the same property ($count) in the composition of C. However, the definition differs and is considered incompatible. Class was composed
Alternatives
- Make the property declaration identical (visibility, type, default value and modifiers) in every trait.
- Remove the property from all traits but one.
- Declare the property directly on the class instead, and remove it from the traits.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s cannot implement %s - it is not an interface
Description
The implements keyword must use an interface, and cannot use anything else. In particular, it cannot be another class, enumeration or trait. All four structures CITE (class, Interface, Trait and Enumeration) use the same namespaces, and they cannot be told apart by reading the name only.
Indeed, when the structure has no definition, PHP reports interface-"E" not found.
Example
<?php
enum E {}
class X implements E {}
?>
Literal Examples
- X cannot implement e - it is not an interface
Alternatives
- Make sure the implements structure is an interface, not a class, trait or enumeration.
Related error messages
%s cannot use %s - it is not a trait
Description
In a class definition, the use expression must only use traits. All other structures, such as class, interface, enum or else, are not allowed.
Example
<?php
class X {}
class Y {
use x;
}
?>
Literal Examples
- y cannot use x - it is not a trait
Alternatives
- Remove the use expression that uses the class.
- Fix the name of the class, and use an existing trait.
Related error messages
%s class %s cannot extend %s class %s
Description
This is the generic form of the error emitted when a readonly class and a non-readonly class try to extend one another: the first two %s are Readonly/Non-readonly plus the child class name, the last two are readonly/non-readonly plus the parent class name.
readonly is a class-wide modifier: it applies to every property declared in the class. Because a subclass inherits all of its parent’s properties, mixing a readonly class with a non-readonly one in the same hierarchy would leave some properties ambiguous about whether they can be written to after construction. PHP forbids this by requiring every class in an inheritance chain to share the same readonly status.
Example
<?php
readonly class Foo
{
}
class Bar extends Foo
{
}
?>
Literal Examples
- Readonly class Bar cannot extend non-readonly class Foo
- Non-readonly class Bar cannot extend readonly class Foo
Alternatives
- Make both classes readonly.
- Make both classes non-readonly.
- Make both classes non-readonly and apply readonly per property instead.
Related error messages
- readonly-class-%s-cannot-extend-non-readonly-class-%s
- non-readonly-class-%s-cannot-extend-readonly-class-%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s function %s::%s() cannot be declared private
Description
A method may be private, as in only available to current class, or abstract, as in always redefined in a child class, but not both at the same time.
These two properties are mutually exclusive.
Example
<?php
class X {
private abstract function foo() ;
}
?>
Literal Examples
- abstract function X::foo() cannot be declared private
Alternatives
- Make the method protected or public.
- Remove the abstract keyword.
%s function %s::%s() cannot contain body
Description
A method that is abstract – either explicitly declared abstract, or implicitly abstract because it belongs to an interface – is only a signature: it must not have an implementation.
The first %s in the message is Interface when the method is declared inside an interface, and Abstract when it is an explicitly abstract method of a class or trait.
Example
<?php
interface Colorful {
function color() {
return 'red';
}
}
?>
Literal Examples
- Interface function Colorful::color() cannot contain body
- Abstract function C::color() cannot contain body
Alternatives
- Remove the method body, keeping only the signature followed by a semicolon.
- Remove the
abstractkeyword, or move the method out of the interface, if it should have an implementation.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s hook of property %s::$%s must accept exactly one parameters
Description
When the set hook of a property is declared with an explicit parameter list, that list must contain exactly one parameter: the value being assigned. Declaring zero, two, or more parameters is not allowed.
This is different from omitting the parenthesis altogether, in which case the hook implicitly receives the value through a variable named $value.
Example
<?php
class X
{
public string $property {
set($a, $b) {
$this->property = $a;
}
}
}
?>
Literal Examples
- set hook of property X::$property must accept exactly one parameters
Alternatives
- Keep only one parameter in the hook’s parameter list.
- Remove the parameter list entirely and use the implicit
$valuevariable instead.
Related error messages
- get-hook-of-property-%s::$%s-must-not-have-a-parameter-list
- parameter-$%s-of-%s-hook-%s::$%s-must-not-be-variadic
- parameter-$%s-of-%s-hook-%s::$%s-must-not-have-a-default-value
- parameter-$%s-of-%s-hook-%s::$%s-must-not-be-pass-by-reference
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s implements the Serializable interface
Description
The Serializable interface (serialize()/unserialize()) was PHP’s original hook for customizing object serialization, but it has a well-known flaw: it cannot represent the identity and reference structure of nested objects correctly, which is why __serialize()/__unserialize() were introduced in PHP 7.4 as a full replacement.
As of PHP 8.1, any non-abstract class that implements Serializable without also implementing both __serialize() and __unserialize() emits this deprecation notice as soon as the class is declared (not just when an instance is serialized). A class that implements Serializable and the two magic methods is not affected – that combination remains the recommended way to support both old and new PHP versions.
Example
<?php
class Foo implements Serializable {
public function serialize(): string {
return '';
}
public function unserialize($data): void {
}
}
new Foo;
?>
Literal Examples
- Foo implements the Serializable interface, which is deprecated. Implement __serialize() and __unserialize() instead (or in addition, if support for old PHP versions is necessary)
Alternatives
- Replace serialize()/unserialize() with __serialize(): array and __unserialize(array $data): void.
- If backward compatibility with PHP < 7.4 is required, keep implementing Serializable but also add __serialize() and __unserialize() – only the interface without the magic methods triggers the notice.
- Drop custom serialization handling entirely if the default property-based serialization is sufficient.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
%s is not supported on type %s
Description
This error is reported when an operation is attempted indirectly on a wrong type of data. Here, there is an attempt to add 3 values, one of which is an array.
Example
<?php
$array = [ 1, 2, [3]];
print array_sum($array);
$array = [ 1, 2, (object) [3]];
print array_product($array);
?>
Literal Examples
- Addition is not supported on type array
- Multiplication is not supported on type object
Alternatives
- Check that the array only contains numbers.
%s method %s::%s() must not be abstract
Description
Interface methods are implicitly abstract: they never carry a body, since an interface only declares a contract. Writing the abstract keyword explicitly on an interface method is therefore redundant, and PHP rejects it.
The same message is used for enums, since 8.5: an enum can never be declared abstract, so none of its own methods can be abstract either (its cases are not classes that could provide the missing implementation).
This is the templated, general-purpose version of the message: the first %s is replaced by the kind of structure (Interface or Enum), the second and third by the class name and the method name.
Before PHP 8.5, declaring an abstract method directly inside an enum body produced the generic %s %s must implement %d abstract method%s (...) message instead of this dedicated one.
Example
<?php
interface Colorful {
abstract function color();
}
?>
Literal Examples
- Interface method Colorful::color() must not be abstract
- Enum method Suit::foo() must not be abstract
Alternatives
- Remove the
abstractkeyword from the method declaration. - If the method needs a real implementation, give it a body instead of declaring it
abstract.
Related error messages
- anonymous-class-method-%s()-must-not-be-abstract
- class-%s-declares-abstract-method-%s()-and-must-therefore-be-declared-abstract
- %s-%s-must-implement-%d-abstract-method%s-(
- interface-%s-cannot-contain-non-abstract-method-%s()
- %s-function-%s::%s()-cannot-contain-body
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See abstractMethodMessageSplit85
%s virtual property %s::$%s must not specify asymmetric visibility
Description
A virtual property is related to property hooks: it is a property whose hook do not use the underlying property for storage, but uses another one (or, like here, none).
When the set or get visibility doesn’t apply, this error is displayed. The error message may start with Read-only or Write-only.
Example
<?php
class X {
public private(set) int $p {
set {}
}
}
class Y {
public private(set) int $p {
get {}
}
}
?>
Literal Examples
- Write-only virtual property X::$p must not specify asymmetric visibility
- Readonly-only virtual property Y::$p must not specify asymmetric visibility
Alternatives
- Remove the asymmetric visibility from the definition of the property.
- Remove the property hook from the definition of the property.
- Remove the virtual property, by making the property hook use the underlying property.
%s::$%s has #[\Override] attribute
Description
PHP 8.5 extends the #[\Override] attribute, previously usable only on methods, so that it can also be applied to properties. It tells the engine that the property is expected to override a property of the same name declared in a parent class or an implemented interface, so that the engine can check that this is really the case.
Here, Y::$b is marked as overriding, but X (the parent of Y) has no $b property at all – only $a. Since there is nothing to override, the attribute is meaningless, and PHP reports it as an error at compile time. The full message continues with ‘, but no matching parent property exists’.
This error is also raised when the class using the attribute has no parent at all, or when the property is declared in a trait whose using class has no matching parent property.
Example
<?php
class X {
public int $a = 1;
}
class Y extends X {
#[\Override]
public int $b = 2;
}
?>
Literal Examples
- Y::$b has #[\Override] attribute, but no matching parent property exists
Alternatives
- Remove the
#[\Override]attribute. - Rename the property to match the name used by the parent class or interface.
- Add the property, with the same name, to the parent class.
Related error messages
- %s::%s()-has-#[-override]-attribute,-but-no-matching-parent-method-exists
- has-#[-override]-attribute,-but-no-matching-parent-method-exists
- %s::%s-has-#[–override]-attribute
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See overrideAttributeOnProperty85
%s::%s() has #[\Override] attribute, but no matching parent method exists
Description
This error message has two sources: it happens, at compilation time, when the class has no parent, yet has a method with Override attribute. Since the attribute implies that the method is overriding a parent’s method, this is not possible.
The second cause is a method that has no counterpart in the parents’ classes: there, the attribute plays its actual role.
This error happens when the Override attribute was used in PHP version 8.2, or older, and then, the code was moved to PHP 8.3. With the last version change, the attribute became active, and the code is now actually checked.
Example
<?php
class X {
#[Override]
function foo();
}
class Y extends X {
#[Override]
function goo();
}
?>
Alternatives
- Remove the Override attribute.
- Add a method with the same name to the parent class.
- Rename the current method to one that is present in the parent.
- Stay on PHP 8.2.
Related error messages
%s::%s(): Return type must be %s when declared
Description
The magic methods __sleep and __serialize may be left without a return type. By construction, PHP uses array for them.
So, when a return type is written in the source, for these methods, it must be array.
Here is the list of compulsory return types:
- __destruct() :
void - __construct() :
void - __unserialize() :
void - __unset() :
void - __set() :
void - __serialize() :
array - __isset() :
bool - __toString() :
string.
Example
<?php
class X {
function __construct() : int {}
function __sleep() : int {}
function __serialize() : int {}
function __isset() : int {}
}
?>
Literal Examples
- X::__sleep(): Return type must be array when declared
- X::__construct(): Return type must be void when declared
- X::__isset(): Return type must be bool when declared
Alternatives
- Give the correct return type to the magic method.
- Remove the return type of the magic method.
%s::%s cannot override final constant %s::%s
Description
The final keyword prevents any child class to define the same constant or method. The final const may overwrite a parent’s definition, but this is the definitive value associated to the constant. Child class must define a distinct constant name.
Example
<?php
class X {
final const A = 1;
}
class Y extends X {
const A = 1;
}
?>
Literal Examples
- Y::A cannot override final constant X::Y
Alternatives
- Remove the final option in the parent class.
- Rename the non-final constant in the child class.
Related error messages
%s::%s has #[\Override] attribute
Description
PHP 8.6 extends the #[\Override] attribute, previously usable only on methods and properties, to class constants and enum cases, the later being internally a special kind of class constant. It tells the engine that the constant is expected to override a constant of the same name declared in a parent class or an implemented interface, so that the engine can check that this is really the case.
Here, Square::COLOR is marked as overriding, but Shape, the interface Square implements, only declares SIDES, not COLOR. Since there is nothing to override, the attribute is meaningless, and PHP reports it as an error at compile time. The full message continues with ‘, but no matching parent constant exists’.
Only public and protected constants of a parent class or implemented interface satisfy the attribute; private constants do not count. This error is also raised when the class using the attribute has no parent and implements no interface at all.
Example
<?php
interface Shape {
const SIDES = 0;
}
class Square implements Shape {
#[\Override]
const SIDES = 4; // Fine, overrides Shape::SIDES
#[\Override]
const COLOR = 'blue'; // Fatal error, no matching parent constant
}
?>
Literal Examples
- Square::COLOR has #[\Override] attribute, but no matching parent constant exists
Alternatives
- Remove the
#[\Override]attribute. - Rename the constant, or enum case, to match one declared in a parent class or interface.
- Add a constant with the same name to the parent class or interface.
Related error messages
- %s::%s()-has-#[-override]-attribute,-but-no-matching-parent-method-exists
- %s::$%s-has-#[–override]-attribute
- has-#[-override]-attribute,-but-no-matching-parent-method-exists
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See overrideAttributeOnConstant86
%s::__sleep() should return an array only containing the names of instance-variables to serialize
Description
The return type of __sleep is actually array, even when it is not mentioned. Any other returned value generate this error.
Example
<?php
class X {
function __sleep() {
return 1;
}
}
serialize(new X);
?>
Alternatives
- Return an array from
__sleep. - Add the return type
arrayand return an array from__sleep. - Remove the
__sleep()method.
Related error messages
In previous PHP versions, this error message used to be :ref:sleep-should-return-an-array-only-containing-the-names-of-instance-variables-to-serialize..
%s::__toString() must return a string
Description
The magic method __toString converts the current object into a string. Hence, and even if the return type of that method is not explicitly set, it MUST return a string.
With strict types, it may only be a string. Without them, integers and booleans are auto cast silently.
Adding the return type or not does not change this behavior. It is actually set, and could not be any other type anyway.
Example
<?php
class X {
function __toString() {
return 1;
}
}
(string) (new X);
?>
Literal Examples
- X::__toString() must return a string
Alternatives
- Return a string.
- Cast the value to a string before returning.
‘%s’ not in the ‘loop’ or ‘switch’ context
Description
break and continue are used to jump out of a loop, and proceed from the end of that loop. Since PHP 7.0, it is not possible to use them outside such a structure.
They can’t be used in a match.
Example
<?php
continue;
break;
?>
Literal Examples
- ‘break’ not in the ‘loop’ or ‘switch’ context
- ‘continue’ not in the ‘loop’ or ‘switch’ context
Alternatives
- Remove the
break. - Remove the
continue. - Move the
breakinside aswitchblock. - Move the
continueinside a loop block:for,foreach,while,do..while.
Related error messages
‘%s’ operator accepts only positive integers
Description
The break and continue operators only accepts a positive integer as explicit operand.
break and continue exit from the current loop. By default, it only exits the current loop; when a higher number is passed, they also exit the next loops.
It makes no sense to exit 0 loops (no need for break then), or a negative number of loop (call a new foreach). Break only works with literal integers, and doesn’t compile otherwise.
Example
<?php
break 1.2;
continue -1;
?>
Literal Examples
- ‘break’ operator accepts only positive integers
- ‘continue’ operator accepts only positive integers
Alternatives
- Round the number to the closest integer.
- Remove the call to break altogether.
- Move the loop in a separate method, and use return to break out of the loop.
- Use a goto to jump out of the loop.
Related error messages
‘%s’ operator with non-integer operand
Description
The break and continue operators only accept a positive non-null literal integer.
Beyond the obvious improper code that is break 1.2, even storing the number of break levels in a constant or a variable is not a valid syntax. It can only accept an integer.
Example
<?php
break 1.2;
const A = 1;
break A;
?>
Literal Examples
- ‘break’ operator with non-integer operand
- ‘continue’ operator with non-integer operand
Alternatives
- Round the number to the closest integer.
- Remove the call to break altogether.
- Move the loop in a separate method, and use return to break out of the loop.
- Use a goto to jump out of the loop.
Related error messages
‘%s’ is an invalid class name
Description
self describes the current class. It is a relative class name, as it has no literal value.
As such, it doesn’t have an absolute path version, such as \self. Hence, the error emitted there.
This error is also emitted for static and parent.
It was possible to circumvent this check until PHP 8.1, with namespace\%s syntax, where namespace represents the current namespace.
Example
<?php
function foo(\self $a) {};
function foo( $a) : \self {};
class X {
private \self $f;
private \x $f2;
}
?>
Literal Examples
- ‘\self’ is an invalid class name
- ‘\parent’ is an invalid class name
- ‘\static’ is an invalid class name
Alternatives
- Remove the initial backslash.
- Use the literal name of the intended class.
Related error messages
‘goto’ into loop or switch statement is disallowed
Description
It is not possible to put a label inside a loop (for, foreach, while, do…while…) or a switch call. Such statement have to be initialized before execution, and the goto would cut short this crucial step.
On the other hand, it is possible to jump from a loop or a switch to outside that structure: then, it terminates it.
It is also possible to use a goto within a loop and a switch.
This is a compilation error: it is detected before execution.
Example
<?php
function foo() {
goto A;
foreach($a as $b) {
A:
}
}
function bar() {
goto A;
switch($a) {
case 1:
A:
break;
}
}
?>
Alternatives
- Create a separate method to handle this specific case.
‘goto’ to undefined label ‘%s’
Description
This error is displayed when a goto command has no corresponding label in the method.
This is an compilation error: it is only reported before execution.
On the other hand, a label without a goto is not reported.
Example
<?php
function foo() {
goto A;
A:
goto B;
// Not such label as B:
// A orphan label
C:
}
?>
Literal Examples
- ‘goto’ to undefined label ‘THEN’
Alternatives
- Create the missing label.
- Remove the goto call.
- Rename the goto call.
(expression)::class cannot be used in constant expressions
Description
This error appears when the value of a constant is not entirely static, but may depend on context. In this case, the self::A will only be known when the trait t is used in a class.
Example
<?php
trait T {
const A = parent::class;
const B = self::A::class;
}
?>
Alternatives
- Keep values of constants simple.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
0 __HALT_COMPILER() can only be used from the outermost scope
Description
__HALT_COMPILER() stops the compiler at the exact point it is encountered; everything that follows in the file is no longer parsed as PHP code but kept as raw data, readable through the COMPILER_HALT_OFFSET constant and a file handle on the same script. Because it changes how the rest of the file is interpreted, it is only meaningful once, at the very top level of the file, and cannot be placed inside a function, a class, a conditional block, or any other nested structure. The leading “0” in this entry’s error text is a data artifact and not part of the actual PHP message.
Example
<?php
function boot() {
__halt_compiler();
}
boot();
?>
Alternatives
- Move the __halt_compiler() call out of the function/class/block, to the outermost level of the file.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
[] operator not supported for strings
Description
Strings and array share the bracket operator for accessing individual elements, but the append operator [] is not supported for strings.
Example
<?php
$string = 'abc';
$string[] = 'b';
?>
Alternatives
- Use the
.operator to add a string at the end of another.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
__autoload() is deprecated, use spl_autoload_register() instead
Description
The initial autoloader was a custom function, that was called whenever a class, interface or trait had to be loaded, but could not be found by PHP yet.
This approach was useful, but limited management operation: in particular, it was not possible to add more functions, or remove some of them. So, it was replaced with the spl_autoload_register() function, which add a closure to a list of autoloaders.
Example
<?php
function __autoload() {}
?>
Alternatives
- Give another name to the
__autoloadfunction, and register it as autoloader with spl_autoload_register(). - Remove the
__autoloadfunction.
In more recent PHP versions, this error message is now :ref:autoload()-is-no-longer-supported,-use-spl_autoload_register()-instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See autoload
__autoload() is no longer supported, use spl_autoload_register() instead
Description
The initial autoloader was a custom function, that was called whenever a class, interface or trait had to be loaded, but could not be found by PHP yet.
This approach was useful, but limited management operation: in particular, it was not possible to add more functions, or remove some of them. So, it was replaced with the spl_autoload_register() function, which add a closure to a list of autoloaders.
Example
<?php
function __autoload() {}
?>
Alternatives
- Give another name to the
__autoloadfunction, and register it as autoloader with spl_autoload_register(). - Remove the
__autoloadfunction.
In previous PHP versions, this error message used to be :ref:autoload()-is-deprecated,-use-spl_autoload_register()-instead.
__clone method called on non-object
Description
This error signals an attempt at cloning a value that is not an object. Indeed, anything but an object triggers this error: boolean, array, string, etc.
Note that it is possible to clone a constant since PHP 8.1, so it is legit to use clone on a constant.
Example
<?php
$a = clone array();
$b = null;
clone null;
const C = new Stdclass();
clone C;
?>
Alternatives
- Check the data before cloning it, with is_object() or instanceof.
Related error messages
In more recent PHP versions, this error message is now :ref:clone():-argument-#1-($object)-must-be-of-type-object,-%s-given.
__HALT_COMPILER() can only be used from the outermost scope
Description
__HALT_COMPILER() stops the compiler at the exact point it is encountered; everything that follows in the file is no longer parsed as PHP code but kept as raw data, readable through the COMPILER_HALT_OFFSET constant and a file handle on the same script. Because it changes how the rest of the file is interpreted, it is only meaningful once, at the very top level of the file, and cannot be placed inside a function, a class, a conditional block, or any other nested structure.
Example
<?php
function boot() {
__halt_compiler();
}
boot();
?>
Alternatives
- Move the __halt_compiler() call out of the function/class/block, to the outermost level of the file.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
__sleep should return an array only containing the names of instance-variables to serialize.
Description
The return type of __sleep is actually array, even when it is not mentioned. Any other returned value generate this error.
Example
<?php
class X {
function __sleep() {
return 1;
}
}
serialize(new X);
?>
Alternatives
- Return an array from __sleep.
- Add the return type
arrayand return an array from __sleep. - Remove the __sleep() method.
Related error messages
In more recent PHP versions, this error message is now :ref:%s::__sleep()-should-return-an-array-only-containing-the-names-of-instance-variables-to-serialize.
`%s’ is not a valid mode for fopen
Description
There are several modes when opening a file, as passed with the 2nd argument. Yet, there are values and combinaisons of values thare are not possible.
Example
<?php
$fp = fopen($path, "+rw");
?>
Literal Examples
- ‘+rw’ is not a valid mode for fopen
Alternatives
- Use a valid open mode.
Related error messages
A %s with return type must return a value
Description
When a function or a method declares a return type, every return statement in its body must provide a value, unless the type accepts no returned value (void, never) or the type allows null.
Writing a bare return;, without an expression, is only valid when the declared return type permits the absence of a value. Here, int does not, so the engine cannot supply an implicit value.
This is a compile time check: it does not depend on the code being executed.
Example
<?php
function foo(): int {
return;
}
?>
Alternatives
- Add a value to the return statement, matching the declared return type.
- Remove the return type, if the function is not meant to return a value.
- Change the return type to
voidif the function is not meant to return a value.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
A class constant must not be called class. it is reserved for class name fetching
Description
Class constants can use a lot of names, but not the name ‘class’. This is used by default to fetch the full name of the class, and there is no need to defined it.
Hence, it is not possible to define a class constant called ‘class’, case non-withstanding, as it conflict with the default constant.
Example
<?php
class X {
const CLASS = 1;
// the problem is case insensitive. class, Class, CLass... are all forbidden
}
?>
Alternatives
- Use another name for that constant.
Related error messages
A function with return type must return a value
Description
When a function has a return type, it must have a return command in its block, which must also have an argument. In this illustration, return has no argument, so it is return void, and this is detected at compilation time.
Note that PHP lint doesn’t check the type of the returned value at linting time: any return value makes this error go away. Type is checked at execution time, and only when the expression is used: it may trigger a ‘Return value must be of type int, string returned’.
This also applies to closures, methods, arrow functions.
This error is displayed with any return that doesn’t have an argument. They might be several of them in a single function.
Example
<?php
function foo(): int {
return ;
}
?>
Alternatives
- Add a returned value to all the return command.
- Check all the return commands for returned values.
- Remove the return type.
Related error messages
- return-value-of-%s%s%s()-must-%s%s%s,-%s%s-returned
- %s%s%s():-return-value-must-be-of-type-%s,-%s-returned
A never returning %s does not return a value, but #[\NoDiscard] requires a return value
Description
This definition include contradicting information: the return type never means that the function will never return, so there should be no return value to handle. On the other hand, the NoDiscard attribute request the caller to do something with the returned values. This is irreconcilable.
Example
<?php
#[\NoDiscard]
function test(): never {
throw new \Exception('Error!');
}
test();
?>
Literal Examples
- A never returning function does not return a value, but #[\NoDiscard] requires a return value
- A never returning method does not return a value, but #[\NoDiscard] requires a return value
Alternatives
- Remove the
neverreturn type. - Remove the
NoDiscardattribute.
Related error messages
- a-void-%s-does-not-return-a-value
- method-%s::%s-cannot-be-#[–nodiscard]
- method-%s::%s-cannot-be-#[–nodiscard]-error_type
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
A never-returning %s must not return
Description
A function that never returns, aka, with the never return type, must not use the return statement.
In fact, it must use either throw, die, exit, or call another function that never returns.
This applies to methods, static methods, and any variant of closure.
The runtime-equivalent of this error is never-returning function must not implicitly return.
Example
<?php
function foo() : never {
return 1;
}
?>
Literal Examples
- A never-returning function must not return.
Alternatives
- Remove the
neverreturn type. - Remove the
returncall.
Related error messages
A never-returning function must not return
Description
When using the never keyword, the function shall not use the return keyword. never means that the function will not return, but rather die, throw an exception, or trigger an error.
Also note that never cannot be used in a union or intersection type.
This error message applies to functions, closures and arrow functions. In PHP 8.4, a separate message applies to methods.
Example
<?php
function foo() : never {
return true;
}
?>
Alternatives
- Remove the
returnkeyword in the body of the function. - Change the
neverreturn type to another type.
Related error messages
A never-returning method must not return
Description
When using the never keyword, the method shall not use the return keyword. never means that the method will not return, but rather die, throw an exception, or trigger an error.
Also note that never cannot be used in a union type.
This error message applies to methods, since PHP 8.4. Before that version, a unified message mentioning functions applied to all structures.
Example
<?php
class X {
function foo() : never {
return true;
}
}
?>
Alternatives
- Remove the
returnkeyword in the body of the method. - Change the
neverreturn type to another type.
Related error messages
A non-numeric value encountered
Description
When the operands have to be integer, PHP tries to cast the value to an integer before perform the operation. The results varies from impossible to a simple loss of precision. In-between, some of the values cannot be partially converted, and yield this error message.
Here, the string may be converted to the integer 3, but also will loose some of the non-numeric data ‘fd’. PHP warns the user about that partial conversion, in case it doesn’t yield the expected results.
When the value cannot be converted to integer due to its type, a fatal error ‘Unsupported operand types’ is raised.
Example
<?php
var_dump("3df" % 2);
?>
Alternatives
- Add an explicit cast to integer before usage.
- Test if the value has an integer value before usage.
Related error messages
- implicit-conversion-from-float-string-“%s”-to-int-loses
- unsupported-operand-types
- unexpected-nan-value-was-coerced-to-%s
In previous PHP versions, this error message used to be :ref:a-non-well-formed-numeric-value-encountered.
A non well formed numeric value encountered
Description
When the operands have to be integer, PHP tries to cast the value to an integer before perform the operation. The results varies from impossible to a simple loss of precision. In-between, some of the values cannot be partially converted, and yield this error message.
Here, the string may be converted to the integer 3, but also will loose some of the non-numeric data ‘fd’. PHP warns the user about that partial conversion, in case it doesn’t yield the expected results.
When the value cannot be converted to integer due to its type, a fatal error ‘Unsupported operand types’ is raised.
Example
<?php
var_dump("3df" % 2);
?>
Alternatives
- Add an explicit cast to integer before usage.
- Test if the value has an integer value before usage.
Related error messages
In more recent PHP versions, this error message is now :ref:a-non-numeric-value-encountered.
A precedence rule was defined for %s::%s but this method does not exist
Description
When importing the trait, a rule was set up to resolve a method conflict between two methods, while one of them does not exist. This conflict resolution may be removed.
Example
<?php
trait A {}
trait B {
public function bar() {}
}
class MyClass {
use A, B {
A::bar insteadof B; // No bar in A
A::bar as C; // No bar in A too
}
}
?>
Literal Examples
- A precedence rule was defined for A::bar but this method does not exist
Alternatives
- Remove the conflicting rule.
- Create the missing method in the original trait.
Related error messages
- cannot-use–“static-”-as-method-modifier-in-trait-alias
- an-alias-was-defined-for-method-%s(),-which-exists-in-both-%s-and-%s.-use-%s::%s-or-%s::%s-to-resolve-the-ambiguity
- inconsistent-insteadof-definition.-the-method-%s-is-to-be-used-from-%s
- the-modifiers-of-the-trait-method-%s()-are-changed,-but-this-method-does-not-exist.-error
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
A void %s does not return a value, but #[\NoDiscard] requires a return value
Description
The #[\NoDiscard] attribute marks a function, method or closure so that the engine emits a warning whenever a caller ignores its return value. A void-returning function never produces a value to begin with, so requiring the caller to use one is a contradiction, and PHP rejects the combination at compile time.
Example
<?php
#[\NoDiscard]
function foo(): void {}
?>
Literal Examples
- A void function does not return a value, but #[\NoDiscard] requires a return value
- A void method does not return a value, but #[\NoDiscard] requires a return value
Alternatives
- Remove the
voidreturn type, and actually return a meaningful value. - Remove the
#[\NoDiscard]attribute, since there is nothing to discard.
Related error messages
- a-void-%s-must-not-return-a-value
- a-never-returning-%s-does-not-return-a-value
- method-%s::%s-cannot-be-#[–nodiscard]
- method-%s::%s-cannot-be-#[–nodiscard]-error_type
- a-%s-with-return-type-must-return-a-value
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
A void %s must not return a value
Description
A function, method or closure that uses the void return type, must not have a return expression with a parameter, in its body.
This is checked anywhere in the body of the function, at compilation time.
It is possible to use return, without any argument. It is not possible to return null, it must be without argument.
Example
<?php
function foo() : void {
return 1;
}
?>
Alternatives
- Remove the return expression.
- Remove the argument of the return expression.
- Remove the void returntype.
Related error messages
- a-void-%s-does-not-return-a-value
- a-%s-with-return-type-must-return-a-value
- void-can-only-be-used-as-a-standalone-type
Abstract property %s::$%s must specify at least one abstract hook
Description
An abstract property must have at least one of its hooks declared without a body (abstract). If all hooks have implementations, the property cannot be abstract, as there is nothing left for child classes to implement.
This is a PHP 8.4 language-level restriction enforced for abstract properties with hooks. An abstract property’s purpose is to require child classes to provide an implementation, but if all hooks already have bodies, there is no requirement to fulfill.
Example
<?php
abstract class X {
abstract public string $property {
get { return ''; }
set { }
}
}
?>
Literal Examples
- Abstract property x::$property must specify at least one abstract hook
Alternatives
- Make at least one hook abstract by removing its body block, e.g. change
get { return ''; }toget;. - Remove the
abstractkeyword from the property if all hooks should have implementations.
Related error messages
- only-hooked-properties-may-be-declared-abstract
- abstract-property-hook-cannot-have-body
- non-abstract-property-hook-must-have-a-body
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Abstract property hook cannot have body
Description
Property hooks, both set and get, may be made abstract by adding the keyword to the property definition. And, just like methods, abstract property hooks cannot have a body.
Example
<?php
class X {
public abstract $property {
get {}
}
}
?>
Alternatives
- Remove the abstract keyword.
- Remove the body of the property hook.
Related error messages
- non-abstract-property-hook-must-have-a-body
- abstract-property-%s::$%s-must-specify-at-least-one-abstract-hook
Access level to %s::$%s must be %s (as in class %s)%s
Description
A property redeclared in a child class cannot be given a stricter visibility than the one it has in the parent class. public may be narrowed to protected or private, and protected may be narrowed to private, but never the other way, and a child cannot go further and restrict a protected property down when the parent is already public unless it stays at least as visible.
Here, X::$property is protected, and Y tries to redeclare it as private, which is a narrowing and is therefore rejected.
The trailing, optional part of the message ( or weaker) is added whenever the parent property is not public: it means the child property must use the same visibility as the parent, or something even more permissive.
Example
<?php
class X {
protected $property;
}
class Y extends X {
private $property;
}
?>
Literal Examples
- Access level to Y::$property must be protected or weaker (as in class X)
Alternatives
- Use the same visibility as the parent property.
- Use a visibility that is the same as, or wider than, the parent property’s.
- Remove the redeclaration in the child class, and inherit the parent property as-is.
Related error messages
- access-level-to-%s::%s-must-be-%s-(as-in-%s-%s)%s
- set-access-level-of-%s::$%s-must-be-%s-(as-in-class-%s)%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Access level to %s::%s must be %s (as in %s %s)%s
Description
This error is emitted when a class constant is given more restrictive visibility than in the interface.
Anything in an interface is public, and so does any re-declaration in the host class.
Example
<?php
interface I {
public const A = 'public';
}
class X implements I {
private const A = 'public';
}
?>
Literal Examples
- Access level to x::A must be public (as in interface i)
- Access level to Z::B must be protected (as in class Y)
Alternatives
- Remove the constant from the interface.
- Remove the constant from the class.
Related error messages
- set-access-level-of-%s::$%s-must-be-%s-(as-in-class-%s)%s
- access-level-to-%s::$%s-must-be-%s-(as-in-class-%s)%s
Access to undeclared static property %s::$%s
Description
This error is reported when reading an undefined static property. The property must be defined before usage, or it yields a Fatal error.
This error is related to static properties: a different error is emitted for non-static properties.
Example
<?php
class X {
public static $a = 1;
}
$x = new X;
echo X::$a; // OK
echo X::$b;
$name = 'C';
echo X::${$c}; // dynamic properties
?>
Literal Examples
- Access to undeclared static property X::$staticProperty
Alternatives
- Define the static property in the requested class.
- Fix the name of the property on that class.
- Fix the name of the class of the property.
- Use a non-static property to handle this situation.
- Use property_exists() or isset() to check if the property exists before using it.
- Check if the dynamic name of the property is a string, before usage.
Related error messages
Access type for interface constant %s::%s must be public
Description
An method or a constant, that are defined in an interface, must appear as public in all the implementing classes. They cannot be made protected or private, as they would be no accessible.
Example
<?php
interface I {
private const C = 1;
}
?>
Literal Examples
- Access type for interface constant I::C must be public
Alternatives
- Set the visibility to public in the interface.
- Remove the visibility in the interface.
- Remove the constant in the interface.
Related error messages
Access type for interface method %s::%s() must be public
Description
An method, that is defined in an interface, must appear as public. They cannot be made protected or private, as they would be no accessible.
Example
<?php
interface I {
private function foo();
protected const C = 1;
}
?>
Literal Examples
- Access type for interface method I::foo() must be public
Alternatives
- Set the visibility to public in the interface.
- Remove the visibility in the interface.
Related error messages
Accessing static property %s::$%s as non static
Description
The property property is declared as static, and should be access with the :: operator.
Accessing that property with the -> or ?-> object operators is quite safe, as there is no confusion with the name of the property, and the object holds the name of the host class.
On the other hand, using the object operators does not provide accurate information about the actual property.
Example
<?php
class X {
public static $property = 1;
}
$x = new X;
echo $x->property;
?>
Literal Examples
- Accessing static property X::$property as non static
Alternatives
- Use the
::operator to access static properties. - Drop the
staticoption on the property.
Accessing static trait property %s::$%s is deprecated, it should only be accessed on a class using the trait
Description
Traits should not be used as standalone structure, but rather as a part of a class. Even for class agnostic structures, such as constants or static properties, they should be accessed via any class that uses them.
Example
<?php
trait T {
public static $property = 1;
}
echo T::$property;
T::$property = 2;
?>
Literal Examples
- Accessing static trait property T::$property is deprecated, it should only be accessed on a class using the trait
Alternatives
- Find a class that use the trait, and then, access the static property from there.
- Create a class that only use the trait, and use it. An anonymous class would do.
- Turn the trait into a class.
Related error messages
Accessing static trait property %s::$%s is deprecated
Description
Traits cannot be used independently from a host class. They must be used inside a class, with the use keyword.
Until PHP 8.1, it was possible to call traits without a host class. Since 8.1, writing or reading properties in a trait is forbidden.
It is also not possible to call a method or a constant on a trait.
Example
<?php
trait T {
public static $t = 1;
}
echo T::$t;
T::$t = 2;
?>
Literal Examples
- Accessing static trait property T::$property is deprecated
Alternatives
- Use the trait in a class and access its features.
- Convert the trait into a class and access its features.
Related error messages
An alias (%s) was defined for method %s(), but this method does not exist
Description
When importing methods from a trait, it is possible to create a method alias: give a new name to the trait method, when it is inside a class.
PHP checks that the original method exists, before allocating the new name. When the original method doesn’t exist, PHP emits this error message.
Example
<?php
trait T {}
class X {
use T {
foo as bar;
}
}
?>
Literal Examples
- An alias (bar) was defined for method foo(), but this method does not exist
Alternatives
- Check the name of the original method for typos.
- Add the missing method in the trait.
- Remove the alias.
- Remove the method with the same name in the class, and remove the alias.
Related error messages
An alias was defined for %s::%s but this method does not exist
Description
When importing methods from a trait, it is possible to create a method alias: give a new name to the trait method, when it is inside a class.
PHP checks that the original method exists, before allocating the new name. When the original method doesn’t exist, PHP emits this error message.
Example
<?php
trait T {}
class X {
use T {
foo as bar;
}
}
?>
Literal Examples
- An alias was defined for X::foo but this method does not exist
Alternatives
- Check the name of the original method for typos.
- Add the missing method in the trait.
- Remove the alias.
- Remove the method with the same name in the class, and remove the alias.
Related error messages
- an-alias-(%s)-was-defined-for-method-%s(),-but-this-method-does-not-exist
- cannot-use–“static-”-as-method-modifier-in-trait-alias
An alias was defined for method %s(), which exists in both %s and %s. Use %s::%s or %s::%s to resolve the ambiguity
Description
Inside the use block of a class, an alias rule can rename a trait method without stating which trait it comes from, by writing method as alias;.
When several of the traits used by the class declare a method with that exact name, PHP has no way to decide which one the alias should refer to, since the unqualified form only works when the name is unambiguous. The class composition fails until the origin trait is made explicit.
Example
<?php
trait A {
public function foo() {}
}
trait B {
public function foo() {}
}
class C {
use A, B {
foo as bar;
}
}
?>
Literal Examples
- An alias was defined for method foo(), which exists in both A and B. Use A::foo or B::foo to resolve the ambiguity
Alternatives
- Qualify the reference with the trait it should come from, as in
A::foo as bar;. - Rename or remove the method in one of the conflicting traits so only one of them still declares it.
Related error messages
- the-modifiers-of-the-trait-method-%s()-are-changed,-but-this-method-does-not-exist.-error
- a-precedence-rule-was-defined-for-%s::%s-but-this-method-does-not-exist
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
An iterator cannot be used with foreach by reference
Description
It is possible to use a foreach loop with a reference on the blind variable: this allows the original data to be modified.
Such feature is possible with an array as a source, but it is not possible with an iterator as a source. The iterator allows reading, but has no support for writing the individual elements it emits.
Example
<?php
$heap = new SplMinHeap;
foreach( $heap as &$item ) {}
?>
Alternatives
- Turn the iterator into an array and use it.
- Keep the blind variable per-value, and call a setter in it to update it.
- Use objects in the iterator, it is possible to update the blind variable without the reference.
Anonymous class method %s() must not be abstract
Description
An anonymous class cannot have an abstract method, as the class is actually immediately instantiate, while abstract class, and classes that contains an abstract method cannot be instantiated.
This error was also detected previously, with a more generic error message.
Example
<?php
new class() {
abstract function foo();
}
?>
Literal Examples
- Anonymous class method foo() must not be abstract
Alternatives
- Remove the abstract method.
- Add a body to the abstract method, and remove the abstract option.
Related error messages
- class-%s-contains-%d-abstract-method%s-and-must-therefore-be-declared-abstract-or-implement-the-remaining-methods
- %s-%s-must-implement-%d-abstract-method%s-(
- %s-%s-contains-%d-abstract-method%s-and-must-therefore-be-declared-abstract-or-implement-the-remaining-method%s-(
- %s-method-%s::%s()-must-not-be-abstract
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Argument #%d ($%s) must be of type %s, %s given
Description
This error is emitted when data of a wrong type is given to a typed argument.
The first parameter that fails the type constraint is reported. There might be other type failures after this one, though they are hidden by the first one encountered.
Example
<?php
function foo(int $x) {}
foo(1); // OK
foo('2'); // OK, with strict_types = 0
foo('abc'); // not OK
?>
Literal Examples
- Argument #1 ($x) must be of type int, string given
Alternatives
- Pass the correct argument to the method.
- Cast the value to the requested type.
- Change the type in the signature of the called method.
- Add the type in the signature of the called method.
Related error messages
In previous PHP versions, this error message used to be :ref:using-array_key_exists()-on-objects-is-deprecated..
In more recent PHP versions, this error message is now :ref:passing-the-encoding-as-third-parameter-is-deprecated.-use-an-explicit-zero-offset.
Argument #%d must be greater than or equal to 0
Description
This error is reported when a parameter is expected to be an integer, positive or zero. This is the case with the second argument of str_repeat().
Example
<?php
str_repeat('abc', -1);
// This is valid, and returns an empty string
str_repeat('abc', 0);
?>
Literal Examples
- str_repeat(): Argument #2 ($times) must be greater than or equal to 0
Alternatives
- Make sure the second argument is an integer, greater or equal to zero.
- Use intval() on the value of the second integer.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
range(): Argument #1 ($start) must be a single byte string if argument #2 ($end) is a single byte string, argument #2 ($end) converted to 0
Description
When range() produces all the values between two boundaries. These two boundaries must be of the same type, for consistency purpose. Hence, when one is a string, the second one also needs to be a string, and range() will generate all the values between these strings.
Example
<?php
range(1, 'b');
?>
Literal Examples
- range(): Argument #1 ($start) must be a single byte string if argument #2 ($end) is a single byte string, argument #2 ($end) converted to 0
Alternatives
- Cast the integer to a string.
- Cast the string to an integer.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See rangeSingleByteString
Argument #1 ($value) must contain at least one element
Description
max() and min() require at least one element in the array: otherwise, the returned value could be confused with NULL.
Example
<?php
max([]);
?>
Alternatives
- Check if the array has at least one argument before calling max() or min().
- Add an element to the array before callign max(), and use it as a canary.
range(): Argument #2 ($end) must be a single byte string if argument #1 ($start) is a single byte string, argument #1 ($start) converted to 0
Description
When range() produces all the values between two boundaries. These two boundaries must be of the same type, for consistency purpose. Hence, when one is a one character string, the second one also needs to be a one character string, and range() generates all the values between these strings.
Example
<?php
range('c', 3);
?>
Literal Examples
- range(): Argument #2 ($end) must be a single byte string if argument #1 ($start) is a single byte string, argument #1 ($start) converted to 0
Alternatives
- Use another string as second argument.
- Call range with two integers, and use chr() on each element of the array to turn them into characters.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See rangeSingleByteString
Argument of type %s will be interpreted as string in the future
Description
All of the ctype_*() functions (ctype_digit(), ctype_alpha(), ctype_alnum(), etc.) accept a string. For backward compatibility with very old PHP versions, though, when an int between -128 and 255 was passed instead, it was silently treated as a single ASCII character code (as if chr() had been called first) rather than being converted to its decimal string representation – so ctype_digit(123) tested the character chr(123) ({), not the string '123', which is a frequent source of confusion.
As of PHP 8.1, passing anything other than a string to a ctype_*() function emits this deprecation notice, warning that the value will be converted to a plain string instead of being interpreted as a codepoint once the legacy behaviour is removed.
Example
<?php
// 123 is not a string, so ctype_digit() has always treated it as an
// ASCII codepoint (like chr(123)) instead of the string "123".
var_dump(ctype_digit(123));
?>
Literal Examples
- ctype_digit(): Argument of type int will be interpreted as string in the future
Alternatives
- Cast the value to string explicitly if a numeric-looking value was intended, e.g. ctype_digit((string) $value).
- Call chr() explicitly first if the intent really was to test a single ASCII codepoint, e.g. ctype_digit(chr($value)).
- Use is_int()/is_numeric() instead of ctype_digit() when the input may not already be a string.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Argument unpacking in constant expressions is not supported
Description
It is not possible to use the ... operator in an static constant expression, with the new operator.
On the other hand, it is possible to use it inside arrays to spread the elements. It is also possible to use it in a closure definition.
Example
<?php
const A = [1,2,3];
function foo($a = new C(...A)) {}
function goo($a = [...A, ...A])) {}
?>
Alternatives
- Access the array elements individually.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Array and string offset access syntax with curly braces is deprecated
Description
PHP used to support the curly braces {} to access elements in an array and a string. This was deprecated in PHP 7.4 and abandoned in PHP 8.0. The only operator to access an element is the square brackets [].
Example
<?php
$string = 'abc';
echo $string{1}; // b
$array = ['A', 'B', 'C'];
echo $array{1}; // B
?>
Alternatives
- Switch to the square brackets.
- Use the substr() function to extract one string char.
In more recent PHP versions, this error message is now :ref:array-and-string-offset-access-syntax-with-curly-braces-is-no-longer-supported.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See curly_braces
Array and string offset access syntax with curly braces is no longer supported
Description
PHP used to support the curly braces {} to access elements in an array and a string. This was deprecated in PHP 7.4 and abandoned in PHP 8.0. The only operator to access an element is the square brackets [].
Example
<?php
$string = 'abc';
echo $string{1}; // b
$array = ['A', 'B', 'C'];
echo $array{1}; // B
?>
Alternatives
- Switch to the square brackets.
- Use the substr() function to extract one string char.
Related error messages
In previous PHP versions, this error message used to be :ref:array-and-string-offset-access-syntax-with-curly-braces-is-deprecated.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See curly_braces
Array callback has to contain indices 0 and 1
Description
PHP uses an array format to represents callback methods: it is an array with two elements. The first element is the class, and the second element is the method. To be valid, this array must also only use the index 0 and 1 (resp.) for these elements.
Also, note that this array must only have two elements.
With the explicit 0 and 1 indices, the order of the elements are not important in the array. With omitted indices, the order is important for PHP to differentiate which is the class, and which is the method.
Example
<?php
class X {
static function foo() {}
}
$callback = [3 => X::class, 'foo'];
$callback();
?>
Alternatives
- Apply array_values() to the array before using it as a callback.
- Convert the array syntax to the new x::foo(…) syntax.
- Convert the array syntax to the string ‘\x::foo’ syntax.
- Remove the index in the array definition.
Related error messages
Array callback must have exactly two elements
Description
An array callback is an array that is used as a callback function. That structure is needed when using a method, static or not, as a callback: indeed, it requires an object or a class name, and the method name. It also does not need more elements, so two are sufficient.
Example
<?php
$a = array('a', 'b', 'c');
$a();
$e = array('d');
$e();
?>
Alternatives
- Remove any extra elements in the array, to have only two elements.
- Add any missing elements in the array, up to two elements.
Related error messages
Array to string conversion
Description
This error appears when an array is converted into a string, without a proper type cast. For example, in the illustration code, the array is directly used with echo, which requires a string, as argument. The result of this expression is Array.
This error may be a sub-part of other operations, that also requires strings. This is the second example, with implode() : the source of the error lies in the elements of the array. They are supposed to be strings, so as to be concatenated with the separator; but one of them is also an array, leading to the error.
This error is not affected by strict_types: it is always emits the same error.
Example
<?php
echo ['a'];
echo implode(',', [1, 2, ['c']]);
?>
Alternatives
- Convert the array to a string first.
- Extract one (or more) entries from the array, as long as they are strings.
- Force the array to a string with cast (although it will produce the
Arraystring). - Use a method that accept strings and arrays.
Related error messages
array_key_exists(): Argument #2 ($array) must be of type array, %s given
Description
Until PHP 8.0, it was possible to use array_key_exists() on both arrays, and objects. The objects were considered as an array, where the properties are the indices, linked to their values.
Since PHP 8.0, it is a deprecated behavior, and in a later version, PHP will make the typing more strict.
The other types, such as integer or string, are not accepted either.
Example
<?php
$object = (object) ['a' => 1]; // stdClass
var_dump(array_key_exists('a', $object));
?>
Literal Examples
- array_key_exists(): Argument #2 ($array) must be of type array, stdClass given
- array_key_exists(): Argument #2 ($array) must be of type array, string given
- array_key_exists(): Argument #2 ($array) must be of type array, int given
Alternatives
- Cast the object to array before searching.
- Call a method on the object to convert it to an array, before searching.
- Create a search method, among the properties, on the object.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See array_key_existsOnObjects
array_merge() does not accept unknown named parameters
Description
array_merge() accepts one parameter, called $arrays. In fact, it is a variadic parameter, so this parameter may be repeated as needed. Yet, there is only one name for it.
When using array_merge() with a variadic argument, PHP tries to match the keys of the array with the parameters, and in this case, fails for all but one: $arrays.
The solution is to spread the array, after removing the string keys: with integer keys, PHP will not check the names.
There are several PHP native functions that behave like that: array_merge(), array_diff_key(), etc. In fact, any native method which has a variadic parameter.
PHP doesn’t emit an error when spreading an array with unknown keys in a custom function.
Example
<?php
$a = ['x' => [1], 'y' => [3]];
foo(...$a);
//array_merge() does not accept unknown named parameters
array_merge(...$a);
function foo($x, array ...$arrays) {
print_r($arrays);
}
?>
Alternatives
- Apply array_values() to the array that is used with array_merge().
array_merge() expects at least 1 parameter, 0 given
Description
Until PHP 7.4, array_merge() always needed at least one argument to execute. This means that using the variadic operator on an empty array yielded no argument, and then, an error.
Since PHP 7.4, array_merge() handles graciously the case of no arguments, by returning an empty array, and not more error.
This applies to array_merge() and array_merge_recursive().
Example
<?php
$array = [];
$array2 = array_merge(...[]);
?>
Alternatives
- Check for non-empty array before using it with array_merge().
array_product(): Multiplication is not supported on type array
Description
array_product() multiplies each element in the first argument, with each other. This is a valid operation for integer, floats, numeric strings, booleans and null, as they can be cast to numbers.
This is not the case for arrays, objects, non-numeric strings or resources, which yield this warning, and are omitted in the operation.
Until PHP 8.3, the omission of invalid argument was a silent behavior.
Example
<?php
var_dump(array_product([[]] )); // returns 1
var_dump(array_product([[], 3] )); // returns 3
?>
Alternatives
- Filter out all values in the first argument not actually numeric: aka, they can’t be cast to integer or float without error.
- Filter out all arrays inside the first argument.
Related error messages
- array_product():-multiplication-is-not-supported-on-type-object
- array_product():-multiplication-is-not-supported-on-type-string
array_product(): Multiplication is not supported on type object
Description
array_product() multiplies each element in the first argument, with each other. This is a valid operation for integer, floats, numeric strings, booleans and null, as they can be cast to numbers.
This is not the case for arrays, objects, non-numeric strings or resources, which yield this warning, and are omitted in the operation.
Objects are not turned to string before being cast to numeric.
Until PHP 8.3, the omission of invalid argument was a silent behavior.
Example
<?php
var_dump(array_product([new stdClass()] )); // returns 1
var_dump(array_product([new stdClass(), 3] )); // returns 99
?>
Alternatives
- Filter out all values in the first argument not actually numeric: aka, they can’t be cast to integer or float without error.
- Filter out all objects inside the first argument.
Related error messages
- array_product():-multiplication-is-not-supported-on-type-array
- array_product():-multiplication-is-not-supported-on-type-string
- array_sum():-addition-is-not-supported-on-type-array
array_product(): Multiplication is not supported on type string
Description
array_product() multiplies each element in the first argument, with each other. This is a valid operation for integer, floats, numeric strings, booleans and null, as they can be cast to numbers.
This is not the case for arrays, objects, non-numeric strings or resources, which yield this warning, and are omitted in the operation.
Until PHP 8.3, the omission of invalid argument was a silent behavior.
Example
<?php
var_dump(array_product(['abc'] )); // returns 1
var_dump(array_product(['33', 3] )); // returns 99
?>
Alternatives
- Filter out all values in the first argument not actually numeric: aka, they can’t be cast to integer or float without error.
- Filter out all strings inside the first argument, which fails the is_numeric() call.
Related error messages
- array_product():-multiplication-is-not-supported-on-type-array
- array_product():-multiplication-is-not-supported-on-type-object
array_sum(): Addition is not supported on type array
Description
array_sum() adds each element in the first argument, with each other. This is a valid operation for integers, floats, numeric strings, booleans and null, as they can be cast to numbers.
This is not the case for arrays, objects, non-numeric strings or resources, which yield this warning, and are omitted in the operation.
Until PHP 8.3, the omission of invalid argument was a silent behavior.
Example
<?php
var_dump(array_sum([[]] )); // returns 0
var_dump(array_sum([[], 3] )); // returns 3
?>
Alternatives
- Filter out all values in the first argument not actually numeric: aka, they can’t be cast to integer or float without error.
- Filter out all arrays inside the first argument.
Related error messages
Arrow functions on the right hand side of |> must be parenthesized
Description
The pipe operator accepts many variants of closures, such as closures, callable, arrays and first class callables. Yet, it doesn’t accept direct arrow functions: they must be placed inside parenthesis. This ensures the parser knows when to finish the returned expression, which might also include another pipe operator.
Example
<?php
echo 'a' |> fn($a) => 1;
?>
Alternatives
- Use a closure.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
assert.active INI setting is deprecated
Description
assert.active is a legacy INI directive that dates back to the pre-PHP 7 implementation of assert(), where assertions could be toggled on or off at runtime through several assert.* INI settings.
Since PHP 7, assertion behavior is primarily controlled by the zend.assertions directive, which supports three modes: 1 (generate and execute code, development mode), 0 (generate code, but skip execution at runtime), and -1 (do not generate code, production mode). assert.active became redundant, only affecting whether assert() calls are executed at all, and is now deprecated.
The deprecation notice is triggered whenever assert.active is set to a falsy value, either in php.ini or through ini_set().
Example
<?php
ini_set('assert.active', '0');
?>
Alternatives
- Use the
zend.assertionsdirective to control whether assertions are compiled and executed. - Remove
ini_set()/ini_get()calls involvingassert.activefrom the code.
Related error messages
- assert.bail-ini-setting-is-deprecated
- assert.exception-ini-setting-is-deprecated
- assert.warning-ini-setting-is-deprecated
In more recent PHP versions, this error message is now :ref:assert.bail-ini-setting-is-deprecated.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See assert
assert.bail INI setting is deprecated
Description
assert.bail is a legacy INI directive from the pre-PHP 7 implementation of assert(). When enabled, it terminated script execution as soon as a failed assertion was encountered, instead of letting the script continue.
This behavior is redundant with throwing an AssertionError (the default behavior since PHP 7 when assert.exception is enabled), which already interrupts execution unless the exception is caught. As part of the general cleanup of the legacy assertion configuration, assert.bail is now deprecated.
The deprecation notice is triggered whenever assert.bail is set to a truthy value, either in php.ini or through ini_set().
Example
<?php
ini_set('assert.bail', '1');
?>
Alternatives
- Rely on the
AssertionErrorexception thrown by failed assertions (controlled byassert.exception) to stop execution, and catch it where appropriate. - Remove
ini_set()/ini_get()calls involvingassert.bailfrom the code.
Related error messages
- assert.active-ini-setting-is-deprecated
- assert.exception-ini-setting-is-deprecated
- assert.warning-ini-setting-is-deprecated
In previous PHP versions, this error message used to be :ref:assert.active-ini-setting-is-deprecated.
In more recent PHP versions, this error message is now :ref:assert.exception-ini-setting-is-deprecated.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See assert
assert.callback INI setting is deprecated
Description
The php.ini directive assert.callback is deprecated, alongside several features from the assert functions. It should not be set anymore in the code.
Note that a call to ini_get() will not generate the warning: only the ini_set().
Example
<?php
ini_set('assert.callback', 1);
?>
Alternatives
- Remove the call to
assert.callbackand its dependencies.
assert.exception INI setting is deprecated
Description
assert.exception controls whether a failed assert() throws an AssertionError (the default since PHP 7) or falls back to the legacy behavior of emitting a warning and continuing execution.
Disabling exceptions for assertions revives pre-PHP 7 behavior that is inconsistent with the rest of the language, where failures are normally reported through exceptions or errors. As part of the cleanup of the legacy assert.* configuration, this directive is now deprecated.
The deprecation notice is triggered whenever assert.exception is set to a falsy value, either in php.ini or through ini_set().
Example
<?php
ini_set('assert.exception', '0');
?>
Alternatives
- Keep
assert.exceptionenabled (the default) and catchAssertionErrorwhere a failed assertion needs to be handled instead of propagating. - Remove
ini_set()/ini_get()calls involvingassert.exceptionfrom the code.
Related error messages
- assert.active-ini-setting-is-deprecated
- assert.bail-ini-setting-is-deprecated
- assert.warning-ini-setting-is-deprecated
In previous PHP versions, this error message used to be :ref:assert.bail-ini-setting-is-deprecated.
In more recent PHP versions, this error message is now :ref:assert.warning-ini-setting-is-deprecated.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See assert
assert.warning INI setting is deprecated
Description
assert.warning is a legacy INI directive that, when assert.exception is disabled, controls whether a failed assert() call emits an E_WARNING. It is part of the pre-PHP 7 assertion configuration that predates AssertionError.
Since this directive only has an effect together with the also-deprecated assert.exception, and there is no equivalent replacement to keep emitting a custom warning message, it is now deprecated as well. Once removed in PHP 9, disabling it will no longer be possible.
The deprecation notice is triggered whenever assert.warning is set to a falsy value, either in php.ini or through ini_set().
Example
<?php
ini_set('assert.warning', '0');
?>
Alternatives
- Rely on the
AssertionErrorexception thrown by failed assertions instead of the legacy warning-based reporting. - Remove
ini_set()/ini_get()calls involvingassert.warningfrom the code.
Related error messages
- assert.active-ini-setting-is-deprecated
- assert.bail-ini-setting-is-deprecated
- assert.exception-ini-setting-is-deprecated
In previous PHP versions, this error message used to be :ref:assert.exception-ini-setting-is-deprecated.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See assert
Assignments can only happen to writable values
Description
With the list() operator, the right part of the => operator must be a variable or equivalent. The corresponding value on the right part of the assignation will be stored there, so it has to be a data container. It is possible to use a variable, property (static or not), an array element or an array append.
The same error may happen when the property is not available: this may be the case with a nullsafe operator.
This is valid with or without the index part, in the list() call.
Example
<?php
// short array syntax. The left part is not an array, but a list()
[1] = [2];
['a' => 1] = ['a' => 2];
list('a' => 1) = array('a' => 2);
// ?-> may be returning null, and not a valid container.
[$foo?->bar->baz] = ['bar'];
?>
Alternatives
- Use a variable.
- Use an array append.
- Use a a property.
Attempt to assign property “%s” on null
Description
null is not an object, and it can’t be used as such. Until PHP 8.0, the engine would automatically create a stdClass object, and replace the null value with it. This is not the case anymore.
Example
<?php
$a = null;
$a->b = 1;
?>
Literal Examples
- Attempt to assign property “b” on null
Alternatives
- Instantiate any object and replace
nullwith it. - Explicitly instantiate a
stdClassobject and replacenullwith it. - Remove the property usage.
- Use another variable to use this property.
In previous PHP versions, this error message used to be :ref:creating-default-object-from-empty-value.
Attempt to read property “%s” on %s
Description
This error reports that a non-object was used with an object syntax. Non-objects are integers, floats, strings, null, booleans, etc.
This is a warning, so PHP will continue execution, using null as a result of this operation.
Example
<?php
$integer = 1;
var_dump($integer->a);
$array = [3];
var_dump($array?->a);
?>
Literal Examples
- Attempt to read property “a” on int
- Attempt to read property “a” on array
- Attempt to read property “a” on float
- Attempt to read property “a” on string
- Attempt to read property “a” on bool
Alternatives
- Remove the use of the property.
- Add a type to the underlying variable, to ensure it is an object.
- Check the variable is an object.
Attempt to unset static property %s::$%s
Description
It is not possible to unset a static property.
This applies to typed and not typed static properties. It also only applies to static properties that are already set, such as in the illustration: PHP complains about uninitialized state first, and later, about removing static properties.
This does not apply to properties, which may be removed.
Example
<?php
class X {
public static $y = 1;
public static int $z;
}
//Attempt to unset static property X::$x
unset(X::$y);
//Attempt to unset static property X::$z
unset(X::$z);
X::$z = 2;
//Attempt to unset static property X::$x
unset(X::$z);
?>
Literal Examples
- Attempt to unset static property X::$x
Alternatives
- Set the property to null.
- Set the property to a value that represents removal.
Related error messages
- typed-property-%s::$%s-must-not-be-accessed-before-initialization
- typed-static-property-%s::$%s-must-not-be-accessed-before-initialization
Attribute “%s” cannot target %s (allowed targets: %s)
Description
Attributes are built with a specific target, and may not be applicable to any structure. For example, the native ReturnTypeWillChange targets only methods, and not properties.
With a custom structure, the error is shown when requesting an instance of the attribute. Otherwise, this error remains silent, and the structure may be used without error.
With a PHP native attribute, the engine decides when it makes use of it.
Example
<?php
// example with a native PHP attribute
class Foo
{
#[ReturnTypeWillChange]
public int $bar;
}
#[Attribute(Attribute::TARGET_FUNCTION | Attribute::TARGET_METHOD)]
class X { }
// the object is created. It may be used without error.
$ref = new ReflectionObject(new #[X] class() { });
$attr = $ref->getAttributes()[0];
try {
$attr->newInstance();
} catch (\Throwable $e) {
print $e->getMessage();
}
?>
Alternatives
- Remove the attribute restrictions.
- Update the attribute to target the requested feature.
- Remove the attribute from the forbidden feature.
- Create another the attribute for the feature.
Attribute class “%s” not found
Description
This error reports that a class was not found. This is also focusing on attribute classes.
Class are reported as not found when they are used, so this error message is displayed when the attribute is actually used in the code, by calling the getInstance reflection. An attribute might exists without its underlying class, as long as it is not instanciated.
Example
<?php
#[X]
function f() { }
$ref = new \ReflectionFunction('\f');
try {
$ref->getAttributes()[0]->newInstance();
} catch (\Error $e) {
var_dump($e->getMessage());
}
?>
Literal Examples
- Attribute class “Deprecated” not found
Alternatives
- Check spelling and namespace for that class.
- Create the associated class.
- Avoid using getInstance() on that attribute.
Related error messages
auto_detect_line_endings is deprecated
Description
The auto_detect_line_endings ini directive tells fgets(), file() and fgetss() to look at the first few lines of a file to detect the classic Mac OS (pre-OS X) \r-only line ending convention, and adjust the line-splitting logic accordingly.
Classic Mac OS line endings are essentially extinct, so keeping this detection logic around adds a runtime cost and a behavioral surprise for very little benefit. The directive is deprecated, and setting it to a truthy value now raises a deprecation notice; it will be removed entirely in PHP 9.0.
Example
<?php
ini_set('auto_detect_line_endings', '1');
$fp = fopen('data.txt', 'r');
$line = fgets($fp);
?>
Alternatives
- Leave
auto_detect_line_endingsat its default (disabled) value. - If
\r-only line endings must be supported, read the whole file withfile_get_contents()and split it with a regular expression that matches\r\n,\ror\n, such aspreg_split('/\r\n|\r|\n/', $contents).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Automatic conversion of false to array is deprecated
Description
The array syntax $variable[index] is only available for arrays and strings. Yet, false is an edge case: PHP used to convert automatically, and silently, the boolean to array, when that syntax was used. This is called autovivification.
The other boolean, true behaves the same way, with a different error message.
This feature is used to initialize variables with false, and then convert it to array as needed.
Since PHP 8.1, it is a deprecated behavior.
Example
<?php
$variable = false;
$variable[0] = 1;
// $variable is now an array
class X {
public bool|array $property = false;
}
$x = new X;
$x->property['d'] = 3;
?>
Alternatives
- Use an empty array as default value.
- Test the type of the variable before using it as an array.
Related error messages
- cannot-unset-offset-in-a-non-array-variable
- cannot-auto-initialize-an-array-inside-property-%s::$%s-of-type-%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See autoInitializeArrayFromBool
Automatic fetching of PostgreSQL connection is deprecated
Description
Many pg_* functions, such as pg_query() and pg_query_params(), accept a PostgreSQL connection as their first argument, but this parameter used to be optional: when omitted, PHP implicitly reused the last connection opened with pg_connect() or pg_pconnect().
This implicit default_link behavior makes it easy to accidentally query the wrong connection when a script opens more than one, and it forces the pgsql extension to keep a hidden, mutable global state. As of PHP 8.1.0, relying on this default connection is deprecated, and an explicit connection must be passed instead.
Example
<?php
pg_connect('host=localhost dbname=test');
// The connection argument is omitted: PHP implicitly reuses
// the last connection opened by pg_connect()/pg_pconnect().
$result = pg_query('SELECT 1');
?>
Alternatives
- Store the resource/object returned by
pg_connect()orpg_pconnect()and pass it explicitly as the first argument to everypg_*function used afterwards.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See pg_query
Bad class name in the catch statement
Description
A catch clause lists one or more class or interface names (possibly joined with |) that the caught exception must match. Those names have to be resolvable to a concrete class at compile time.
The pseudo-class static refers to the class the method was actually called on, which is only known at runtime, not at compile time. Since PHP needs to know the exact catch types while compiling the try/catch block, static cannot be used there, even though it is otherwise allowed as a return type or inside the method body.
Example
<?php
class Test
{
public function method()
{
try {
foo();
} catch (static $e) {
}
}
}
?>
Literal Examples
- Bad class name in the catch statement
Alternatives
- Use the real class name instead of
static. - Use
selfif the intent is to catch the class in which the method is defined.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
break operator accepts only positive integers
Description
break indicates the number of nested loop to break from. The minimum is 1. 0 would be a no operation, and shall be skipped. Negative numbers or decimals make no sense.
Example
<?php
$a = [];
foreach($a as $b) {
break 0;
}
?>
Alternatives
- Remove the continue command.
- Remove the 0.
Related error messages
Call to %s %s::%s() from global scope
Description
This error reports that the requested method exists, but is not available from the context of call. Here, the method is private and should only be called from within its definition class.
There are distinct messages for calling an unknown method, or calling a protected method.
Example
<?php
class X {
public function foo() {}
private function goo() {}
}
$x = new X;
$x->goo();
?>
Literal Examples
- Call to private x::goo() from global scope
Alternatives
- Call a public method on that class.
- Check for typos in the name of the method.
- Change the visibility of the method, to be able to call it.
Related error messages
Call to %s %s::%s() from invalid
Description
A private method shall only be called from within its own class. It cannot be called from another class, or from the global space. In particular, the method cannot be called directly, or indirectly: for example, new X indirectly calls the __construct method.
A protected method shall only be called from within its own class, or any of it parent or children. It cannot be called from another non-related class, or from the global space. In particular, the method cannot be called directly, or indirectly: for example, new X indirectly calls the __construct method.
A public method may be called from anywhere in the code.
Example
<?php
class X {
//This is also the case with proctected __construct
private function __construct() {}
static public function factory() {
return new X();
}
}
//This is not possible
$x = new X();
?>
Literal Examples
- Call to private method X::__construct() from global scope
Alternatives
- Check that the call to the method, and the visibility of the method are compatible.
In more recent PHP versions, this error message is now :ref:call-to-%s-method-%s::%s()-from-%s%s.
Call to %s %s::__destruct() from global scope during shutdown ignored
Description
During PHP shutdown, destructors are called for remaining objects. When a __destruct() method is invoked from global scope (i.e. not as part of object destruction triggered by the garbage collector or script end), PHP emits this warning and ignores the call.
This typically happens when a register_shutdown_function() callback creates an object whose destructor is called during the final cleanup phase. The object is destroyed immediately, but the invocation from global scope is considered invalid.
The warning ensures that destructors are only called in their expected context: as part of object lifetime management, not from arbitrary global code.
Example
<?php
class X {
public function __destruct() {
echo "Destroying\n";
}
}
register_shutdown_function(function() {
$x = new X;
});
?>
Literal Examples
- Call to public X::__destruct() from global scope during shutdown ignored
- Call to protected X::__destruct() from global scope during shutdown ignored
Alternatives
- Move the logic from
__destruct()into a regular method and call it explicitly before the object is destroyed. - Avoid creating objects inside shutdown functions if you rely on their destructor behavior.
- Use a dedicated lifecycle method instead of relying on
__destruct()for cleanup logic.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Call to %s method %s::%s() from %s%s
Description
A private method shall only be called from within its own class. It cannot be called from another class, or from the global space. In particular, the method cannot be called directly, or indirectly: for example, new X indirectly calls the __construct method.
A protected method shall only be called from within its own class, or any of it parent or children. It cannot be called from another non-related class, or from the global space. In particular, the method cannot be called directly, or indirectly: for example, new X indirectly calls the __construct method.
A public method may be called from anywhere in the code.
Example
<?php
class X {
//This is also the case with proctected __construct
private function __construct() {}
static public function factory() {
return new X();
}
}
//This is not possible
$x = new X();
?>
Literal Examples
- Call to private method X::__construct() from global scope
Alternatives
- Check that the call to the method, and the visibility of the method are compatible.
In previous PHP versions, this error message used to be :ref:call-to-%s-%s::%s()-from-invalid.
Call to a member function %s() on %s
Description
This error happens when the object syntax is used on a string. A string is a scalar type, and cannot hold method, properties nor constants. The type of the variable should be checked before usage. This also happens with the nullsafe operator, which only protects against NULL used as an object.
Example
<?php
'a'?->foo();
$string = 'abc';
$string->foo();
?>
Literal Examples
- Call to a member function foo() on string
- Call to a member function foo() on int
- Call to a member function foo() on null
Alternatives
- Check the type of the object before usage.
Related error messages
Call to undefined function %s()
Description
This error is displayed when the called function is not defined. There are many places in the code where a function may be defined: in the PHP core engine, in PHP extensions, in dependencies, in the current file, in an included file. Also, since PHP 8.0, a function, disabled with the disable_functions directive, is shown as undefined, rather than forbidden.
Example
<?php
undefined_function();
?>
Literal Examples
- Call to undefined function undefined_function()
- Call to undefined function shell_exec()
- Call to undefined function mb_substr()
Alternatives
- The function has not been written in the code.
- The function has not been included in the code before being called.
- The function name has a typo.
- The function is not defined in the current PHP version.
- The function is not defined in any PHP extension version.
- The function is not defined the current namespace, or the global namespace.
- The
useexpression, used to import that function from another namespace, misses thefunctionkeyword:use foo as Ainstead ofuse function foo as A. - The function is actually a closure: a
$is missing:$variable(), instead ofvariable(). - This is actually a constant, and extra
()were added. - The function was disabled with
disable_functions.
In previous PHP versions, this error message used to be :ref:%s()-has-been-disabled-for-security-reasons.
Call to undefined function each()
Description
each() used to be a PHP native function. It was deprecated in PHP 7.4, and is undefined since PHP 8.0.
Example
<?php
$array = ['a', 'b'];
while(list($key, $value) = each($array)) {
print "$key => $value\n";
}
?>
Alternatives
- Downgrade to PHP 7.x.
- Use
yield. - Use
yield from. - Use
foreach().
Related error messages
In previous PHP versions, this error message used to be :ref:the-each()-function-is-deprecated.-this-message-will-be-suppressed-on-further-calls.
Call to undefined function exit()
Description
exit and die used to be language constructures, until PHP 8.4. Then, they could not be used in a dynamic function call, such as shown here. Indeed, language constructs are not accessible with that syntax.
Since PHP 8.4, die and exit are defined as functions, and shall be used with the dynamic call feature.
Example
<?php
$function = 'exit';
$function();
?>
Alternatives
- Upgrade to PHP 8.4.
Related error messages
Call to undefined function
Description
This error appears when calling a function that is not defined.
There should be a function definition in the code, and that definition must be included in the code before it is called. The presence of a function may be tested with the function_exists() function.
The function may be defined in a PHP extension, or its core: then, the function has no explicit definition. Its existence may be checked with a call to get_defined_function(), which lists all the functions, at the execution point.
A function may be disabled in the PHP.ini, using the disabled_functions directive. Then, the function is totally unknown by PHP, and it may even be redefined.
Language constructs, such as exit and die, are not functions, and some features, such as calling them from a string, is not possible until PHP 8.4.
The function might be defined in a different namespace, or its import might be missing.
Example
<?php
// calling a function before it is defined
foo();
function foo() {}
try {
//Uncaught Error: Call to undefined function \exit()
$s = 'exit';
$s();
} catch(Error) {
print "No such function as $s";
}
?>
Alternatives
- Check the spelling of the function name.
- Check the version of PHP, or its extensions: some functions are defined in specific versions, or later.
- Check the namespace of the called function: it might not be available in the current namespace, or in the global namespace.
- Check the use expression at the beginning of the file: the import expression might be missing.
- Use the function_exists() function before calling a function whose name is stored in a variable.
- Use a try/catch around the function call, and catch Error (not exceptions).
Related error messages
Call to undefined method %s::%s()
Description
This message is emitted when no method with the requested name could be found on the class, or its parents or traits.
Calling from another class’s context yields a distinct message.
Example
<?php
class X {
function foo() {}
}
$x = new X;
$x->goo();
?>
Literal Examples
- Call to undefined method x::goo()
Alternatives
- Check the spelling of the method name.
- Check if the object supports this method.
- Check if there are the valid trait name import (
usein a class), to define the method. - Check if the method is still available in the current setup (PHP version, components and library versions…).
- Check if the magic method
__call()is not missing in the object’s class.
Related error messages
Callables of the form ["%s
Description
PHP’s callable array syntax is documented as [$objectOrClass, 'methodName']: the first element gives the object or class, the second is a plain method name. The engine, however, has always also accepted a second element that is itself a compound 'Class::method' string, silently ignoring or double-checking the class given by the first element. This form only ever worked through call_user_func(), is_callable() and similar reflective APIs – it was never invocable through the direct $callable() syntax – so it belongs to the family of ‘partially supported callables’.
As of PHP 8.2, resolving such an array emits Callables of the form ["%s", "%s"] are deprecated, with the two placeholders filled with the class name resolved from the first element and the full compound string from the second. Plain callables such as 'Class::method' or [$objectOrClass, 'method'] are not affected.
Example
<?php
class Foo {
public static function bar() {
return 'bar called';
}
}
// The first element already resolves 'Foo', and the second element
// repeats it inside a compound 'Class::method' string.
$callable = ['Foo', 'Foo::bar'];
var_dump(call_user_func($callable));
?>
Literal Examples
- Callables of the form [“Foo”, “Foo::bar”] are deprecated
Alternatives
- Drop the redundant class prefix from the second element and use the plain method name: [$objectOrClass, ‘method’].
- If a fully qualified callable is preferred, use the string form ‘Class::method’ directly instead of an array.
- Use first-class callable syntax (PHP 8.1+), e.g. Foo::bar(…), when the target is known at the call site.
Related error messages
- use-of–“self-”-in-callables-is-deprecated
- use-of–“parent-”-in-callables-is-deprecated
- use-of–“static-”-in-callables-is-deprecated
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling %pS() for static method %pS::%pS() does not need an object parameter
Description
ReflectionMethod::invoke() and ReflectionMethod::invokeArgs() accept an object as their first argument to use as $this inside the invoked method. For a static method there is no $this, so that object is simply ignored — but silently ignoring it hides a likely mistake, such as invoking the wrong method or forgetting the target is static. PHP 8.6 deprecates passing a non-null object in this case.
Example
<?php
class TestClass {
private static function staticMethod() {
echo "Called staticMethod()\n";
}
}
$method = new ReflectionMethod(TestClass::class, 'staticMethod');
$instance = new TestClass();
$method->invoke($instance);
?>
Literal Examples
- Calling ReflectionMethod::invoke() for static method TestClass::staticMethod() does not need an object parameter
- Calling ReflectionMethod::invokeArgs() for static method TestClass::staticMethod() does not need an object parameter
Alternatives
- Pass
nullas the object argument when invoking a static method:$method->invoke(null). - If you meant to call an instance method, check that
$methodreally refers to it.
Related error messages
In more recent PHP versions, this error message is now :ref:calling-%ps()-with-a-given-object-that-is-not-an-instance-of-the-class-this-property-was-declared-in-is-deprecated.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling %pS() with a 1st argument which is not null or an object is deprecated
Description
ReflectionProperty::setValue() sets a static property when called as setValue(null, $value): the 1st argument is not used to locate a static property, since it has no associated object, but it is still type-checked.
Prior to this deprecation, PHP silently accepted any value as the 1st argument in that case, as it was simply discarded. Since PHP 8.3, passing a value that is neither null nor an object as the 1st argument is deprecated, in order to make the accepted signature consistent with its declared ?object type.
Example
<?php
class X {
public static int $count = 0;
}
$prop = new ReflectionProperty(X::class, 'count');
// deprecated: the 1st argument is ignored for static properties,
// but it must still be null or an object
$prop->setValue('ignored', 42);
var_dump(X::$count);
?>
Literal Examples
- Calling ReflectionProperty::setValue() with a 1st argument which is not null or an object is deprecated
Alternatives
- Pass
nullexplicitly as the 1st argument when setting a static property:setValue(null, $value). - If the property is not static, pass the actual object instance as the 1st argument instead of an unrelated value.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling %pS() with a given object that is not an instance of the class this property was declared in is deprecated
Description
ReflectionProperty::setValue() and ReflectionProperty::setRawValue() take the target object as their first argument. When that object is not an instance of the class (or a subclass of it) the property was declared on, the write silently falls back to creating a dynamic property on the unrelated object instead of failing. PHP 8.6 deprecates this mismatch, since it almost always indicates the wrong $propInfo or the wrong object was used.
Example
<?php
class TestClass {
public $pub2 = 5;
}
#[AllowDynamicProperties]
class AnotherClass {
}
$instanceWithNoProperties = new AnotherClass();
$propInfo = new ReflectionProperty('TestClass', 'pub2');
$propInfo->setValue($instanceWithNoProperties, 'NewValue');
?>
Literal Examples
- Calling ReflectionProperty::setValue() with a given object that is not an instance of the class this property was declared in is deprecated
- Calling ReflectionProperty::setRawValue() with a given object that is not an instance of the class this property was declared in is deprecated
Alternatives
- Only call setValue() / setRawValue() with an object that is an instance of the class the ReflectionProperty was created for.
- Use
instanceofto verify the object before calling setValue() if it is not known statically.
Related error messages
In previous PHP versions, this error message used to be :ref:calling-%ps()-for-static-method-%ps::%ps()-does-not-need-an-object-parameter.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling %pS() with a single argument is deprecated
Description
ReflectionProperty::setValue() accepts an object as its 1st argument and the new value as its 2nd argument. Static properties have no associated object, so PHP historically allowed calling setValue() with a single argument (the value only) to set a static property.
Since this single-argument form is ambiguous with the two-argument form used for instance properties, it is deprecated as of PHP 8.3. The 1st argument must now be passed explicitly, using null to mean “this is a static property”.
Example
<?php
class X {
public static int $count = 0;
}
$prop = new ReflectionProperty(X::class, 'count');
// deprecated: the object argument is missing
$prop->setValue(42);
var_dump(X::$count);
?>
Literal Examples
- Calling ReflectionProperty::setValue() with a single argument is deprecated
Alternatives
- Call
setValue(null, $value)instead ofsetValue($value)to set a static property. - For instance properties, always pass the object as the 1st argument:
setValue($object, $value). - Use
ReflectionClass::setStaticPropertyValue()as an alternative way to set a static property by reflection.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling %s() on an object is deprecated
Description
prev(), current(), next() and reset() where php native functions used to navigate in arrays. They also applied to objects, although this is an accidental feature. Nowadays, using object with these functions is deprecated.
Example
<?php
$object = (object) ['a' => 1];
echo current($object);
?>
Literal Examples
- Calling prev() on an object is deprecated
- Calling next() on an object is deprecated
- Calling reset() on an object is deprecated
- Calling current() on an object is deprecated
Alternatives
- Cast the object to an array, and store it in a variable before using the mentioned functions.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See passingObjectIsDeprecated
Calling %s() with 2 arguments is deprecated,
Description
This is the generic shape of a family of deprecation notices introduced by the Deprecate functions with overloaded signatures RFC. Several built-in functions used to accept more than one call shape, distinguished only by how many arguments were passed, such as pg_fetch_result(), pg_field_prtlen() and pg_field_is_null() (2-argument form relying on an implicit row cursor) or stream_context_set_option() (2-argument form taking a whole options array instead of a single wrapper/option/value triple).
As of PHP 8.4, calling any of these functions with the specific, older argument count that made the overload ambiguous emits this deprecation notice, naming the function and pointing to its replacement. The exact wording of the second half of the message (after the comma) depends on the function.
Example
<?php
$conn = pg_connect('host=localhost dbname=test');
$result = pg_query($conn, 'SELECT id, name FROM users');
// 2-argument form: implicit row cursor instead of an explicit $row
echo pg_fetch_result($result, 'name'), "\n";
?>
Literal Examples
- Calling pg_fetch_result() with 2 arguments is deprecated, use the 3-parameter signature with a null $row parameter instead
- Calling stream_context_set_option() with 2 arguments is deprecated, use stream_context_set_options() instead
- Calling pg_field_is_null() with 2 arguments is deprecated, use the 3-parameter signature with a null $row parameter instead
Alternatives
- Check the specific function’s documentation for its replacement: a dedicated function (e.g. stream_context_set_options()) or the newer, explicit argument count (e.g. always passing $row to pg_fetch_result()).
Related error messages
- calling-pg_fetch_result()-with-2-arguments-is-deprecated,
- calling-stream_context_set_option()-with-2-arguments-is-deprecated,
- calling-reflectionmethod::__construct()-with-1-argument-is-deprecated,
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling %s(resource $stub
Description
Phar::setStub() (and PharData::setStub()) historically accepted two different signatures: a plain string $stub, or a resource $stub together with an int $length telling PHP how many bytes to read from the stream. Overloaded signatures like this make the function harder to reason about and to type-check.
As of PHP 8.3, calling the method with the (resource $stub, int $length) form is deprecated in favour of the single string $stub signature; the resource variant will be removed in PHP 9.0.
Example
<?php
$phar = new Phar('/tmp/test.phar');
$stream = fopen('php://memory', 'r+');
fwrite($stream, "<?php __HALT_COMPILER(); ?>");
rewind($stream);
// Passing a resource plus an explicit length is the overloaded,
// now-deprecated signature.
$phar->setStub($stream, 20);
fclose($stream);
?>
Literal Examples
- Calling Phar::setStub(resource $stub, int $length) is deprecated
- Calling PharData::setStub(resource $stub, int $length) is deprecated
Alternatives
- Read the resource into a string first and pass that string: $phar->setStub(stream_get_contents($stub)).
- If the resource is a file, read its contents with file_get_contents() instead of fopen()+fread().
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling a function “readonly” is deprecated
Description
readonly has been a semi-reserved word since PHP 8.1, when it was introduced as a modifier for readonly properties and classes. It could still be used as the name of a function, class, or constant, and PHP even special-cased a global function literally called readonly() so that WordPress, which ships one, would keep working.
PHP 8.6 deprecates calling such a function, as part of a broader effort to fully reserve readonly for the language. The deprecation notice is emitted every time the function is called, not when it is declared.
Example
<?php
function readonly() {
return 'not a property modifier';
}
echo readonly();
?>
Literal Examples
- Calling a function “readonly” is deprecated
Alternatives
- Rename the function to something that is not
readonly, e.g.readonlyValue()orgetReadonly().
Related error messages
- cannot-use-‘readonly’-as-%s-modifier
- syntax-error,-unexpected-identifier-“readonly”,-expecting-“function”-or-“const”
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, a global function literally named readonly() could be declared and called without any warning, as a compatibility carve-out for WordPress. As of PHP 8.6, calling it emits a deprecation notice, in preparation for readonly becoming a fully reserved word.](Previously, a global function literally named readonly() could be declared and called without any warning, as a compatibility carve-out for WordPress. As of PHP 8.6, calling it emits a deprecation notice, in preparation for readonly becoming a fully reserved word.)
Calling DatePeriod::__construct(string $isostr, int $options = 0) is deprecated,
Description
DatePeriod::__construct() has always accepted several unrelated sets of arguments: a start DateTimeInterface, an interval and either an end date or a number of recurrences, or, as a third overload, a single ISO 8601 recurring interval string (such as R4/2026-01-01T00:00:00Z/P1D).
Overloaded constructors that change meaning based on the number and type of arguments are error-prone and hard to document accurately. The ISO 8601 string overload is being split out into its own named constructor, and calling the constructor directly with a string is deprecated.
Example
<?php
$period = new DatePeriod('R4/2026-01-01T00:00:00Z/P1D');
foreach ($period as $date) {
echo $date->format('Y-m-d'), PHP_EOL;
}
?>
Alternatives
- Use
DatePeriod::createFromISO8601String()instead of passing the ISO 8601 recurring interval string to the constructor.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling dba_fetch() with $dba at the 3rd parameter is deprecated
Description
dba_fetch() historically accepted the database handle as its 3rd argument, behind an optional $skip argument used to select a duplicate key: dba_fetch(string $key, int $skip, resource $dba).
Every other dba_*() function takes the database handle as its 2nd argument, right after the key, so this older signature was inconsistent with the rest of the extension. Calling dba_fetch() with the handle in the 3rd position is now deprecated in favor of the consistent signature.
Example
<?php
$dba = dba_open('/tmp/test.db', 'c', 'flatfile');
$value = dba_fetch('some_key', 0, $dba);
?>
Alternatives
- Pass the database handle as the 2nd argument instead:
dba_fetch(string $key, resource $dba, int $skip = 0).
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling FFI::cast() statically is deprecated
Description
cast(), new() and type() are instance methods of the object returned by FFI::cdef() or FFI::load(): each loaded C definition scope has its own set of types, so casting or instantiating should happen on that specific instance.
For convenience, PHP also allowed calling these methods statically as FFI::cast(), FFI::new() and FFI::type(), in which case they implicitly operated on an anonymous, definition-less scope. This static shortcut is ambiguous about which set of C declarations is being used, and is now deprecated.
Example
<?php
$ffi = FFI::cdef('typedef struct { int x; int y; } point;');
$mem = $ffi->new('point');
$casted = FFI::cast('int', $mem);
?>
Alternatives
- Call
cast()on theFFIinstance returned byFFI::cdef()orFFI::load()instead of calling it statically:$ffi->cast(...).
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See ffiCastStaticDeprecated
Calling FFI::new() statically is deprecated
Description
new(), cast() and type() are instance methods of the object returned by FFI::cdef() or FFI::load(): each loaded C definition scope has its own set of types, so allocating a new value should happen on that specific instance.
For convenience, PHP also allowed calling these methods statically as FFI::new(), FFI::cast() and FFI::type(), in which case they implicitly operated on an anonymous, definition-less scope. This static shortcut is ambiguous about which set of C declarations is being used, and is now deprecated.
Example
<?php
FFI::cdef('typedef struct { int x; int y; } point;');
$mem = FFI::new('point');
?>
Alternatives
- Call
new()on theFFIinstance returned byFFI::cdef()orFFI::load()instead of calling it statically:$ffi->new(...).
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See ffiNewStaticDeprecated
Calling FFI::type() statically is deprecated
Description
type(), cast() and new() are instance methods of the object returned by FFI::cdef() or FFI::load(): each loaded C definition scope has its own set of types, so resolving a type name should happen on that specific instance.
For convenience, PHP also allowed calling these methods statically as FFI::type(), FFI::cast() and FFI::new(), in which case they implicitly operated on an anonymous, definition-less scope. This static shortcut is ambiguous about which set of C declarations is being used, and is now deprecated.
Example
<?php
FFI::cdef('typedef struct { int x; int y; } point;');
$type = FFI::type('point');
?>
Alternatives
- Call
type()on theFFIinstance returned byFFI::cdef()orFFI::load()instead of calling it statically:$ffi->type(...).
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See ffiTypeStaticDeprecated
Calling get_class() without arguments is deprecated
Description
get_class() used to allow its usage without an argument. Then, it would return the current class context, at compile time. Hence, in the code here, it used to return x, may it be called from x or y.
This behavior is not allowed anymore, and will be removed in PHP 9.
Note that calling get_class without an argument was different from calling get_class with the null value.
Example
<?php
class X {
function foo() {
echo get_class(); // x
echo get_class($this); // y
// echo get_class(null); // Type error
}
}
class Y extends X {}
echo (new Y)->foo();
?>
Alternatives
- Use the CLASS constant to get the name of the class at compile time.
- Use the
get_class($this)call, to get the name of the class at execution time.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See get_classWithoutArgument
Calling get_parent_class() without arguments is deprecated
Description
Using null as a parameter for the get_class() and get_parent_class() native call is deprecated since PHP 8.3. Using the null value defaulted to the current class, so it is possible to use $this instead.
Example
<?php
get_parent_class();
?>
Alternatives
- Use
$thisas an argument.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See get_classWithoutArgument
Calling IntlCalendar::set() with more than 2 arguments is deprecated,
Description
IntlCalendar::set() (and the procedural intlcal_set()) used to accept between 2 and 6 arguments: a single field/value pair, or up to a year, month, day, hour, minute and second all at once. Squeezing several different call shapes into one method made the signature hard to read and to type correctly.
Calling it with more than 2 arguments — i.e. using it to set several date or time components at once — is now deprecated in favor of two dedicated methods.
Example
<?php
$calendar = IntlCalendar::createInstance('UTC');
$calendar->set(2026, 0, 1, 12, 30, 0);
?>
Alternatives
- Use
IntlCalendar::setDate()to set the year, month and day, orIntlCalendar::setDateTime()to also set the hour, minute and second.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling IntlGregorianCalendar::__construct() with more than 2 arguments is deprecated,
Description
IntlGregorianCalendar::__construct() (and the procedural intlgregcal_create_instance()) used to accept many different combinations of arguments: a timezone, a locale, or up to a year, month, day, hour, minute and second, all disambiguated at runtime from the number and type of arguments given.
Calling the constructor with more than 2 arguments — i.e. using it to build a date directly from year/month/day(/hour/minute/second) components — is now deprecated in favor of two dedicated, unambiguous factory methods.
Example
<?php
$calendar = new IntlGregorianCalendar(2026, 0, 1, 12, 30, 0);
?>
Alternatives
- Use
IntlGregorianCalendar::createFromDate()to build a calendar from a year, month and day, orIntlGregorianCalendar::createFromDateTime()to also set the hour, minute and second.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling ldap_connect() with Oracle-specific arguments is deprecated
Description
When PHP’s LDAP extension is built against Oracle Instant Client, ldap_connect() gained two extra, Oracle-specific parameters ($wallet and $wallet_passwd, plus an $auth_mode flag) on top of the hostname and port, to authenticate using an Oracle wallet.
This Oracle-only overload is now deprecated along with the rest of ldap_connect()’s multi-argument forms, in favor of a dedicated function that only exists in Oracle-enabled builds.
Example
<?php
$ldap = ldap_connect('ldap.example.com', 389, '/path/to/wallet', 'wallet_password', 1);
?>
Alternatives
- Use
ldap_connect_wallet()to connect with an Oracle wallet instead of passing wallet arguments toldap_connect().
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling ldap_exop() with more than 4 arguments is deprecated, use ldap_exop_sync() instead
Description
ldap_exop() used to serve two purposes at once: sending an LDAP extended operation and, when called with 5 or 6 arguments, also synchronously waiting for the response and returning its data and OID through reference parameters (&$response_data, &$response_oid).
Mixing the asynchronous, low-level operation with an optional synchronous, high-level convenience wrapper in a single overloaded function made the API harder to reason about. Calling ldap_exop() with more than 4 arguments is now deprecated in favor of a dedicated synchronous function.
Example
<?php
$ldap = ldap_connect('ldap://ldap.example.com');
ldap_bind($ldap);
ldap_exop($ldap, LDAP_EXOP_WHO_AM_I, null, null, $response_data, $response_oid);
?>
Alternatives
- Use
ldap_exop_sync()when you need to send the operation and immediately read back its response data and OID.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling mb_check_encoding() without argument is deprecated
Description
mb_check_encoding() normally takes a string (or an array of strings) and checks whether it is valid in a given encoding. It could also be called with no arguments at all, in which case the documentation claimed it would check $_GET, $_POST, $_SERVER, and other superglobal input for encoding validity.
In practice, this zero-argument form was never fully implemented: it only reported whether any invalid byte sequences had been detected so far during the request, rather than actually checking all of the input again. Because this behavior is confusing and unreliable, calling mb_check_encoding() without an argument is deprecated as of PHP 8.1.0.
Example
<?php
// Called without any argument.
var_dump(mb_check_encoding());
?>
Alternatives
- Pass the value to check explicitly, e.g.
mb_check_encoding($value, 'UTF-8'). - Validate each relevant superglobal entry individually instead of relying on the implicit whole-request check.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See mb_check_encoding
Calling pg_fetch_result() with 2 arguments is deprecated,
Description
pg_fetch_result() originally accepted two different call shapes: a 3-argument form giving the row and field explicitly, and a 2-argument form that omitted the row and implicitly fetched from an internal, auto-advancing row cursor. Mixing an explicit-row API and a stateful, cursor-based one in a single overloaded function made the behavior harder to predict, especially when other calls interleaved with the cursor’s position.
As of PHP 8.4, calling pg_fetch_result() with only 2 arguments is deprecated in favor of always passing 3 arguments, using null explicitly for $row when the old auto-advancing behavior is wanted.
Example
<?php
$conn = pg_connect('host=localhost dbname=test');
$result = pg_query($conn, 'SELECT id, name FROM users');
// 2-argument form: relies on an implicit "current row" cursor
echo pg_fetch_result($result, 'name'), "\n";
?>
Literal Examples
- Calling pg_fetch_result() with 2 arguments is deprecated, use the 3-parameter signature with a null $row parameter instead
Alternatives
- Call pg_fetch_result() with 3 arguments, passing null as $row to keep the auto-advancing cursor behavior explicitly.
- Track the row index yourself and always pass it explicitly, instead of relying on the implicit cursor.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling ReflectionMethod::__construct() with 1 argument is deprecated,
Description
ReflectionMethod::__construct() originally accepted two call shapes: two arguments, new ReflectionMethod($classOrObject, $methodName), or a single string combining both as "Class::method". Overloading the constructor based on argument count made its signature harder to type and to document.
PHP 8.3 added ReflectionMethod::createFromMethodName() as a dedicated factory method for the single-string form. As of PHP 8.4, calling the constructor with only 1 argument is deprecated in favor of that factory method.
Example
<?php
// Single string argument, combining class and method with '::'
$method = new ReflectionMethod('DateTime::format');
echo $method->getName(), "\n";
?>
Literal Examples
- Calling ReflectionMethod::__construct() with 1 argument is deprecated, use ReflectionMethod::createFromMethodName() instead
Alternatives
- Use ReflectionMethod::createFromMethodName(‘Class::method’) instead of new ReflectionMethod(‘Class::method’).
- Use the 2-argument constructor, new ReflectionMethod($classOrObject, $methodName), when the class and method are already available separately.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Calling static trait method %s::%s is deprecated
Description
Traits cannot be used independently from a host class. They must be used inside a class, with the use keyword.
Until PHP 8.1, it was possible to call traits without a host class. Since 8.1, calling a trait method is deprecated.
It is also not possible to call a method or a property on a trait.
Example
<?php
trait T {
public static function foo() { echo __METHOD__; };
}
t::foo();
?>
Literal Examples
- Calling static trait method T::foo is deprecated
Alternatives
- Use the trait in a class and access its features.
- Convert the trait into a class and access its features.
Related error messages
Calling stream_context_set_option() with 2 arguments is deprecated,
Description
stream_context_set_option() originally accepted two call shapes: a 4-argument form setting a single wrapper/option/value triple, and a 2-argument form that instead took a whole nested ["wrapper"]["option"] = value array in place of the last three arguments. Overloading a single function with such different shapes made the signature hard to express with proper types.
PHP 8.3 added a dedicated stream_context_set_options() function for the array form. As of PHP 8.4, calling stream_context_set_option() with only 2 arguments is deprecated in favor of that new function.
Example
<?php
$context = stream_context_create();
// 2-argument form: context + a full ["wrapper"]["option"] = value array
stream_context_set_option($context, ['http' => ['method' => 'POST']]);
?>
Literal Examples
- Calling stream_context_set_option() with 2 arguments is deprecated, use stream_context_set_options() instead
Alternatives
- Use stream_context_set_options($context, $options) instead of stream_context_set_option($context, $options) for the array form.
- Use the 4-argument form, stream_context_set_option($context, $wrapper, $option, $value), to set a single option.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Can’t inherit abstract function %s::%s() (previously declared abstract in %s)
Description
In PHP 7.0 and 7.1, it was not possible to inherit an abstract class. In PHP 7.2, it was made possible.
Example
<?php
abstract class A { abstract function bar(stdClass $x); }
abstract class B extends A { abstract function bar($x): stdClass; }
// Fatal error: Can't inherit abstract function A::bar()
?>
Literal Examples
- Can't inherit abstract function B::bar() (previously declared abstract in A)
Alternatives
- Upgrade to PHP 7.2 or later.
- Remove the
abstractkeyword. - Remove the method.
Can’t use function return value in write context
Description
A write context is any position that needs an actual variable slot to write to, remove, or bind a reference to: the left side of an assignment, the target of unset(), a foreach-by-reference variable, and similar. A function call only produces a value; it does not designate a storage location, so the engine has nothing to write to, unset, or reference, and rejects the call outright at compile time, before it is ever executed.
Example
<?php
function getValue() {
return 5;
}
getValue() = 3;
unset(getValue());
?>
Alternatives
- Store the return value in a variable first, then use the variable in the write context: $v = getValue(); unset($v);
Related error messages
- can’t-use-method-return-value-in-write-context
- cannot-use-result-of-built-in-function-in-write-context
- can’t-use-nullsafe-operator-in-write-context
- cannot-use-temporary-expression-in-write-context
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Can’t use method return value in write context
Description
A write context is any position that needs an actual variable slot to write to, remove, or bind a reference to: the left side of an assignment, the target of unset(), a foreach-by-reference variable, and similar. This is the same restriction as for plain function calls, reported with a distinct message because the engine recognizes method calls (instance calls with ->, and static calls with ::) as a separate kind of AST node from ordinary function calls. A method call only produces a value; it does not designate a storage location, so it is rejected at compile time, before the method is ever invoked.
Example
<?php
class Foo {
public function getValue() {
return 5;
}
}
(new Foo())->getValue() = 3;
unset((new Foo())->getValue());
?>
Alternatives
- Store the return value in a variable first, then use the variable in the write context: $v = (new Foo())->getValue(); unset($v);
Related error messages
- can’t-use-function-return-value-in-write-context
- cannot-use-result-of-built-in-function-in-write-context
- can’t-use-nullsafe-operator-in-write-context
- cannot-use-temporary-expression-in-write-context
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Can’t use nullsafe operator in write context
Description
The nullsafe operator is only available for reading, not writing. Aka, it cannot be used on the left side of an assignation.
The nullsafe operator replaces any non-existing property with a null value: that value is not an object, and cannot handle properties on its own.
This limitation applies to assignations, short assignations, such as .=, +=, etc., pre and post incrementations ++$a->b, and references arguments.
Example
<?php
$x = new stdClass();
$x?->a = 1;
?>
Alternatives
- Use the
->operator for writing operations.
Related error messages
- can’t-use-function-return-value-in-write-context
- can’t-use-method-return-value-in-write-context
- cannot-combine-nullsafe-operator-with-closure-creation
- cannot-take-reference-of-a-nullsafe-chain
Can only flip string and integer values, entry skipped
Description
array_flip() converts values into keys and keys into values. The former values undergo a process to convert them to valid keys, which are strings or integers.
In general, non-scalar values cannot be converted, and are skipped: this is the case of arrays.
In particular, string or integer backed enumerations and stringable objects are not converted to strings. This applies with or without strict_types.
Example
<?php
array_flip([[1], E::A, new X])
enum E : string {
case A = 'a';
}
class X implements Stringable {
function __toString() {
return 'X';
}
}
?>
Alternatives
- Force the type to be string when building the array.
- Apply a converting method with array_map(), before calling array_filter.
Can only throw objects
Description
The throw keyword operates on exceptions, which are always objects. So, it is not possible to throw other types, such as integers, strings or arrays.
Example
<?php
throw 1;
?>
Alternatives
- Use
throw new Exception(). - Use
throw new Error(). - Use
throw $object, where $object contains an error or an exception. - Use
throw ($object), where $object contains an error or an exception.
Related error messages
Cannot %s readonly property %s::$%s from %s%s
Description
Until PHP 8.4, the assignation (first and final), of a readonly property had to be executed in the definition class. In the illustration, this means that $property must be assigned in the X class. This was applied all the time, without consideration for the visibility of the property.
Since PHP 8.4, visibility allowing, a readonly property may be defined in any of the child classes too.
Example
<?php
class X {
public readonly int $property;
}
class Y extends X {
function __construct() {
$this->property = 5;
}
}
$x = new Y;
echo $x->property;
?>
Literal Examples
- Cannot initialize readonly property X::$property from scope Y
- Cannot initialize readonly property X::$property from global scope
Alternatives
- Upgrade to PHP 8.4.
- Remove the readonly option.
Cannot access %s const %s::%s
Description
Constants have visibility, which restrict access to the defining class (private), or the class and its children (protected).
Example
<?php
class X {
private const A = 1;
}
echo X::A;
?>
Literal Examples
- Cannot access private constant X::A
Alternatives
- Relax the visibility constraint to
protectedorpublicto make the constant available to the calling context. - Create a method to access the value of the constant.
- Extends the class and change the visibility level of the constant.
Related error messages
In more recent PHP versions, this error message is now :ref:cannot-access-%s-constant-%s::%s.
Cannot access %s constant %s::%s
Description
Class constants have visibility, which restrict access to the defining class (private), or the class and its children (protected).
Example
<?php
class X {
private const A = 1;
}
echo X::A;
?>
Literal Examples
- Cannot access private constant X::A
Alternatives
- Relax the visibility constraint to
protectedorpublicto make the constant available to the calling context. - Create a method to access the value of the constant.
- Extends the class and change the visibility level of the constant.
Related error messages
In previous PHP versions, this error message used to be :ref:cannot-access-%s-const-%s::%s.
Cannot access %s property %s::$%s
Description
Properties have visibility, which restrict access to the defining class (private), or the class and its children (protected).
This applies to static and normal properties.
Example
<?php
class X {
private string $property = 'abc';
}
echo (new X)->property;
?>
Literal Examples
- Cannot access private property X::$property
- Cannot access protected property X::$property
Alternatives
- Relax the visibility constraint to
protectedorpublicto make the property available to the calling context. - Create a method to access the value of the property.
- Extends the class and change the visibility level of the property from
protectedtopublic. This has no effect forprivate.
Related error messages
Cannot access offset of type %s in isset or empty
Description
In an array notation, the offset may be a variable, or any container. Yet, it must be a string or an integer; and when applied to an string, it must be an integer.
This error is reported when a value which type is not cast to integer (such as null, boolean, float) or string is used. Here, it is an object.
It is also a specific message, emitted when the error happens as an argument of isset or empty. Both function have an error suppression feature, and yet, this error is reported.
Example
<?php
// illustration example
$object = new Stdclass;
$string = 'abc';
echo isset($string[$object]);
?>
Literal Examples
- Cannot access offset of type stdClass in isset or empty
Alternatives
- Check the type of the index before using it in the array notation.
- Check the type of the underlying object, using the array notation.
- Cast the index to
(string)or(int)when using it in the array notation.
Related error messages
Cannot access offset of type %s on %s
Description
In an array notation, the offset may be a variable, or any container. Yet, it must be a string or an integer; and when applied to an string, it must be an integer.
This error is reported when a value which type is not cast to integer (such as null, boolean, float) or string is used. Here, it is an object.
Note that a class that extends ArrayAccess interface allows the manipulation of any kind of key: this is possible, yet rare.
This error message has been extended to more types than string : for example, array.
Example
<?php
// illustration example
$object = new Stdclass;
$string = 'abc';
echo $string[$object];
$array = [];
echo $array[$object];
function foo(A $a) {
$string = 'abc';
echo $string[$a];
}
?>
Literal Examples
- Cannot access offset of type stdClass on string
- Cannot access offset of type stdClass on array
Alternatives
- Check the type of the index before using it in the array notation.
- Check the type of the underlying object, using the array notation.
- Cast the index to
(string)or(int)when using it in the array notation.
Related error messages
- illegal-offset-type
- illegal-offset-type-in-unset
- illegal-offset-type-in-isset-or-empty
- cannot-auto-initialize-an-array-inside-property-%s::$%s-of-type-%s
Cannot access parent:: when current class scope has no parent
Description
The trait X has a property, which is typed with a relative type: parent. Yet, as a trait, there is no parent class possible.
This situation is solved when the trait is use d in a class, as long as the class has a parent. But it is not possible directly on the trait.
This error is now covered with the upcoming deprecation of direct manipulation of static properties on a trait, without using its host class.
This error is also possible with self. It is not possible with static, as properties can’t be typed static.
This error is also possible on interfaces.
Example
<?php
trait X {
public static parent $property;
}
try {
Test::$property = new stdClass;
} catch (Error $e) {
echo $e->getMessage(), PHP_EOL;
}
?>
Alternatives
- Do not use
parentorselfkeywords in interfaces. Use an actual class name. - Do not use
parentorselfkeywords in traits. Use an actual class name. - Do not use
parentorselfkeywords in enumerations. Use an actual class name.
Cannot access parent:: when no class scope is active
Description
parent refers to the parent class of the one. As such, parent can only be used inside a class or a trait.
Example
<?php
static::x;
?>
Alternatives
- Move the code inside a method, in a trait or a class.
- Use the full name of the class that should be used.
Cannot access self:: when no class scope is active
Description
self refers to the curent class of the one. As such, self can only be used inside a class or a trait.
Example
<?php
static::x;
?>
Alternatives
- Move the code inside a method, in a trait or a class.
- Use the full name of the class that should be used.
Cannot access static:: when no class scope is active
Description
static refers to the class that was called to access the class elements (constants, method, properties..). As such, static can only be used inside a class or a trait.
Example
<?php
static::x;
?>
Alternatives
- Move the code inside a method, in a trait or a class.
- Use the full name of the class that should be used.
In more recent PHP versions, this error message is now :ref:cannot-use-"static"-when-no-class-scope-is-active.
Cannot access trait constant %s::%s directly
Description
Traits cannot be used indepently from a host class. They must be used inside a class, with the use keyword.
It is also not possible to call a method or a property on a trait.
Trait constants were introduced after direct access to trait features was banned, so there was no time where accessing a trait constant was possible, unlike trait properties or methods.
Example
<?php
trait T {
public static const C = 1;
}
echo T::C;
?>
Literal Examples
- Cannot access trait constant T::C directly
Alternatives
- Use the trait in a class and access its features.
- Convert the trait into a class and access its features.
Related error messages
- accessing-static-trait-property-%s::$%s-is-deprecated
- calling-static-trait-method-%s::%s-is-deprecated
- traits-cannot-have-constants
- accessing-static-trait-property-%s::$%s-is-deprecated,-it-should-only-be-accessed-on-a-class-using-the-trait
In previous PHP versions, this error message used to be :ref:traits-cannot-have-constants.
Cannot acquire reference to $GLOBALS
Description
It is not possible to create a reference to a the superglobal $GLOBALS. The property is readonly and cannot be changed. On the other hand, references are never readonly, and provide read and write access to the data. PHP has no way to check that the reference is readonly. Hence, references on readonly properties are not allowed.
Example
<?php
// Cannot acquire reference to $GLOBALS
$a = &$GLOBALS;
?>
Alternatives
- Remove the readonly option on the property.
- Remove the reference to the property.
Related error messages
Cannot acquire reference to readonly property %s::$%s
Description
It is not possible to create a reference to a readonly property. The property is readonly and cannot be changed. On the other hand, references are never readonly, and provide read and write access to the data. PHP has no way to check that the reference is readonly. Hence, references on readonly properties are not allowed.
Example
<?php
class Test {
public readonly int $property;
public function init() {
$this->property = 1;
}
}
$test = new Test;
$test->init();
try {
foreach ($test as &$property) {}
} catch (Error $e) {
echo $e->getMessage(), \n;
}
?>
Literal Examples
- Cannot acquire reference to readonly property Test::$property
Alternatives
- Remove the readonly option on the property.
- Remove the reference to the property.
Cannot add element to the array as the next element is already occupied
Description
This error appears when the largest PHP integer has been used as an index in an array. When appending a new item in the array, PHP calculates the largest index, and adds one. Though, in this situation, it is not possible anymore to create a new integer, since the last one was used.
This error appears when a value was stored out of the way, yet the array is appended later.
Example
<?php
$array = [0 => 'a', PHP_INT_MAX => 'b'];
$array[] = 3;
?>
Alternatives
- Avoid using PHP_INT_MAX as index in the array.
- Assign the value with an explicit index, rather than an append.
Cannot append to $GLOBALS
Description
$GLOBALS is not a regular array: each of its entries is really a reference to a variable in the global scope, identified by its name. Appending with the empty-bracket operator, which would normally pick the next integer key, has no matching global variable to bind to, so PHP 8.1 turned this previously-meaningless operation into a compile-time error instead of silently creating a global variable literally named “0”.
Example
<?php
$GLOBALS[] = 'value';
?>
Alternatives
- Assign to an explicit, named key instead: $GLOBALS[‘name’] = ‘value’;
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See GLOBALSAppend
Cannot append to WeakMap
Description
WeakMap is a map from objects to values, and each key is an object. Unlike an array, it has no automatic integer index, so the [] syntax, which appends a new element, cannot be used with it.
To add an entry, give the object that will be the key: $map[$object] = $value.
Example
<?php
$map = new WeakMap();
// A WeakMap is keyed by objects, so there is no next integer key to append to
$map[] = 'Damien';
?>
Literal Examples
- Cannot append to WeakMap
Alternatives
- Use an object as the key:
$map[$object] = $value, instead of$map[] = $value. - If you need a list of values with integer keys, use a regular
arrayinstead of aWeakMap.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot apply #[AllowDynamicProperties] to enum %s
Description
The attribute AllowDynamicProperties has no meaning when used with an enumeration, even as enums can define properties.
Example
<?php
#[AllowDynamicProperties]
enum E {}
?>
Literal Examples
- Cannot apply #[AllowDynamicProperties] to enum e
Alternatives
- Do not use the attribute on an enumeration.
Cannot apply #[AllowDynamicProperties] to interface %s
Description
The attribute AllowDynamicProperties has no meaning when used with a interface, even as interface can define properties. Apply it to any class that implements the interface.
Example
<?php
#[AllowDynamicProperties]
interface I {}
?>
Literal Examples
- Cannot apply
#[AllowDynamicProperties]to interface i
Alternatives
- Use the attribute on the class that implements the interface.
Cannot apply #[AllowDynamicProperties] to readonly class %s
Description
Readonly classes are classes whose properties are set once, and never changed afterwards. The readonly option may be added to the individual property, or globally, at the class level.
Since PHP 8.1, dynamic properties are deprecated. A dynamic property is a property which is used at execution time, aka $object->dynamic = 2;, and has no explicit definition in the class block. Dynamic properties are created, yet they don’t have any option, including the readonly option. In consequence, #[AllowDynamicProperties] and readonly at the class level are incompatible.`.
Example
<?php
#[AllowDynamicProperties]
readonly class X {
private $property = 1;
}
?>
Literal Examples
- Cannot apply #[AllowDynamicProperties] to readonly class x
Alternatives
- Remove
readonlyfrom the class, and add it to all the properties in the class. - Create a
readonlyproperty with a another class which use the#[AllowDynamicProperties]attribute. - Create a
readonlyproperty with an array type, and use it to process the dynamic entries. - Remove the
#[AllowDynamicProperties]attribute.
Cannot apply #[AllowDynamicProperties] to trait %s
Description
The attribute AllowDynamicProperties has no meaning when used with a trait, even as traits can defined properties. Apply it to any class that uses the trait.
Example
<?php
#[AllowDynamicProperties]
trait T {}
?>
Literal Examples
- Cannot apply #[AllowDynamicProperties] to trait t
Alternatives
- Use the attribute on the class that use the trait.
Cannot apply attributes to multiple constants at once
Description
It is not possible to use attributes on global constants, when several constants are defined at the same time. That syntax is possible with class constants, but not with global constants.
Example
<?php
#[Foo]
const A = 1,
B = 2;
?>
Alternatives
- Split the constant definitions, and apply the same attribute to each of them.
- Convert the global constants to class constants.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot assign %s to class constant %s::%s of type
Description
Since PHP 8.3, constants may have a type specification. In this case, the default value must match the requested type.
In particular, there is not type juggling, so type has to match exactly.
Example
<?php
class X {
const int A = '3';
}
?>
Literal Examples
- Cannot assign string to class constant x::A of type int
Alternatives
- Drop the default value.
- Adapt the default value to the requested type.
- Drop the type of the constant.
Cannot assign %s to property %s::$%s of type %s
Description
This error signals that the wrong type of data was used when assigning a value to a property. When a type is set on a property, it is always expected to receive that type.
Example
<?php
class X {
public int $property;
}
$x = new X;
$x->property = 'de';
?>
Literal Examples
- Cannot assign string to property X::$property of type int
Alternatives
- Add the type of this value to the type description.
- Remove the type on the property.
- Cast the value to the correct type.
Cannot assign %s to reference held by property %s::$%s of type %s
Description
When a variable holds a reference to a property, it also has to satisfy the type constraints. Here, by using a typed reference, the $var variable looks like another local variable, but it is in fact typed.
Example
<?php
class X {
public static int $int = 1;
}
$var = &X::$int;
$var = 'abc';
?>
Literal Examples
- Cannot assign string to reference held by property X::$int of type int
Alternatives
- Remove the type from the property.
- Use a valid value to the property.
- Remove the initial link to the property until the value is of the correct type.
Cannot assign an empty string to a string offset
Description
It is possible to access an individual character inside a string, and replace it with another character.
On the other hand, it is not possible to remove that character by using an empty string. The only allowed modification is a replacement: one character replace another character.
In fact, PHP will only use the first character, when trying to modify an offset with a string longer than one character.
Example
<?php
$string = 'ab d';
$string[2] = 'c'; // add c in the right place
$string[2] = ''; // error
$string[2] = 'Cdef'; // only sets the c
?>
Alternatives
- Use substr() to cut the string before and after, then concatenate them.
- Replace the character with a space.
Cannot assign reference to non referenceable value
Description
It is possible to assign values by references, only when the right operand is already stored in a variable, or similar.
Example
<?php
list(&$x) = [1, 2];
$array = [1,2];
list(&$x, ) = $array
?>
Alternatives
- Store the operand in a variable (or equivalent).
- Assign values individually.
Cannot assign to array(), use [] instead in %s
Description
The left array is actualy the list instruction. With that, PHP tries to assign each values of the array on the right to their same position on the left. In this case, there is an array, and it is not possible to assign directly to an array: it could be assigned to an element of that array, just not the whole array.
Example
<?php
[array($a)] = [array(42)];
var_dump($a);
?>
Alternatives
- Remove the array() on the left.
- Remove the [] on the left.
- Replace the
=with an==operator, to convert this into an assignation.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot assign to array(), use [] instead
Description
array(…) is a language construct that builds a new array value; it does not designate a destructurable container the way list(…) or the short […] syntax do, so it can never appear on the left-hand side of an assignment. This dedicated error exists to catch the common mistake of typing array(…) where list(…) was meant, and points directly to the short-syntax alternative.
Example
<?php
$data = [1, 2];
array($a, $b) = $data;
?>
Alternatives
- Use list(): list($a, $b) = $data;
- Use the short destructuring syntax: [$a, $b] = $data;
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot auto-initialize an array inside property %s::$%s of type %s
Description
The last command is using the array syntax on the property $property. In fact, the property is of type bool.
If this was a variable, this would be tolerated, but it cannot happen on a property, which enforces the types at all times.
Indeed, if the union type bool|array is used, the automatic conversion to array is reported.
When the type of the property is string, the array syntax is partially supported: it works with integer index, and fails with strings.
Example
<?php
class X {
public bool $property = false;
}
$x = new X;
$x->property[4] = 3;
?>
Literal Examples
- Cannot auto-initialize an array inside property X::$property of type bool
- Cannot auto-initialize an array inside property X::$property of type int
Alternatives
- Convert the type of the property to array.
- Create a distinct property, with the array type, to use the array syntax.
Related error messages
cannot be 0
Description
The third argument of range() is the step: the amount to progress for each element, compared to the previous one. When that step is null, the range() function always creates the same element, with no chance to finish. This cannot be 0.
Example
<?php
$interval = range(10, 20, 0);
?>
Alternatives
- Use a value strictly non-zero.
cannot be a class constant
Description
Class constants must be defined in classes, enums, traits or interfaces. They cannot be created dynamically, nor with the define() function.
Example
<?php
define('foo::bar', 1);
define('::', 1);
?>
Alternatives
- Define the class constant in a class.
- Define the class constant in a trait.
- Define the class constant in a interface.
- Define the class constant in a enum.
- Define the global constant, and use it as a value for the class constant.
cannot be empty
Description
The provided parameter is of the valid type, but cannot be left empty.
Example
<?php
print_r(explode('', 'abc')); // Not possible with an empty delimiter
print_r(str_split(1, 'abc'));
?>
Alternatives
- When parsing data, make sure that the separator is not empty.
In previous PHP versions, this error message used to be :ref:empty-delimiter.
In more recent PHP versions, this error message is now :ref:must-not-be-empty.
cannot be LC_ALL
Description
The 3rd argument ($category) of dcgettext() and the 5th argument ($category) of dcngettext() cannot be LC_ALL.
Example
<?php
dcgettext('a', 'item', LC_ALL);
dcngettext('b', 'item', 'item2', 1, LC_ALL);
?>
Alternatives
- Use one of the valid categories: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
Related error messages
cannot be null when argument #1 ($objectOrMethod) is an object
Description
The ReflectionMethod class requires 2 argument: the first with the class, and the second with the method name. Passing one argument is deprecated.
Example
<?php
$x = new X();
$method = new ReflectionMethod($x);
?>
Alternatives
- Adds the name as second argument
method.
Related error messages
Cannot bind an instance to a static closure, this will be an error in PHP 9
Description
The Closure::bind() method gives the scope of execution of a closure. And a static closure uses no scope, so the bind() method fails.
Example
<?php
$closure = static function () { return __METHOD__;};
$closure->bindTo(new Stdclass());
$closure();
?>
Alternatives
- Remove the static option on the closure.
- Remove the call to
bind().
Related error messages
- cannot-rebind-scope-of-closure-created-from-method,-this-will-be-an-error-in-php-9
- cannot-bind-method-%s::%s()-to-object-of-class-%s,-this-will-be-an-error-in-php-9
- cannot-rebind-scope-of-closure-created-from-function,-this-will-be-an-error-in-php-9
- cannot-unbind-$this-of-closure-using-$this,-this-will-be-an-error-in-php-9
In previous PHP versions, this error message used to be :ref:cannot-bind-an-instance-to-a-static-closure.
Cannot bind an instance to a static closure
Description
The Closure::bind() method gives the scope of execution of a closure. And a static closure uses no scope, so the bind() method fails.
Example
<?php
$closure = static function () { return __METHOD__;};
$closure->bindTo(new Stdclass());
$closure();
?>
Alternatives
- Remove the static option on the closure.
- Remove the call to
bind().
Related error messages
In more recent PHP versions, this error message is now :ref:cannot-bind-an-instance-to-a-static-closure,-this-will-be-an-error-in-php-9.
Cannot bind method %s::%s() to object of class %s, this will be an error in PHP 9
Description
A closure created from a non-static method ($obj->method(...) or Closure::fromCallable()) can only be bound to an instance of the class the method belongs to, or one of its subclasses. Binding it to an object of an unrelated class, as done above with an instance of Y while the method is defined on X, is not allowed.
Since PHP 8.5, this operation already emitted an E_WARNING and the bind silently failed, returning null. It is now deprecated and will become a fatal error in PHP 9.0.
Example
<?php
class X {
public function method() {
return __METHOD__;
}
}
class Y {}
$x = new X;
$fn = $x->method(...);
$fn2 = Closure::bind($fn, new Y, Y::class);
var_dump($fn2);
?>
Literal Examples
- Cannot bind method X::method() to object of class Y, this will be an error in PHP 9
Alternatives
- Bind the closure to an instance of the class that declares the method, or one of its subclasses.
- If the method should work on unrelated classes too, extract the logic into a standalone function or a trait shared by both classes.
Related error messages
- cannot-bind-method-%s::%s()-to-object-of-class-%s
- cannot-bind-an-instance-to-a-static-closure,-this-will-be-an-error-in-php-9
- cannot-rebind-scope-of-closure-created-from-method,-this-will-be-an-error-in-php-9
Related error messages
In previous PHP versions, this error message used to be :ref:cannot-bind-method-%s::%s()-to-object-of-class-%s.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See closure
Cannot bind method %s::%s() to object of class %s
Description
This error is reported when a closure is called on an object which is not identical to the the type of the original object.
Example
<?php
class X {
public function method() { }
}
class Y { }
$closure = Closure::fromCallable([new X, 'method']);
$closure->call(new B);
?>
Literal Examples
- Cannot bind method A::M() to object of class C
Alternatives
- Make sure the new object is of the same type as the original support one.
Related error messages
In more recent PHP versions, this error message is now :ref:cannot-bind-method-%s::%s()-to-object-of-class-%s,-this-will-be-an-error-in-php-9.
Cannot call %pS() dynamically
Description
A handful of built-in functions, such as compact(), extract(), func_get_args(), func_get_arg() and func_num_args(), work by inspecting the calling scope directly. Because of that, they can only be called by writing their name literally in the source code; they cannot be called dynamically, for example through a variable holding the function name, call_user_func(), or the first-class callable syntax. This restriction predates PHP 8.6: the Closure produced by $fn(...) above is created successfully, but throws this Error the moment it is actually invoked.
PHP 8.6 introduces Partial Function Application (the ? and ... placeholders), which is built on the same compiler as first-class callable syntax. Using a placeholder call such as compact(?, ?) on one of these scope-dependent functions hits the same restriction, but does so immediately, while the partial-application expression itself is being compiled, rather than only when the resulting closure is later called.
Example
<?php
$fn = 'compact';
// First-class callable syntax applied to a variable function name
$partial = $fn(...);
$partial('a', 'b');
?>
Literal Examples
- Cannot call compact() dynamically
- Cannot call extract() dynamically
- Cannot call func_get_args() dynamically
Alternatives
- Call the function by writing its literal name in the source, instead of through a variable, callback, or Partial Function Application.
- For compact()/extract(), pass the variables or array explicitly instead of relying on the calling scope.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [The restriction and its message text are unchanged. PHP 8.6 only changes when it is reported for these functions when used with Partial Function Application placeholders: the error now surfaces while compiling the partial-application expression, instead of only when the resulting Closure is later called.](The restriction and its message text are unchanged. PHP 8.6 only changes when it is reported for these functions when used with Partial Function Application placeholders: the error now surfaces while compiling the partial-application expression, instead of only when the resulting Closure is later called.)
Cannot call constructor
Description
When there is no need to define a constructor, it may be skipped. Then, PHP creates the object without that initial method call.
On the other hand, if a child class makes an explicit call to the parent constructor, then on of the parents MUST have a constructor.
In the example here, the child class explicitly calls the parent constructor, but it doesn’t exists.
Example
<?php
class X {}
class Y extends X {
function __construct() {
parent::__construct();
}
}
?>
Alternatives
- Create an empty constructure in a parent, to ensure its calling.
- Skip the call to the parent constructor in the child: it is useless anyway.
Cannot change default fetch mode while fetching
Description
PDOStatement::setFetchMode() refuses to run while the statement is in the middle of fetching a row. This happens when PDO::FETCH_CLASS is used and the constructor of the target class receives the statement object itself (via the constructor arguments) and calls setFetchMode() on it before the current fetch() call has finished.
Prior to this guard, such a re-entrant call could corrupt the statement’s internal fetch state and lead to a use-after-free. PDO now detects the situation and throws an Error instead.
Example
<?php
class Test {
public string $val1;
public string $val2;
public function __construct(mixed $stmt) {
if ($stmt instanceof PDOStatement) {
// Re-entrant call -- the statement is still fetching the current row
$stmt->setFetchMode(PDO::FETCH_CLASS, self::class, [$this->val2]);
}
}
}
$stmt = $pdo->prepare('SELECT val1, val2 FROM example');
$stmt->setFetchMode(PDO::FETCH_CLASS, Test::class, [$stmt]);
$stmt->execute();
$stmt->fetch();
?>
Alternatives
- Call
setFetchMode()beforefetch()/fetchAll()starts, never from within a constructor triggered by the fetch itself. - Avoid passing the live
PDOStatementas a constructor argument to the fetched class; pass the data it needs instead. - If the fetch mode must change mid-iteration, finish consuming the current row first, then call
setFetchMode()before the nextfetch().
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot combine named arguments and argument unpacking
Description
In PHP 8.0, named parameters were introduced. They allow the naming of a parameter, which is used later to assign the value to the parameter, based on names and not on position.
Initially, it was not possible to mix unpacked arguments from an array and parameters.
Example
<?php
function foo(...$params) {
print_r($params);
}
$args = [1, 2];
foo(...$args, params: 1);
?>
Alternatives
- Upgrade PHP version to 8.1 or later.
- Move the arguments in the array, and unpack it.
Related error messages
Cannot combine nullsafe operator with Closure creation
Description
PHP 8.1 introduced the first class callable syntax, using (...) to create a Closure from a method or function call, without invoking it.
The nullsafe operator ?-> short-circuits the call when the object is null, evaluating to null instead. Combined with Closure creation, this would mean the expression sometimes returns a Closure and sometimes null, which is not a coherent result for the engine to compile.
This combination is therefore forbidden, and detected at compile time.
Example
<?php
class X {
public function foo() {}
}
$x = new X();
$closure = $x?->foo(...);
?>
Alternatives
- Use the
->operator instead of?->, making sure the object is nevernullat that point. - Check the object for
nullexplicitly, before creating the Closure.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot combine partial application and unpacking
Description
PHP 8.5 extends the first-class callable syntax with partial application: a lone … placeholder as the last argument of a call turns it into a Closure over the remaining, not-yet-supplied parameters. The same … token is already used for argument unpacking (spreading an array’s values as arguments), so a call that both spreads an array and ends with the placeholder is ambiguous between “spread this array, then partially apply” and a typo, and PHP rejects it outright.
Example
<?php
function add($a, $b, $c) {
return $a + $b + $c;
}
$args = [1, 2];
$curried = add(...$args, ...);
?>
Alternatives
- Wrap the call in an explicit closure instead: $curried = fn($c) => add(…$args, $c);
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot create Closure as attribute argument
Description
It is possible to use ... in a function call, but not as an attribute, as it leads to create a PHP closure, which does not carry the Attribute attribute (sic). It also makes little sense, though the PHP parser accepts it, but not the linter.
Example
<?php
#[Foo(...)]
function goo() {}
?>
Alternatives
- Remove the three dots from the attribute.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot create Closure for new expression
Description
When using the ... ellpsis operator as an argument, it creates a closure, based on the current function or method. While the syntax can be linted by PHP, it is not possible to use it with a new operator.
Example
<?php
class X {
function __construct() {}
}
$closure = new X(...);
?>
Alternatives
- Make a closure that takes the arguments, and relay them to the
newoperator. - Create a named constructor, and make a closure from this.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot create Closure for parent property hook call
Description
parent::$property::get() (and ::set()) is dedicated syntax, resolved at compile time, that invokes the property hook implementation the current class overrides. It does not correspond to a standalone, independently callable method the way parent::method() does, so it cannot be captured as a first-class callable / Closure.
Example
<?php
class Base {
public string $name = '' {
get => $this->name;
}
}
class Child extends Base {
public string $name = '' {
get {
$fn = parent::$name::get(...);
return $fn();
}
}
}
?>
Alternatives
- Call the parent hook directly instead of turning it into a Closure: parent::$name::get().
- Wrap the call yourself in an ordinary closure: $fn = fn() => parent::$name::get();
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot create dynamic property %s::$%s
Description
It is not possible to add a property to an enumeration, and it is also not possible to create a property dynamically, on an enumeration object. This is valid for both normal and static properties.
This error message also appears when the class is readonly: then, it is not possible to create any dynamic property.
Example
<?php
enum E: int {
case Foo = 0;
}
$variable = E::Foo;
$variable->property = 1;
readonly class X {}
$x = new X;
$x->p = 1;
?>
Literal Examples
- Cannot create dynamic property E::$property
Alternatives
- Don’t create a property on an enumeration.
- Don’t create a property on a readonly class.
- Encapsulate the enumeration in an another class, and set the property on this class.
Cannot create reference to property %s::$%s
Description
While it is possible to acquire a reference on an object’s property, it is not possible to acquire that reference on a property with hooks. By default, the property hook is returned by value, and cannot accomodate the reference. Unless the property hooks is made by reference, with a & before the name of the hook.
The message is also related to using an object in a foreach loop. There is a different message for direct creation of a reference on a property.
Example
<?php
class X {
public $byRef {
get {
$x = 42;
return $x;
}
}
}
foreach (new X as $prop => &$value) {
var_dump($value);
}
?>
Alternatives
- Add
&before thegethook. - Make the property a normal property, without hooks.
- Avoid using a reference on a property hook.
Related error messages
Cannot declare const %s because
Description
This error is the constant counterpart of the use collision error raised for classes and functions: it fires when a top-level const declaration reuses a name that was already brought into the current file through a use const ... as ... import.
The full message reads: Cannot declare const %s because the name is already in use.
Example
<?php
use const App\FOO as BAR;
const BAR = 42;
?>
Literal Examples
- Cannot declare const BAR because the name is already in use
Alternatives
- Rename the
constdeclaration. - Change the alias used in the
use constimport.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot declare hooks for static property
Description
Static properties are not supported for property hooks. Property hooks are only for non-static methods.
Example
<?php
class X
{
public static string $property {
set => $this->property . _1;
SET {
$this->property = $value;
}
}
}
?>
Alternatives
- Make the property non-static.
- Create accessors for the static property.
Cannot declare promoted property in an abstract constructor
Description
It is not possible to use a promoted property in an abstract constructor. The promoted property is akin to concrete code (the property assignation), while the abstrat constructor has no body.
On the other hand, a child class may overwrite the constructor signature with a promoted property, so it is possible to define properties that way, but not on an abstract method.
In order to enforce a property, from an abstract class, the property must be defined out of the constructor.
Example
<?php
abstract class X {
abstract function __construct(private string $a);
}
?>
Alternatives
- Remove the abstract from the constructor.
- Define the property outside the construtor.
- Check all children classes, so they all have the promoted property in their constructor definition.
Cannot declare promoted property outside a constructor
Description
A promoted property is the declaration of a property, as part of the signature of the constructor. It is detected with the use of private, protected and public keyword, in the parameter signature. When these keyword are found in the signature of a method that is not the constructor, PHP emits this error.
Example
<?php
class X {
function foo(private int $p) {
}
}
?>
Alternatives
- Remove the private, protected or public keyword.
- Rename the method __construct, to make it the constructor.
- Move that parameter to the constructor.
Cannot declare self-referencing constant
Description
A self-referencing constant is a constant that is defined by itself.
This error doesn’t apply to global constants. The global constants are immediately made available, and, for that, they need to be evaluated: this leads to the error Undefined constant A.
Self-referencing constants are not allowed, contraty to self-referencing acronym, that PHP enjoys.
Example
<?php
class X {
const A = x::A + 1;
const B = self::C + 1;
const C = x::B + 1;
}
?>
Alternatives
- Create a distinct constant that can help build this one.
- Fix the name of the constant with a distinct one.
- Fix the name of the class with a distinct one.
Related error messages
Cannot declare variadic promoted property
Description
Properties may be declared, as an parameter in a constructor. Then, they also act as an parameter, and a local variable.
Variadic option is a parameter only option, which pack all the remaning arguments in the final parameter.
Variadic option makes no sense in a property definition, as only one value is stored there.
Example
<?php
class X {
function __construct(
private string ...$x
) {}
}
?>
Alternatives
- Remove the property definition from the constructor: keep the argument use the variadic, and define the property in the traditional way.
- Remove the variadic option.
Related error messages
- cannot-redeclare-%s::$%s
- only-the-last-parameter-can-be-variadic
- variadic-parameter-cannot-have-a-default-value
Cannot decrement property %s::$%s of type int past its minimal value
Description
When a property is typed as an int, it cannot have a value lower than PHP_INT_MIN. There is a symetric error with the max value of an integer.
Example
<?php
class X {
public int $p;
}
$x = new X;
$x->p = PHP_INT_MIN;
--$test->foo;
?>
Literal Examples
- Cannot decrement property Test::$p of type int past its minimal value
Alternatives
- Check the value before decrementing.
- Drop the type, but see the property get turned into a float.
Related error messages
Cannot deserialize ArrayObject with iterator class %s; this class is not derived from ArrayIterator
Description
ArrayObject can be constructed with a custom iterator class (via its second constructor argument), used in place of the default ArrayIterator whenever the object is iterated. That choice is preserved across serialize()/unserialize() by storing the iterator class name as part of the object’s serialized state, and restored inside ArrayObject::__unserialize().
Since that class name travels as a plain string inside the serialized payload, it can end up naming any class, including one with no relation to iteration at all, if the payload was tampered with or was produced by mismatched code. Since PHP 8.6, ArrayObject::__unserialize() requires the named class to actually extend ArrayIterator, and throws an UnexpectedValueException naming the class otherwise, rather than accepting any class that merely implements Iterator.
Example
<?php
$data = 'O:11:"ArrayObject":4:{i:0;i:0;i:1;a:0:{}i:2;a:0:{}i:3;s:8:"stdClass";}';
unserialize($data);
?>
Literal Examples
- Cannot deserialize ArrayObject with iterator class ‘stdClass’; this class is not derived from ArrayIterator
Alternatives
- Only unserialize ArrayObject data that was produced by trusted code, and make sure any custom iterator class passed to ArrayObject’s constructor extends ArrayIterator.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.6, the same UnexpectedValueException was thrown for a class that does not implement Iterator at all, with the message “Cannot deserialize ArrayObject with iterator class ‘%s’; this class does not implement the Iterator interface”. PHP 8.6 tightened the requirement from merely implementing Iterator to actually extending ArrayIterator, and reworded the message to match.](Prior to PHP 8.6, the same UnexpectedValueException was thrown for a class that does not implement Iterator at all, with the message “Cannot deserialize ArrayObject with iterator class ‘%s’; this class does not implement the Iterator interface”. PHP 8.6 tightened the requirement from merely implementing Iterator to actually extending ArrayIterator, and reworded the message to match.)
Cannot directly construct Directory, use dir() instead
Description
Directory is the object returned by the dir() function, giving access to path, handle, read(), rewind() and close(). It predates the rest of PHP’s object model and is a thin, internal wrapper around a directory stream: it has no public constructor of its own.
Calling new Directory(...) directly is rejected, because the object needs to be initialized with an already-opened directory handle, something only dir() can set up correctly.
Example
<?php
$d = new Directory('.');
?>
Alternatives
- Use
dir($path)to obtain aDirectoryobject. - Use
opendir(),readdir(),closedir()for a purely procedural approach instead of theDirectoryobject. - Use
DirectoryIteratororRecursiveDirectoryIteratorfor an object-oriented, iterable interface.
Related error messages
- sqlite3result-cannot-be-directly-instantiated
- the-sqlite3-object-has-not-been-correctly-initialised-or-is-already-closed
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot disable function %s()
Description
The disable_functions (and, for language constructs treated as functions internally, similarly-behaving) php.ini directive lets an administrator remove selected functions from the language, for hardening purposes. A handful of language constructs, namely exit/die and clone, are implemented internally as pseudo-functions so that they can be listed in disable_functions too, but they cannot actually be removed: doing so would leave the engine without a way to terminate a script or clone an object, both of which are needed by the engine itself.
Listing one of these three names in disable_functions does not stop PHP from starting; it only emits this warning once, at startup, and the name stays callable.
Example
; php.ini
disable_functions = exit,die,clone
Literal Examples
- Cannot disable function exit()
- Cannot disable function die()
- Cannot disable function clone()
Alternatives
- Do not list exit, die or clone in disable_functions; they cannot be disabled.
- To restrict script termination or cloning, use a different mechanism, such as static analysis, a coding standard, or a runtime policy (open_basedir, custom error/shutdown handlers) instead.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot increment property %s::$%s of type int past its maximal value
Description
When a property is typed as an int, it cannot have a value higher than PHP_INT_MIN: beyond it, it would be turned into a float. There is a symetric error with the min value of an integer.
Example
<?php
class X {
public int $p;
}
$x = new X;
$x->p = PHP_INT_MAX;
++$test->foo;
?>
Literal Examples
- Cannot increment property X::$p of type int past its maximal value
Alternatives
- Check the value before incrementing.
- Drop the type, but see the property get turned into a float.
Related error messages
Cannot indirectly modify readonly property %s::$%s
Description
A readonly property cannot be changed after it was set. This includes trying to reach the property via a reference.
Example
<?php
class X {
readonly public string $property;
public function __construct() {
$this->property = 'A';
}
}
$object = new X;
$variable =& $object->property;
class Y {
public funciton __construct(
readonly int &$y
) {}
}
?>
Literal Examples
- Cannot indirectly modify readonly property X::$property
Alternatives
- Do not create a reference to a readonly property.
- Do not create a referenced parameter with a promoted property.
Cannot inherit previously-inherited or override constant %s from interface %s
Description
Until PHP 8.1, it was not possible to override a constant when it was defined in an interface, even with the same definition.
Example
<?php
interface I {
const A = 1;
}
class X implements I {
const A = 2;
}
?>
Literal Examples
- Cannot inherit previously-inherited or override constant x from interface i
Alternatives
- Remove the constant from the class.
- Remove the constant from the interface.
- Move to PHP 8.1 or more recent.
Cannot instantiate enum %s
Description
Enumeration cannot be instantiated directly.
An enumeration object is created automatically when reading one of its case.
Example
<?php
enum E {
case A;
}
//Cannot instantiate enum E
new E();
// E
print get_class(E::A);
?>
Literal Examples
- Cannot instantiate enum e
Alternatives
- Use one of the enumeration cases.
Related error messages
Cannot instantiate interface %s
Description
An interface represents an abstract class, and cannot be instantiated alone. For that, the interface must be implemented by a class, aka, it must be specified with the implements keyword.
Example
<?php
interface I {}
//Cannot instantiate interface I
new I();
class XI implements I {
}
new XI();
?>
Literal Examples
- Cannot instantiate interface i
Alternatives
- Implement the interface with a class and use that class.
Related error messages
Cannot instantiate trait %s
Description
Traits cannot be instantiated directly. They need to be used in a class, or another trait, which will also need to be used in a class.
Example
<?php
trait T {}
//Cannot instantiate trait T
new T();
?>
Literal Examples
- Cannot instantiate trait t
Alternatives
- Use one of the class using that trait.
- Rewrite the trait into an class.
Related error messages
Cannot load module “%s” because required module “%s” is not loaded
Description
This is an error in the structure of the compiled PHP parser. PHP relies on extensions to provide features : xml, sql, http, etc. Sometimes, those extensions are build on top of other extensions: for example, the redis extension requires the json extension.
The names of the modules are displayed in the error messsage: check the installation procedure, as there might be missing extensions or libraries.
Here, modules is another name for a PHP extension.
Example
<?php
// well, the problem might also happen even before
// trying to execute that code
$redis = new Redis();
?>
Literal Examples
- Cannot load module “redis” because required module “redis” is not loaded
Alternatives
- Check the module list of PHP, and finish the installation of the missing extension.
- Remove the first module, which will remove the dependency on the second, and, its related features.
Cannot make non abstract method %s::%s() abstract in class %s
Description
Once a method has a body, it cannot be made abstract again.
On the other hand, the child class may be abstract, while the parent class is not. It just means that new methods must be implemented.
Example
<?php
class X {
function foo() {}
}
abstract class Y extends X {
abstract function foo();
}
?>
Alternatives
- Make the child class the parent.
- Change the name of the abstract method in the child class.
- Remove the abstract option in the child class.
- Add the abstract option in the parent class.
- Make the method abstract in the parent class.
Cannot make non static method %s::%s() static in class %s
Description
Once a method has been defined, the static keyword, or its absence, must be preserved for the same method in the children classes.
Example
<?php
class X {
function foo() {}
}
class Y extends X {
static function foo() {}
}
?>
Literal Examples
- Cannot make non static method X::foo() static in class Y
Alternatives
- Add the
statickeyword to the method in the parent class. - Remove the
statickeyword in all eponymous methods in the children class. - Rename some of the methods to avoid a
staticconflict.
Related error messages
Cannot make static method %s::%s() non static in class %s
Description
Once a method has been defined, the static keyword, or its absence, must be preserved for the same method in the children classes.
Example
<?php
class X {
function static foo() {}
}
class Y extends X {
function foo() {}
}
?>
Literal Examples
- Cannot make static method X::foo() non static in class Y
Alternatives
- Remove the
statickeyword to the method in the parent class. - Add the
statickeyword in all eponymous methods in the children class. - Rename some of the methods to avoid a
staticconflict.
Related error messages
Cannot mix [] and list()
Description
list() and the short [] syntax are two different notations for exactly the same destructuring construct. PHP requires a single destructuring expression to use one notation consistently at every nesting level; using list() for the outer pattern and [] for a nested one, or the other way around, is rejected at compile time even though each form is individually valid.
Example
<?php
$data = [1, [2, 3]];
list($a, [$b, $c]) = $data;
?>
Alternatives
- Use list() consistently at every level: list($a, list($b, $c)) = $data;
- Use the short [] syntax consistently at every level: [$a, [$b, $c]] = $data;
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot mix bracketed namespace declarations
Description
PHP supports two syntaxes to declare a namespace: the unbracketed form, namespace Foo;, which applies to the rest of the file (or until the next namespace statement), and the bracketed form, namespace Foo { ... }, which delimits the namespace explicitly.
A single file must consistently use one form or the other; mixing bracketed and unbracketed declarations together is not allowed. The full message reads: Cannot mix bracketed namespace declarations with unbracketed namespace declarations.
Example
<?php
namespace A {
// bracketed syntax
}
namespace B;
// unbracketed syntax, in the same file
?>
Alternatives
- Convert every
namespacestatement in the file to the bracketed form. - Convert every
namespacestatement in the file to the unbracketed form. - Split the file so that each file only uses one of the two forms.
Related error messages
- namespace-declarations-cannot-be-nested
- no-code-may-exist-outside-of-namespace-{}
- namespace-declaration-statement-has-to-be
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot mix keyed and unkeyed array entries in assignments
Description
list() is a construct that maps an array to a set of variables. The assignation is done by position, or by key. By position, this means the first value of the array goes to the first variable of the list() : in that case, list() doesn’t specify keys with the => operator. On the other hand, the key are matched by their value, and not their position. The error here happens when list() syntax is created with a mixed set of position and key assignations.
Example
<?php
$array = [];
list(
'' => $foo,
$bar
) = $array;
?>
Literal Examples
- Cannot mix keyed and unkeyed array entries in assignments
Alternatives
- Remove all the => operators in the list() call.
- Add all the => operators in the list() call.
- Make the assignations in a different way.
Cannot modify header information - headers already sent
Description
This error happens when PHP has already started sending the body of the response to the client. In HTTP protocol, the headers must comme first, and after, the body.
There are several reasons for PHP to start sending the body early. Among the most frequent, there might be a space, or the UTF-8 BOM at the beginning of an included file. They may also be at the end of the code, if there is a closing PHP tag.
There may also be some displays, with echo, or from errors.
Example
<?php
// There is a space before the opening tag
headers('my headers');
// There is a space after the closing tag, which impact including and autoloading files
?>
Alternatives
- Check the beginning of the script for invisible, or visible characters before the opening PHP tag.
- Check the beginning of the UTF-8 BOM before the opening PHP tag.
- Check the end of the script for invisible characters after the closing PHP tag, if any.
- Check any included files for the first three tips.
- Check for any call to a display functions, such as
echo,print,print_r,var_dump(),debug_print_backtrace(). - Check that
output_bufferingis active in the PHP configuration.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot modify readonly object of class %s
Description
It is possible to call the constructor on an existing object, after its creation. In the case of the Url objects, the underlying URL string is readonly, and the renewed call to the constructor is not possible.
Example
<?php
$uri = new Uri\WhatWg\Url('https://www.php.net/');
$uri->__construct('https://php.net/');
?>
Literal Examples
- Cannot modify readonly object of class Uri\WhatWg\Url
Alternatives
- Create a new Url object, instead of updating the existing one.
Related error messages
Cannot modify readonly property %s::$%s
Description
readonly properties can only be set once.
When such property is set in the constructor, there should not be another assignation of this property in another method: it would fail.
When the property is set in another method, then, such method shall only be called once.
They also should be set from their original class (or its children) and not from the public space.
Example
<?php
class X {
public readonly int $property;
public int $other;
}
$x = new X;
$x->other = 3;
$x->property = 5;
?>
Literal Examples
- Cannot modify readonly property x::$property
Alternatives
- Drop the readonly option.
- Create an accessor to set the property in the correct context.
Related error messages
Cannot override final %s::%s() with %s::%s()
Description
The final keyword prevents any child class to define the same constant or method. This impacts any class that tries to extends a final class.
Example
<?php
class X {
final function foo() {}
}
class Y extends X {
function foo() {}
}
?>
Literal Examples
- Cannot override final x::foo() with y::foo()
Alternatives
- Remove the final option in the parent class.
- Rename the non-final constant or method in the child class.
Related error messages
- %s::%s-cannot-override-final-constant-%s::%s
- cannot-override-final-%s::__construct()-with-%s::__construct()
Cannot override final %s::__construct() with %s::__construct()
Description
The final keyword prevents any child class from redeclaring the same method. Constructors are not exempt from this rule: if a parent class marks its __construct() method as final, no child class may declare its own constructor, even though constructors are otherwise treated differently from regular methods during inheritance checks (their signature is not required to be compatible with the parent’s).
Example
<?php
class X {
final function __construct() {}
}
class Y extends X {
function __construct() {}
}
?>
Literal Examples
- Cannot override final X::__construct() with Y::__construct()
Alternatives
- Remove the
finalkeyword from the parent constructor. - Do not declare a constructor in the child class; it will inherit the parent’s final constructor automatically.
- Add a differently named factory method in the child class instead of a constructor.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot override final property %s::$%s
Description
A property that is private for writing, is automatically considered final. That is, it cannot be redeclared in a child class, with a different visibility.
Example
<?php
class X {
public private(set) int $property;
}
class Y extends X {
public int $property;
}
new Y;
?>
Literal Examples
- Cannot override final property X::$property
Alternatives
- Remove the asymmetric visibility from the parent class.
- Remove the property declaration from the child class.
- Add the
finalkeyword to the property declaration in the parent (and adapt the children).
Related error messages
Cannot override final property hook %s::%s()
Description
Property hooks may be declared final, just like any other methods. In that case, it is not possible to override then with a new definition in a child class.
The property may be declared final as whole, in the property definition; otherwise, each individual hook may be declared final.
Example
<?php
class X {
public $property {
final get => 2;
set => $this->property = $value;
}
// No hook can be changed
public final $q {
get => 2;
}
}
class Y extends X {
public final $property {
get => 3; // This one cannot be overriden
set => $this->property = $value; // This one is OK
}
public final $q {
get => 2;
}
}
?>
Literal Examples
- Cannot override final property hook $p::get()
Alternatives
- Remove the final keyword on the parent hook.
- Remove the hook in the child class.
Related error messages
Cannot pass parameter %d by reference
Description
When a parameter is set to be passed by reference, there is a & character before its name. In that case, the argument must be a data container, such as a variable, a property, a static property, an array index, but it cannot be a literal value, a constant, or the result of an expression.
Example
<?php
function foo(&$a) {}
// invalid cases
foo(1);
foo(1 + 2);
const A = 1;
foo(A);
class X {
const B = 2;
}
foo(X::B);
?>
Literal Examples
- Cannot pass parameter 1 by reference
Alternatives
- Store the value in a variable and passe the variable.
- Remove the reference in the method signature.
Related error messages
- %s%s%s():-argument-#%d%s%s%s-must-be-passed-by-reference,-value-given
- parameter-%d-must-be-passed-by-reference
In more recent PHP versions, this error message is now :ref:%s():-argument-#%d%s%s%s-cannot-be-passed-by-reference.
Cannot perform bitwise not on %s
Description
Bitwise operations are only available on integers. Other types are forbidden. Among the operations ~ is a bitwise operation. For the other operators, a different error is emitted.
Example
<?php
$array = [1,2];
~$array;
?>
Literal Examples
- Cannot perform bitwise not on object
- Cannot perform bitwise not on boolean
- Cannot perform bitwise not on resource
- Cannot perform bitwise not on array
Alternatives
- Use another operator than the bitwise not, such as
!. - Cast the forbidden type to int before using the bitwise.
Related error messages
Cannot re-assign $this
Description
It is never possible to assign a new value to the pseudo-variable $this, inside a class or outside. In fact, it is also never allowed to unset it either. In short, it is possible to read $this, and nothing more.
Example
<?php
unset($this);
?>
Alternatives
- Remove this call to unset.
Related error messages
- cannot-unset-$this
- cannot-re-assign-auto-global-variable-%s
- cannot-use-auto-global-as-lexical-variable
- cannot-use-$this-as-global-variable
Cannot re-assign auto-global variable %s
Description
It is not possible to use one of the superglobal variable names as argument of a method: such code hides the assignation that happens at call time, which will interfere with the $_POST variable being a global. Hence, such syntax is forbidden.
The error is not emitted when the same superglobal variables are used as variables, as it may be legit code.
This applies to all PHP superglobal, such as $_ENV, $GLOBALS, or $_POST. See the full list in annex.
Example
<?php
function foo($_POST) {
}
?>
Literal Examples
- Cannot re-assign auto-global variable $_POST
Alternatives
- Use a parameter anme that is not a superglobal or a special PHP variable.
Related error messages
Cannot rebind scope of closure created from function, this will be an error in PHP 9
Description
A closure created from a plain, top-level function (Closure::fromCallable('foo') or foo(...)) has no class scope: it was never attached to an object or a class in the first place. Passing a scope argument to Closure::bind() or Closure::bindTo() on such a closure has nothing to rebind.
Since PHP 8.5, this operation already emitted an E_WARNING and the bind silently failed, returning null. It is now deprecated and will become a fatal error in PHP 9.0.
Example
<?php
class X {}
function foo() {
return __FUNCTION__;
}
$fn = Closure::fromCallable('foo');
$fn2 = Closure::bind($fn, new X, X::class);
var_dump($fn2);
?>
Literal Examples
- Cannot rebind scope of closure created from function, this will be an error in PHP 9
Alternatives
- Do not attempt to bind a scope to a closure created from a plain function; it has none.
- If scoped behaviour is required, define the closure inside the class (as a method or a property initializer) instead of wrapping a free function.
Related error messages
- cannot-rebind-scope-of-closure-created-from-method,-this-will-be-an-error-in-php-9
- cannot-rebind-scope-of-closure-created-from-method
- cannot-bind-an-instance-to-a-static-closure,-this-will-be-an-error-in-php-9
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See closure
Cannot rebind scope of closure created from method, this will be an error in PHP 9
Description
When a closure is created from an object method ($obj->method(...)), its scope and binding are tied to the originating object. Attempting to rebind that closure to a different scope or object using Closure::bind() or Closure::bindTo() is not allowed.
In PHP 7.0, this was silently accepted. Since PHP 8.0, it raises a warning. In PHP 9.0, it will be a fatal error.
The restriction exists because a method-bound closure captures the object’s internal context. Rebinding it would violate encapsulation by granting access to private and protected members of an unrelated class.
Example
<?php
class X {
public function method() {}
}
class Y {}
$x = new X;
$fn = $x->method(...);
$fn->bindTo($x, Y::class);
?>
Literal Examples
- Cannot rebind scope of closure created from method, this will be an error in PHP 9
Alternatives
- Create the closure from within the class itself using
[self, 'method']orClosure::fromCallable()to allow rebinding. - Avoid rebinding method-bound closures; use
call_user_func()or$closure(...)with the original binding. - If you need a rebound closure, create a standalone closure that wraps the method call.
Related error messages
- cannot-rebind-scope-of-closure-created-from-method
- cannot-bind-an-instance-to-a-static-closure
- cannot-bind-an-instance-to-a-static-closure,-this-will-be-an-error-in-php-9
- cannot-bind-method-%s::%s()-to-object-of-class-%s,-this-will-be-an-error-in-php-9
- cannot-rebind-scope-of-closure-created-from-function,-this-will-be-an-error-in-php-9
- cannot-unbind-$this-of-method,-this-will-be-an-error-in-php-9
Related error messages
In previous PHP versions, this error message used to be :ref:cannot-rebind-scope-of-closure-created-from-method.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot rebind scope of closure created from method
Description
When a closure is build from a method and an existing object, it is not possible to rebind it to another object.
Example
<?php
class X {
function method () {}
}
class Y {}
$x = new X;
$fn = $x->method(...);
$ret = $fn->bindTo($x, Y::class);
?>
Alternatives
- To be rebound, the closure must be build from within the class.
Related error messages
- cannot-rebind-scope-of-closure-created-from-method,-this-will-be-an-error-in-php-9
- cannot-rebind-scope-of-closure-created-from-function,-this-will-be-an-error-in-php-9
In more recent PHP versions, this error message is now :ref:cannot-rebind-scope-of-closure-created-from-method,-this-will-be-an-error-in-php-9.
Cannot redeclare %s%s::$%s as %s%s::$%s
Description
A non-private property redeclared in a child class must keep the same static/non-static nature as in the parent class. A static property belongs to the class itself, while a non-static property belongs to each instance; the two are fundamentally different storage locations, so a child class cannot silently turn one into the other while inheriting from the same family.
Here, X::$property is declared static, and Y redeclares it as an instance property, which is rejected.
This is a distinct check from the one that reports readonly conflicts between parent and child properties: that message uses the literal word “property” (as in Cannot redeclare readonly property X::$property as non-readonly Y::$property), while the static/non-static check never does.
Example
<?php
class X {
protected static $property;
}
class Y extends X {
protected $property;
}
?>
Literal Examples
- Cannot redeclare static X::$property as non static Y::$property
- Cannot redeclare non static X::$property as static Y::$property
Alternatives
- Make both declarations static.
- Make both declarations non-static.
- Remove the redeclaration in the child class, and inherit the parent property as-is.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot redeclare %s() (previously declared in %s:%d)
Description
Functions must have a unique name: there cannot be two functions with the same name.
Function names are case insensitive, so making changing the case doesn’t make the function name unique.
In fact, two functions in the same namespace cannot have the same name, so the complete constraint is namespace + function must be unique.
Example
<?php
function foo() {}
function FOO() {}
?>
Literal Examples
- Cannot redeclare foo() (previously declared in file:3)
Alternatives
- Change the name of the function.
- Make the function a closure.
- Move the function to another namespace.
Related error messages
In more recent PHP versions, this error message is now :ref:cannot-redeclare-function-%s()-(previously-declared-in-%s:%d).
Cannot redeclare %s %s (previously declared in %s:%d)
Description
A class, interface, trait or enum name can only be declared once per request, whether that happens directly in the same file or because two different, user-defined files both declare the same name. This is the general form of the redeclaration error: the first placeholder is the kind of symbol (class, interface, trait or enum), the second is its name, and the location points at the file and line of the earlier, conflicting declaration.
Unlike functions, none of these can be conditionally redeclared, even if the two declarations are byte-for-byte identical.
Example
<?php
interface Foo {
}
interface Foo {
}
?>
Literal Examples
- Cannot redeclare interface Foo (previously declared in /path/to/file.php:3)
- Cannot redeclare trait Foo (previously declared in /path/to/file.php:3)
- Cannot redeclare enum Foo (previously declared in /path/to/file.php:3)
Alternatives
- Use include_once or require_once instead of include or require to avoid loading the same file twice.
- Wrap the declaration in a class_exists()/interface_exists()/trait_exists()/enum_exists() check if it may legitimately be loaded more than once.
- Rename one of the two symbols, or move them into different namespaces.
Related error messages
- cannot-redeclare-class-%s
- cannot-redeclare-%s-%s
- cannot-redeclare-function-%s()-(previously-declared-in-%s:%d)
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot redeclare %s %s
Description
This is the general form of the class/interface/trait/enum redeclaration error, used specifically when the conflicting name is already taken by an internal symbol, one built into PHP itself or provided by a loaded extension, rather than by another user-defined file. Because internal classes and interfaces have no PHP source file or line number of their own, the message omits the (previously declared in ...) location that appears when the conflict is with another user-defined file.
The first placeholder is the kind of symbol (class, interface, trait or enum), the second is its name.
Example
<?php
interface Stringable {
}
?>
Literal Examples
- Cannot redeclare interface Stringable
- Cannot redeclare class stdClass
Alternatives
- Rename the declaration to avoid colliding with a built-in or extension-provided name.
- Wrap the declaration in a class_exists()/interface_exists()/trait_exists()/enum_exists() check, though this rarely helps for internal symbols since they are always present.
Related error messages
In more recent PHP versions, this error message is now :ref:cannot-redeclare-%s-%s-(previously-declared-in-%s:%d).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot redeclare %s property %s::$%s as %s %s::$%s
Description
A property must be always readonly or non-readonly, in every classes of the same family. It cannot alternate between the two options, with inheritance.
The same applies also to the static option of properties.
Example
<?php
class X {
private readonly $property;
}
class Y extends X {
private $property;
}
?>
Literal Examples
- Cannot redeclare readonly property X::$property as non-readonly Y::$property
- Cannot redeclare non-readonly property X::$property as readonly Y::$property
- Cannot redeclare static property X::$property as non-static Y::$property
- Cannot redeclare non-static property X::$property as static Y::$property
Alternatives
- Make all the property definitions
readonly. - Make all the property definitions non-
readonly. - Remove some the conflicting property definitions.
Related error messages
Cannot redeclare %s::$%s
Description
A property can only be declared once in a class. This error appears when the same property name is declared twice in the same class body, regardless of whether the visibility or default value differ between the two declarations.
The same restriction applies to promoted properties: a constructor parameter promoted to a property cannot share its name with a property already declared in the class body.
Example
<?php
class X {
public $a;
public $a;
}
?>
Literal Examples
- Cannot redeclare X::$a
Alternatives
- Remove one of the two duplicate property declarations.
- Rename one of the two properties.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot redeclare %s::%s()
Description
Each method in a class must have a distinct name. There can be not two methods with the same name.
The parent classes, or the traits, may have duplicate methods: these will be ignored.
One special case are the enumeration: the backed enumeration, with their type, import two methods to convert a value into one of the case: try and tryFrom. Then, these two methods are part of the definition of the enumeration, and it is not possible anymore to define them in the enumeration.
Example
<?php
class X {
function foo() {}
function foo() {}
}
enum E {
function try() {}
function tryFrom() {}
}
?>
Literal Examples
- Cannot redeclare X::foo()
- Cannot redeclare X::try()
- Cannot redeclare X::tryFrom()
Alternatives
- Remove one of the duplicate function.
- Rename one of the duplicate function.
Related error messages
Cannot redeclare class %s
Description
A class name can only be declared once per request. This error appears when the same class name is declared twice, either directly in the same file, or because a file defining the class was included more than once (for instance with include instead of include_once), or because two different files both declare a class with the same name.
Unlike functions, PHP does not allow a class to be conditionally redeclared, even if the two declarations are identical.
Example
<?php
class X
{
}
class X
{
}
?>
Literal Examples
- Cannot redeclare class X
Alternatives
- Use
include_onceorrequire_onceinstead ofincludeorrequireto avoid loading the same file twice. - Wrap the class declaration in a
class_exists()check if it may legitimately be loaded more than once. - Rename one of the two classes, or move them into different namespaces.
Related error messages
- cannot-redeclare-%s::%s()
- cannot-redeclare-function-%s()-(previously-declared-in-%s:%d)
- class-declarations-may-not-be-nested
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot redeclare constant ‘%s’
Description
A constant declared at the top level with the const keyword can only be declared once per namespace, per request. This is a compile-time error, unlike the runtime warning produced when calling define() twice with the same constant name.
This error also happens when a file declaring a top-level constant is included more than once without a guard.
Example
<?php
const FOO = 1;
const FOO = 2;
?>
Literal Examples
- Cannot redeclare constant ‘FOO’
Alternatives
- Remove the duplicate
constdeclaration. - Use
include_onceorrequire_oncefor files that declare top-level constants. - If the constant needs to be conditionally declared, use
define()together withdefined()instead ofconst.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot redeclare function %s() (previously declared as local import)
Description
A use function statement imports a function under a local name, in the current namespace. When a function is then declared, in the same namespace, under that same local name, and its declared name differs (case insensitively) from the fully qualified imported name, PHP cannot tell which of the import or the local declaration should be used.
This is detected at compile time, as soon as the local function declaration is compiled.
Example
<?php
namespace App;
use function Other\bar;
function bar() {}
?>
Literal Examples
- Cannot redeclare function bar() (previously declared as local import)
Alternatives
- Remove the
use functionimport, and call the function using its fully qualified name. - Alias the import with the
askeyword, so it no longer collides with the local function name. - Rename the local function.
Related error messages
- cannot-redeclare-function-%s()-(previously-declared-in-%s:%d)
- cannot-redeclare-%s()-(previously-declared-in-%s:%d)
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot redeclare function %s() (previously declared in %s:%d)
Description
Functions must have a unique name: there cannot be two functions with the same name.
Function names are case insensitive, so making changing the case doesn’t make the function name unique.
In fact, two functions in the same namespace cannot have the same name, so the complete constraint is namespace + function must be unique.
Example
<?php
function foo() {}
function FOO() {}
?>
Literal Examples
- Cannot redeclare foo() (previously declared in file:3)
Alternatives
- Change the name of the function.
- Make the function a closure.
- Move the function to another namespace.
Related error messages
In previous PHP versions, this error message used to be :ref:cannot-redeclare-%s()-(previously-declared-in-%s:%d).
Cannot redeclare function %s()
Description
This variant of the function redeclaration error is raised by OPcache, when it merges a script’s freshly compiled functions into its shared-memory function table and finds a name collision with a function that is already cached, but for which OPcache has no usable source location (for example, a function generated at runtime, or one whose original op_array metadata is otherwise unavailable). Because there is nothing meaningful to point at, the message omits the (previously declared in ...) part that the ordinary redeclaration error includes.
Functionally, this is the same constraint as the plain function redeclaration error: two functions cannot share the same name (case-insensitively) within the same namespace.
Example
<?php
// requires the Zend OPcache extension to be enabled
function foo() {}
?>
Literal Examples
- Cannot redeclare function foo()
Alternatives
- Change the name of one of the two functions.
- Guard the declaration with function_exists() if the file may legitimately be included more than once.
- Use include_once or require_once instead of include or require.
Related error messages
- cannot-redeclare-function-%s()-(previously-declared-in-%s:%d)
- cannot-redeclare-%s()-(previously-declared-in-%s:%d)
In previous PHP versions, this error message used to be :ref:cannot-redeclare-function-%s()-(previously-declared-in-%s:%d).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot redeclare property hook “%s
Description
Property hook may only have one definition. It is not possible to have duplicates.
Example
<?php
class Test {
public $prop {
GeT {}
get {}
}
}
?>
Literal Examples
- Cannot redeclare property hook “get”
Alternatives
- Remove all but one of the definition.
- Rename one of them with the other property hook name: may be
sethad a typo and was writtenget.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot redeclare property hook
Description
Property hooks must be all distinct, and there can only be two. In that case, it is get and set. Property hooks are case insensitive, so get and GET are the same.
They also differ one from the other by one letter, so review is important.
Example
<?php
class X
{
public string $property {
set => $this->property . _1;
SET {
$this->property = $value;
}
}
}
?>
Alternatives
- Make sure that both hooks are needed.
- Remove any third hook: there can only be two, at most.
- Check case of the hooks name.
Related error messages
Cannot redefine class constant %s::%s
Description
PHP does not allow the same constant twice in the same class. The constant may be declared several times in different classes, including extending or extended ones, or in trait, as each case has conflict resolution mechanisms.
Example
<?php
class C {
const FOO = hello;
const FOO = hello again;
}
?>
Literal Examples
- Cannot redefine class constant C::FOO
Alternatives
- Rename one of the conflicting constants.
- Remove one of the conflicting constants.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot redefine class constant
Description
It is only allowed to defined a constant once per class.
A constant with the same name may be defined in a parent or child class, or even in a trait: there are rules that allow PHP to select one of them, whenever there is a possible name conflict.
At the class, interface, trait level, the constants must all be distinct.
At the enumeration level, the naming conflict may arise between a case and a const: the error message is then the same.
This error applies to class constants, and there is a different error for global constants.
Example
<?php
class X {
const A = 1, A = 1;
}
enum E {
case B;
const B = 1;
}
?>
Alternatives
- Remove one of the constant.
- Rename one of the constant.
- Move one of the constant to a parent, trait or interface.
Related error messages
Cannot rewind a generator that was already run
Description
In this code, $g includes the generator, and it is run twice, from the first loop in $h, and then, in the second loop with $i.
Example
<?php
$g = function (): Generator {
yield from [1,2,3,4];
}; echo $i +;
$g = $g();
foreach($g as $h) {
print h:$h -;
foreach($g as $i) {
echo i:$i +;
break 1;
}
}
?>
Alternatives
- Do not reuse the generator in two loops, but rather call
$g()each time. It generates distinct and new data sources.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot set a userinfo without having a host
Description
Per RFC 3986, the userinfo component (user:pass@) only exists as part of an authority, and an authority always includes a host. There is no valid way to serialize a URI that carries userinfo but no host. Uri\Rfc3986\UriBuilder::build() (and the equivalent withUserInfo() call on an already-hostless URI) rejects that combination instead of producing a URI that would be ambiguous or unparsable when read back.
Example
<?php
$builder = new Uri\Rfc3986\UriBuilder();
$builder->setUserInfo('user:pass');
$uri = $builder->build();
?>
Alternatives
- Set a host on the builder (or the URI) before, or at the same time as, setting the userinfo.
- If the URI genuinely has no authority (e.g. a
mailto:URI), do not set userinfo on it.
Related error messages
In more recent PHP versions, this error message is now :ref:the-specified-userinfo-is-malformed.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot specify default value for virtual hooked property
Description
It is possible to create a virtual property, by defining one accessor that doesn’t refer to the defined property. In the illustration here, the get method is empty. In that case, the property’s value doesn’t have an impact on the operation, and the default value of that property shall not be defined.
Example
<?php
class X {
public int $property = 3 {
get {}
}
}
?>
Alternatives
- Remove the property hooks, to regain usage of the default value.
- Define a property hook that makes use of the property
$this->property.
Cannot take reference of a nullsafe chain
Description
The nullsafe operator ?-> short-circuits the whole access chain to null as soon as one segment is null: the rest of the chain is never evaluated. A reference, on the other hand, must point to a concrete storage location (a variable, array slot, or property); there is no such location to bind to when the chain may short-circuit to a plain null value instead.
This error is raised whenever ANY segment of a chain used in a by-reference context contains a nullsafe operator, whether the reference is taken with &, passed to a by-reference function or method parameter, or used in a by-reference foreach. It is a compile-time error, detected regardless of whether the chain would actually short-circuit at runtime.
Example
<?php
class Address {
public string $city = '';
}
class User {
public ?Address $address = null;
}
$user = new User();
$city = &$user?->address->city;
?>
Alternatives
- Use the regular
->operator instead of?->, after making sure the intermediate value cannot be null. - Split the expression: check for null first, then take the reference with
->.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot throw objects that do not implement Throwable
Description
All classes that are thrown must implement the interfave Throwable. It is possible to catch Throwable objects, but in fact, it is not possible to implement Throwable in a class: this is done by extending either Exception or Error, which, in turn, implements Throwable.
Example
<?php
class X {}
throw new X();
?>
Alternatives
- Make the class extends
\Exception. - Make the class extends
\Error. - Do not throw the class.
Cannot unbind $this of closure using $this, this will be an error in PHP 9
Description
A closure literal that references $this in its body captures the enclosing object when it is created. Rebinding it to null with bindTo() or Closure::bind() would leave the body referencing $this with nothing bound to it, so the operation is refused.
A closure that does not use $this in its body can still be unbound safely; the restriction only applies when $this is actually referenced.
Since PHP 8.5, this operation already emitted an E_WARNING and the bind silently failed, returning null. It is now deprecated and will become a fatal error in PHP 9.0.
Example
<?php
class X {
public $prop = 'hello';
public function getClosure() {
return function () {
return $this->prop;
};
}
}
$x = new X;
$fn = $x->getClosure();
$fn2 = $fn->bindTo(null);
var_dump($fn2);
?>
Literal Examples
- Cannot unbind $this of closure using $this, this will be an error in PHP 9
Alternatives
- If the closure needs to run without an object context, remove every use of
$thisfrom its body. - Keep the closure bound to the object and pass the values it needs as parameters instead of relying on unbinding.
Related error messages
- cannot-unbind-$this-of-method,-this-will-be-an-error-in-php-9
- cannot-bind-an-instance-to-a-static-closure,-this-will-be-an-error-in-php-9
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See closure
Cannot unbind $this of method, this will be an error in PHP 9
Description
A closure created directly from a non-static method ($obj->method(...) or ReflectionMethod::getClosure()) is a $this-call in disguise: the method body may use $this freely, whether or not it is written explicitly. Since PHP 8.0 removed static calls to non-static methods, $this is guaranteed to exist whenever such a method runs, so bindTo(null) can no longer strip it.
Since PHP 8.5, this operation already emitted an E_WARNING and the bind silently failed, returning null. It is now deprecated and will become a fatal error in PHP 9.0.
Example
<?php
class X {
public function method() {
return __METHOD__;
}
}
$x = new X;
$fn = $x->method(...);
$fn2 = $fn->bindTo(null);
var_dump($fn2);
?>
Literal Examples
- Cannot unbind $this of method, this will be an error in PHP 9
Alternatives
- Keep the closure bound to the object; call it with the original binding instead of unbinding
$this. - If a scope-free version of the logic is needed, extract it into a standalone function that does not rely on the method’s
$this.
Related error messages
- cannot-unbind-$this-of-closure-using-$this,-this-will-be-an-error-in-php-9
- cannot-rebind-scope-of-closure-created-from-method,-this-will-be-an-error-in-php-9
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See closure
Cannot unpack array with string keys
Description
Initialy, the ellipsis operator would only work with integer-indexed arrays, and not with string-indexed arrays. This feature was introduced in PHP 8.1, and the error message then disappeared.
Example
<?php
$array = ['a' => 1, 2];
$array2 = [...$array, 3];
?>
Alternatives
- Upgrade the code to PHP 8.1 or newer.
- Use array_keys() before using the ellipsis operator.
Cannot unset $this
Description
It is never possible to unset the pseudo-variable $this, inside a class or outside. Actually, it is also never allowed to write to it. In short, it is possible to read $this, and nothing more.
Example
<?php
unset($this);
?>
Alternatives
- Remove this call to unset.
Related error messages
Cannot unset hooked property %s::$%s
Description
It is not allowed to unset a hooked property, aka, a property with a get or set (or both) hook.
Example
<?php
class X {
public string $property {
get => $this->x;
}
}
$x = new X;
unset($x->x);
?>
Literal Examples
- Cannot unset hooked property x::$property
Alternatives
- Assign null, or a null value to this property.
- Reset the property to its default value.
Cannot unset offset in a non-array variable
Description
The array syntax $variable[index] is only available for arrays and strings. When used on other types, PHP emits a fatal error.
The boolean false and the null value still accept this behavior. The first is deprecated in PHP 8.1, and the second valid in PHP 8.3.
Example
<?php
$x = true;
$x[0] = 1;
?>
Alternatives
- Check for type before using the array syntax.
- Keep using consistent types with each variables.
- Set type with properties to ensure they are consistent.
- Cast the object to array before usage.
Related error messages
In previous PHP versions, this error message used to be :ref:cannot-use-object-of-type-stdclass-as-array.
Cannot unset readonly property %s::$%s
Description
Once a readonly property has been set, it cannot be unset. That would defeat the whoe purpose of readonly.
Example
<?php
class X {
public readonly $property;
function __construct($a) {
$this->property = $a;
unset($this->property);
}
}
?>
Literal Examples
- Cannot unset readonly property X::$property
Alternatives
- Use clone to create a new object, and have a chance to change that value.
- Remove the
unsetcall. - Remove the
readonlyproperty.
Cannot unset string offsets
Description
While strings and arrays share the same syntax with square brackets, to access individual elements, that syntax is not available with the unset() function. Strings do not behave like an array, so it is not possible to remove one char with unset.
Example
<?php
$a = 'abc';
unset($a);
?>
Alternatives
- Explode() the string into an array, use the unset() on the array, and then, implode() it back into a string.
- Use substr() twice, to cut out the unwanted character.
- Use preg_replace(), to replace the character with an empty string.
- Use strtr(), to replace the character with an empty string, if it is unique.
Cannot use%s %s as %s because the name is already in use
Description
This error appears when a name, for class, interface, trait or enumeration was already used by a use command. This is usually a problem within the block that has the use.
Example
<?php
use X as Y;
class Y {}
?>
Literal Examples
- Cannot use X as Y because the name is already in use
Alternatives
- Use another name for the alias.
- Use another name for the definition.
Related error messages
Cannot use(…) variables in constant expression
Description
It is possible to have closures in a constant, since PHP 8.5. Such closure must be static, so that it does not include the current object with $this. It also cannot use the use clause, as the definition of the closure is outside an execution context: there are no available variables to import in the closure.
Example
<?php
class X {
const MY = static function () use ($a) { return 1;};
}
?>
Alternatives
- Remove the
useclause of the closure. - Move the closure inside a method.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use “%s” as a type name as it is reserved
Description
array is a native PHP type, and it cannot be used with the leading \. This is also the case for the other native types, such as int or string, although they provide a different error message.
Example
<?php
function foo(\array $array) {}
?>
Literal Examples
- Cannot use “array” as a type name as it is reserved
Alternatives
- Remove the leading
\, before thearray. - Change the type from
arrayto an actual class.
Related error messages
Cannot use “%s” when no class scope is active
Description
self, static and parent refers to the classes, relative to the current one. As such, they can only be used inside a class or a trait.
Example
<?php
static::x;
?>
Literal Examples
- Cannot use “static::” when no class scope is active
- Cannot use “static” when no class scope is active
Alternatives
- Move the code inside a method, in a trait or a class.
- Use the full name of the class that should be used.
Cannot use “abstract” as method modifier in trait alias
Description
When resolving name conflicts during trait imports, it is not possible to use abstract with the as keyword. The situation is actually confusing: abstract may be the name of the alias, or it could also be understood as the modifier.
The same situation arise with abstract, final or readonly. On the other hand, it is valid to use the visibility modifier to actually change the visibility on the alias.
This message was completed with ‘in trait alias’, in PHP 8.2.
Example
<?php
trait T1 {
function foo() {}
}
class C1 {
use T1 {
T1::foo as abstract;
}
}
?>
Alternatives
- Use another name than
abstractfor the alias. - Use another name than
abstractfor the original method.
Related error messages
- cannot-use-‘final’-as-method-modifier
- cannot-use-‘static’-as-method-modifier
- cannot-use-‘readonly’-as-method-modifier
In previous PHP versions, this error message used to be :ref:cannot-use-'abstract'-as-method-modifier.
Cannot use “parent” when current class scope has no parent
Description
parent keyword represents the first available class in the current class hierarchy. A class has a parent class, when that class uses the extends keyword. When the current class has no such keyword, it has no parent and cannot use it.
This error applies to parent as a class descriptor or as a type.
Example
<?php
class X {
function foo(parent $y) {
parent::goo();
}
}
?>
Alternatives
- Add a parent to the current class.
- Use another class name, instead of
parent: for example, the actual name of the target class, rather than the relative one.
In previous PHP versions, this error message used to be :ref:parameter-uses-'parent'-as-type-hint-although-class-does-not-have-a-parent!.
Cannot use “parent” when no class scope is active
Description
parent is a keyword that represent the parent class of the current class. When the code is not located inside a class, it cannot have a parent, and so, is forbidden.
Example
<?php
function foo(parent $argument) { }
?>
Alternatives
- Convert the function into a method, in a class with a parent.
- Convert the function into a closure, and assign it a to an object of a class with a parent.
Cannot use “static” when no class scope is active
Description
static refers to the class that was called to access the class elements (constants, method, properties..). As such, static can only be used inside a class or a trait.
Example
<?php
static::x;
?>
Alternatives
- Move the code inside a method, in a trait or a class.
- Use the full name of the class that should be used.
In previous PHP versions, this error message used to be :ref:cannot-access-static::-when-no-class-scope-is-active.
Cannot use $this as global variable
Description
The pseudo-variable $this is automatically available inside every method of a class, and refers to the current object. It is not possible to import $this into the global symbol table using the global keyword. $this is special and not a regular variable that may be made global.
Example
<?php
class X {
function foo() {
global $this;
}
}
(new X)->foo();
?>
Alternatives
- Use
$thisdirectly inside the method, without importing it as global. - Pass the object as a parameter to the function that needs it.
Related error messages
- cannot-re-assign-$this
- using-$this-when-not-in-object-context
- cannot-use-auto-global-as-lexical-variable
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use $this as lexical variable
Description
A lexical variable is a variable imported into a closure via the use clause. Since PHP 8.1, $this is automatically available inside all closures defined in an object context, so it is no longer allowed to explicitly import it as a lexical variable. This is also true for arrow functions, which implicitly capture $this when defined inside a method.
Example
<?php
class X {
function foo() {
$fn = function () use ($this) {
return $this;
};
}
}
(new X)->foo();
?>
Alternatives
- Remove
$thisfrom theuseclause, since it is automatically available in the closure. - Use a
staticclosure if$thisis not needed.
Related error messages
- closures-in-constant-expressions-must-be-static
- using-$this-when-not-in-object-context
- cannot-use-auto-global-as-lexical-variable
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use $this as parameter
Description
Cannot use $this as parameter. Using $this as a method parameter is not allowed in PHP.
Example
<?php
function foo($this) { }
?>
Alternatives
- Pass the object as a parameter by creating a method that accepts an object parameter instead.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use $this as static variable
Description
$this is a special variable, automatically bound to the current object inside a method. It cannot be redefined, in particular by making it a static variable, which would give it a persistent value between calls and remove its automatic binding to the object.
This is checked at compile time, whether the method is ever called or not.
Example
<?php
class X {
public function foo() {
static $this;
}
}
?>
Alternatives
- Use another variable name for the static variable.
- Store the required data in a property of the object instead.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use %s() on dynamic property %pS::$%pS
Description
ReflectionProperty::setRawValueWithoutLazyInitialization() and ::skipLazyInitialization() are part of the lazy objects API (PHP 8.4): they work by reaching directly into the storage slot reserved for a declared property, bypassing the object’s lazy initializer. A dynamic property (one added to a specific object at runtime rather than declared in its class) has no such reserved slot, so these methods have nothing to operate on and throw instead.
Since ReflectionProperty is constructed from a property name that may or may not correspond to an actual declared property on the given object, this can only be detected at call time, once the object is known.
Example
<?php
class Foo {}
$obj = new Foo();
$obj->bar = 1;
$prop = new ReflectionProperty($obj, 'bar');
$prop->setRawValueWithoutLazyInitialization($obj, 2);
?>
Literal Examples
- Cannot use setRawValueWithoutLazyInitialization() on dynamic property Foo::$bar
- Cannot use skipLazyInitialization() on dynamic property Foo::$bar
Alternatives
- Only call setRawValueWithoutLazyInitialization()/skipLazyInitialization() for properties that are actually declared on the object’s class, e.g. after checking ReflectionProperty::isDynamic() (or checking the object with property_exists() against the class declaration).
Related error messages
- cannot-use-%s()-on-static-property-%ps::$%ps
- cannot-use-%s()-on-virtual-property-%ps::$%ps
- cannot-use-%s()-on-internal-class-%ps
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.6, the same ReflectionException was thrown, but worded “Can not use %s on dynamic property %s::$%s” (no parentheses after the method name, and “Can not” as two words).](Prior to PHP 8.6, the same ReflectionException was thrown, but worded “Can not use %s on dynamic property %s::$%s” (no parentheses after the method name, and “Can not” as two words).)
Cannot use %s() on internal class %pS
Description
ReflectionProperty::setRawValueWithoutLazyInitialization() and ::skipLazyInitialization() are part of the lazy objects API (PHP 8.4). Making an object lazy relies on the engine’s default property read/write handlers, so it can intercept property access to trigger initialization. Some internal (C-implemented) classes, such as ZipArchive, install their own custom property handlers instead and cannot be made lazy, so a declared property found on such a class still cannot be manipulated through these low-level, lazy-initialization-only APIs, and PHP throws instead of writing to a slot that the object’s own handlers do not expect to be touched directly.
Example
<?php
$zip = new ZipArchive();
$prop = new ReflectionProperty($zip, 'status');
$prop->setRawValueWithoutLazyInitialization($zip, 0);
?>
Literal Examples
- Cannot use setRawValueWithoutLazyInitialization() on internal class ZipArchive
- Cannot use skipLazyInitialization() on internal class ZipArchive
Alternatives
- Use ReflectionProperty::setValue() to set a property on an internal class instance, since setRawValueWithoutLazyInitialization()/skipLazyInitialization() only work with classes that support the engine’s default property handlers and can be made lazy.
Related error messages
- cannot-use-%s()-on-dynamic-property-%ps::$%ps
- cannot-use-%s()-on-static-property-%ps::$%ps
- cannot-use-%s()-on-virtual-property-%ps::$%ps
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.6, the same ReflectionException was thrown, but worded “Can not use %s on internal class %s” (no parentheses after the method name, and “Can not” as two words).](Prior to PHP 8.6, the same ReflectionException was thrown, but worded “Can not use %s on internal class %s” (no parentheses after the method name, and “Can not” as two words).)
Cannot use %s() on static property %pS::$%pS
Description
ReflectionProperty::setRawValueWithoutLazyInitialization() and ::skipLazyInitialization() are part of the lazy objects API (PHP 8.4): they exist to manipulate the storage slot of a lazily-initialized instance property without triggering (or interfering with) the object’s lazy initializer. A static property belongs to the class, not to any particular instance, and is never subject to per-object lazy initialization, so these methods refuse to act on it.
Example
<?php
class Foo {
public static int $counter = 0;
}
$obj = new Foo();
$prop = new ReflectionProperty(Foo::class, 'counter');
$prop->setRawValueWithoutLazyInitialization($obj, 5);
?>
Literal Examples
- Cannot use setRawValueWithoutLazyInitialization() on static property Foo::$counter
- Cannot use skipLazyInitialization() on static property Foo::$counter
Alternatives
- Use ReflectionProperty::setValue() for static properties instead of setRawValueWithoutLazyInitialization()/skipLazyInitialization(), which only make sense for lazily-initialized instance properties.
Related error messages
- cannot-use-%s()-on-dynamic-property-%ps::$%ps
- cannot-use-%s()-on-virtual-property-%ps::$%ps
- cannot-use-%s()-on-internal-class-%ps
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.6, the same ReflectionException was thrown, but worded “Can not use %s on static property %s::$%s” (no parentheses after the method name, and “Can not” as two words).](Prior to PHP 8.6, the same ReflectionException was thrown, but worded “Can not use %s on static property %s::$%s” (no parentheses after the method name, and “Can not” as two words).)
Cannot use %s() on virtual property %pS::$%pS
Description
ReflectionProperty::setRawValueWithoutLazyInitialization() and ::skipLazyInitialization() are part of the lazy objects API (PHP 8.4): they reach directly into the memory slot backing an ordinary, storage-based property, bypassing the object’s lazy initializer. A virtual property (a property hook declared with only get/set and no backing $this->propName storage, from PHP 8.4’s property hooks feature) has no such slot at all, so these methods have nothing to write to and throw instead.
Example
<?php
class Foo {
public int $bar {
get => 5;
}
}
$obj = new Foo();
$prop = new ReflectionProperty($obj, 'bar');
$prop->setRawValueWithoutLazyInitialization($obj, 2);
?>
Literal Examples
- Cannot use setRawValueWithoutLazyInitialization() on virtual property Foo::$bar
- Cannot use skipLazyInitialization() on virtual property Foo::$bar
Alternatives
- Only call setRawValueWithoutLazyInitialization()/skipLazyInitialization() on properties that actually have backing storage, i.e. hooked properties that reference $this->propName in their get/set hooks, not purely virtual ones.
Related error messages
- cannot-use-%s()-on-dynamic-property-%ps::$%ps
- cannot-use-%s()-on-static-property-%ps::$%ps
- cannot-use-%s()-on-internal-class-%ps
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.6, the same ReflectionException was thrown, but worded “Can not use %s on virtual property %s::$%s” (no parentheses after the method name, and “Can not” as two words).](Prior to PHP 8.6, the same ReflectionException was thrown, but worded “Can not use %s on virtual property %s::$%s” (no parentheses after the method name, and “Can not” as two words).)
Cannot use %s as %s because %s is a special class name
Description
Some words, such as float, never, _, … are reserved by PHP and cannot be used as an alias name, just like they are not allowed with class names.
Example
<?php
use X as string;
?>
Literal Examples
- Cannot use X as string because string is a special class name
Alternatives
- Use another name.
Cannot use %s as array
Description
This error is emitted when the right operand of a list operation is not an array, but a scalar, with the exception of null.
Example
<?php
list($a, $b) = 'abc';
?>
Literal Examples
- Cannot use string as array
- Cannot use boolean as array
- Cannot use integer as array
- Cannot use float as array
- Cannot use object as array
Alternatives
- Convert the right operand to an array first.
- Use a simple assignation, rather than
list.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See destructuringNonArray
Cannot use %s as default value for parameter $%s of type %s
Description
The default value of the parameter is not compatible with the type of the parameter. In the example here, the parameter $s is an integer, but has a string as default value.
This error also applies to numeric strings: the default value must be of the same type, without any silent type juggling.
It used to be recommended to make the default value NULL as it would be implicitely accepted by the type. Yet, in PHP 8.4, this is now a deprecated behavior, and it is not recommended anymore.
Example
<?php
function foo(int $s = 's') { }
function bar(int $s = '1') { }
?>
Literal Examples
- Cannot use 3 as default value for parameter $a of type array
Alternatives
- Change the type of the parameter.
- Change the default value.
- Remove the default value.
- Remove the type value.
- Add a second union type to the parameter.
Related error messages
- default-value-for-parameters-with-a-%s-type-can-only-be-%s-or-null
- cannot-use-%s-as-default-value-for-property-%s::$%s-of-type-%s
In previous PHP versions, this error message used to be :ref:default-value-for-parameters-with-a-%s-type-can-only-be-%s-or-null.
Cannot use %s as default value for property %s::$%s of type %s
Description
The default value of the property is not compatible with the type of the same property. In the example here, the property $s is an integer, but has a string as default value.
This error also applies to numeric strings: the default value must be of the same type, without any silent type juggling.
It used to be recommended to make the default value NULL as it would be implicitely accepted by the type. Yet, in PHP 8.4, this is now a deprecated behavior, and it is not recommended anymore.
Example
<?php
class X {
public string $property = 3;
}
?>
Literal Examples
- Cannot use 3 as default value for property X::$property of type string
Alternatives
- Change the type of the parameter.
- Change the default value.
- Remove the default value.
- Remove the type value.
- Add a second union type to the parameter.
Related error messages
- default-value-for-parameters-with-a-%s-type-can-only-be-%s-or-null
- cannot-use-%s-as-default-value-for-parameter-$%s-of-type-%s
Cannot use %s as value for class constant %s::%s of type %s
Description
This error appears when there is a mismatch between the value of a constant, and its declared type.
Note that there is not type juggling, so the value of the constant must match the type exactly. Consider that strict_types always applies in this case.
Example
<?php
class X {
const int A = 'abc';
const int B = '123';
const int C = 3, D = 'abc';
}
?>
Alternatives
- Remove the constant type.
- Replace the constant type.
- Replace the constant value.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use '%s' as namespace name
Description
The namespace keyword is used to declare a namespace, and also to reference the current namespace, when building a name, for a function, a class, etc. As such, it is not possible to use namespace as a prefix of the name of a namespace (sic), as it may be confused later with the current namespace. Also, namespaces are case insensitive.
Example
<?php
namespace Namespace\xyz {}
namespace NAMEspace\xyz {}
// This is OK, as ``namespace`` is not first in the name
namespace Abc\Namespace\Xyz {}
?>
Literal Examples
- Cannot use “namespace\xyz” as namespace name, due to conflict with ns-relative names
Alternatives
- Remove the word namespace in the name of the namespace.
- Add another prefix before the word namespace in the name of the namespace.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use ‘abstract’ as constant modifier
Description
abstract is an option for methods, and it is not available for class constants, properties or enumeration cases.
Example
<?php
class X {
private static const A = 1;
}
?>
Alternatives
- Remove the option from the constant signature.
In more recent PHP versions, this error message is now :ref:cannot-use-the-%s-modifier-on-a-%s.
Cannot use ‘abstract’ as method modifier
Description
When resolving name conflicts during trait imports, it is not possible to use abstract with the as keyword. The situation is actually confusing: abstract may be the name of the alias, or it could also be understood as the modifier.
The same situation arise with abstract, final or readonly. On the other hand, it is valid to use the visibility modifier to actually change the visibility on the alias.
Example
<?php
trait T1 {
function foo() {}
}
class C1 {
use T1 {
T1::foo as abstract;
}
}
?>
Alternatives
- Use another name than
abstractfor the alias. - Use another name than
abstractfor the original method.
Related error messages
- cannot-use-‘final’-as-method-modifier
- cannot-use-‘static’-as-method-modifier
- cannot-use-‘readonly’-as-method-modifier
In more recent PHP versions, this error message is now :ref:cannot-use-"abstract"-as-method-modifier-in-trait-alias.
Cannot use ‘final’ as constant modifier
Description
final is an option for methods, and it is not available for class constants and properties. It becomes a feature with class constants in PHP 8.0.
Example
<?php
class X {
private static const A = 1;
}
?>
Alternatives
- Remove the option from the constant signature.
In more recent PHP versions, this error message is now :ref:cannot-use-the-%s-modifier-on-a-%s.
Cannot use ‘final’ as method modifier
Description
When resolving name conflicts during trait imports, it is not possible to use final with the as keyword. The situation is actually confusing: final may be the name of the alias, or it could also be understood as the modifier.
The same situation arise with abstract, static or readonly. On the other hand, it is valid to use the visibility modifier to actually change the visibility on the alias.
Example
<?php
trait T1 {
function foo() {}
}
class C1 {
use T1 {
T1::foo as final;
}
}
?>
Alternatives
- Use another name than
finalfor the alias. - Use another name than
finalfor the original method.
Related error messages
- cannot-use-‘abstract’-as-method-modifier
- cannot-use-‘static’-as-method-modifier
- cannot-use-‘readonly’-as-method-modifier
- cannot-use-“abstract”-as-method-modifier-in-trait-alias
Cannot use ‘mixed’ as class name as it is reserved
Description
mixed is a PHP reserved keyword, since PHP 8.0. Until then, it was possible to use it anywhere as names, but since PHP 8.0, it is forbidden with class names, interfaces, enumerations and traits.
The same error is used for all CITE structures : class, interfaces, traits and enumerations.
Namespaces do not solve this issue.
mixed as a function, method, property, global or class constants is legit.
Example
<?php
class Mixed {}
interface Mixed {}
trait Mixed {}
enum Mixed {}
?>
Alternatives
- Use another name for that class.
Related error messages
Cannot use ‘namespace’ as namespace name
Description
The namespace namespace keyword introduces a namespace. The namespace may have no name, or a name. The only forbidden name is namespace, as it is used later to identify the current namespace, when used as the first entry in a fully qualified namespace.
Example
<?php
namespace Namespace {}
?>
Alternatives
- Use another name than
namespace.
Cannot use ‘never’ as class name as it is reserved
Description
never is a PHP reserved keyword, since PHP 8.1. Until then, it was possible to use it anywhere as names, but since PHP 8.1, it is forbidden with class names, interfaces, enumerations and traits.
The same error is used for all CITE structures : class, interfaces, traits and enumerations.
Namespaces do not solve this issue.
never as a function, method, property, global or class constants is legit.
Example
<?php
class Never {}
interface Never {}
trait Never {}
enum Never {}
?>
Alternatives
- Use another name for that class.
Related error messages
Cannot use ‘readonly’ as %s modifier
Description
readonly is reserved for properties, and cannot be used with methods, constants, enumeration cases or static properties.
Example
<?php
class X {
readonly function foo() {}
}
?>
Literal Examples
- Cannot use 'readonly' as method modifier
- Cannot use 'readonly' as constant modifier
- Cannot use 'readonly' as constant modifier
Alternatives
- Remove the
readonlyoption from the method signature.
Cannot use ‘readonly’ as method modifier
Description
readonly is reserved for properties, and cannot be used with methods, constants, enumeration cases or static properties.
Example
<?php
class X {
private readonly function foo() {}
}
?>
Alternatives
- Remove the option from the method signature.
Related error messages
- cannot-use-‘abstract’-as-method-modifier
- cannot-use-‘final’-as-method-modifier
- cannot-use-‘static’-as-method-modifier
- cannot-use-“abstract”-as-method-modifier-in-trait-alias
Cannot use ‘static’ as constant modifier
Description
static is an option for properties and methods, and it is not available for class constants. A class constant is reachable with the name of the class: as such, it behaves like a static class constant by definition: there are not object’s constants.
Example
<?php
class X {
private static const A = 1;
}
?>
Alternatives
- Remove the option from the constant signature.
In more recent PHP versions, this error message is now :ref:cannot-use-the-%s-modifier-on-a-%s.
Cannot use ‘static’ as method modifier
Description
When resolving name conflicts during trait imports, it is not possible to use static with the as keyword. The situation is actually confusing: static may be the name of the alias, or it could also be understood as the modifier.
The same situation arise with abstract, final or readonly. On the other hand, it is valid to use the visibility modifier to actually change the visibility on the alias.
Example
<?php
trait T1 {
function foo() {}
}
class C1 {
use T1 {
T1::foo as static;
}
}
?>
Alternatives
- Use another name than
staticfor the alias. - Use another name than
staticfor the original method.
Related error messages
- cannot-use-‘final’-as-method-modifier
- cannot-use-‘abstract’-as-method-modifier
- cannot-use-‘readonly’-as-method-modifier
- cannot-use-“abstract”-as-method-modifier-in-trait-alias
Cannot use "%s" as %s as it is reserved
Description
array and callable cannot be used with the leading backslash. This bug was fixed in PHP 8.5.
Example
<?php
// Since PHP 8.5
function foo() : \array {}
?>
Alternatives
- Use the type without the leading
\. - Upgrade to PHP 8.5 (when available).
Related error messages
Cannot use "%s" as %s
Description
This is the generic, truncated form of a family of errors PHP raises when a reserved word is used where an identifier for a class, interface, trait, enum, or type is expected. The first %s is the reserved word as written by the user, the second %s describes the context (class name, interface name, trait name, enum name, a type name, etc.). The full runtime message continues with as it is reserved.
The list of reserved words has grown over time: bool, int, float, string, true, false, null, self, parent and static since PHP 7.0; void and iterable since PHP 7.1; object since PHP 7.2; mixed since PHP 8.0; never since PHP 8.1. array and callable are also reserved for this purpose, although they cannot even reach the parser as identifiers, since they are proper tokens.
The same underlying check is also used, with a different second argument, when a reserved word is written with a leading backslash in a type declaration, such as \array.
Example
<?php
class Int {}
interface Void {}
trait Object {}
enum Iterable {}
?>
Alternatives
- Use another name; reserved words cannot be used as class, interface, trait, or enum names.
- Check the exact list of reserved words for the PHP version being targeted.
Related error messages
- cannot-use–“%s-”-as-%s-as-it-is-reserved
- cannot-use-“%s”-as-a-type-name-as-it-is-reserved
- cannot-use-‘mixed’-as-class-name-as-it-is-reserved
- cannot-use-‘never’-as-class-name-as-it-is-reserved
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use "%s" when no class scope is active
Description
self and static refer to the class in which the code is written, respectively as a fixed reference and one resolved at call time (late static binding). Both require an active class scope: they can only be used inside a class, trait, or enum, not in a plain function nor at the top level of a script.
This error appears when self or static is used as a class reference, for instance to instantiate an object, call a static method, or fetch a class constant, outside of any class definition.
Example
<?php
function foo() {
return new self();
}
?>
Literal Examples
- Cannot use “self” when no class scope is active
- Cannot use “static” when no class scope is active
Alternatives
- Use the actual class name instead of
selforstatic. - Move the code inside a class, trait, or enum.
Related error messages
- cannot-use–“parent-”-when-no-class-scope-is-active
- cannot-use–“parent-”-when-current-class-scope-has-no-parent
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use "::class" on %s
Description
Since PHP 8.0, expr::class can be used on any object expression to retrieve its class name, not only on class names, self, static or parent. When the expression is a scalar literal, such as an integer, float, string or boolean, PHP can already tell at compile time that it will never hold an object, and rejects the construct right away instead of waiting for a runtime error. %s is replaced with a description of the offending value.
Example
<?php
echo 10::class;
?>
Alternatives
- Only use ::class on a class name, or on an expression that can hold an object.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use "abstract" as method modifier in trait alias
Description
The as clause of a trait use statement can rename a method, and change its visibility (public, protected, private), and, since PHP 8.3, mark it final. It cannot mark the alias abstract, nor static: an alias only renames an existing, concrete method brought in by the trait, it does not declare a new one, so these modifiers make no sense in this context.
This is a compile time check, independent of the class that uses the trait.
Example
<?php
trait T {
public function foo() {}
}
class X {
use T {
foo as abstract bar;
}
}
?>
Alternatives
- Remove the
abstractmodifier from the trait alias. - Declare an actual abstract method, in the class or in an interface, instead of trying to alias the trait method as abstract.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use "parent" when current class scope has no parent
Description
parent:: refers to the parent of the class currently being defined. It can only be used inside a class that actually extends another class.
Using parent:: in a class that has no parent (no extends clause) used to only trigger a deprecation notice, in PHP 7.4. Since PHP 8.0, it is a compile time fatal error.
This differs from using parent:: completely outside of any class scope, which is a separate error.
Example
<?php
class Foo {
public function bar() {
parent::bar();
}
}
?>
Alternatives
- Make the class extend a parent class.
- Remove the
parent::call, and implement the logic directly in the method.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See orphanedParent
Cannot use "parent" when no class scope is active
Description
parent:: can only be used inside a class, trait, or enum, referring to the parent of the class in scope. It cannot be used in a plain function, nor at the top level of a script, where there is no class scope at all.
This differs from using parent:: inside a class that has no parent: that case is a distinct, related error.
Example
<?php
function foo() {
parent::bar();
}
?>
Alternatives
- Move the code inside a class that extends another class.
- Call the target method directly, on an instance or via its class name.
Related error messages
- cannot-use–“parent-”-when-current-class-scope-has-no-parent
- cannot-use–“%s-”-when-no-class-scope-is-active
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use "static" as method modifier in trait alias
Description
The as adaptation syntax used with use (traits) can only change the visibility of an imported method, or give it a new alias. It cannot be used to add the static modifier to a method: a trait method’s static-ness is fixed by how it is declared in the trait itself, and cannot be altered by the class that imports it.
Example
<?php
trait Greet
{
public function hello()
{
echo 'hi';
}
}
class X
{
use Greet {
hello as static greetStatically;
}
}
?>
Literal Examples
- Cannot use “static” as method modifier in trait alias
Alternatives
- Remove the
staticmodifier from theasadaptation, and only change the visibility or the alias name. - Declare the method as
staticdirectly in the trait, if that is the intended behavior.
Related error messages
- a-precedence-rule-was-defined-for-%s::%s-but-this-method-does-not-exist
- an-alias-was-defined-for-%s::%s-but-this-method-does-not-exist
- trait-method-%s::%s-has-not-been-applied-as-%s::%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use "yield from" inside a by-reference generator
Description
yield from only emit data by value, not by reference.
Example
<?php
function &foo() {
yield from [1,2,3];
}
?>
Alternatives
- Remove the reference sign from the function signature.
- Refactor the code to use
yieldinstead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use ::class with dynamic class name
Description
Until PHP 8.0, it was not possible to use a variable (or any data container) with the ::class operator to get its name. Basically, the name of the class had to be hardcoded.
Example
<?php
$a::class;
?>
Alternatives
- Use get_class().
- Use instanceof.
Cannot use [] for reading
Description
The append operator [] is a write operator: it alters the underlying variable. It cannot be used for reading, as it doesn’t produce a value. Hence, it is not possible to use the append operator as an argument, or with a short assignment operator.
Example
<?php
// += needs a value to increment, which [] cannot provide
$a[] += 2;
// When foo() is called, the value of the arguments is transmitted to the function.
// Here, $a[] has no value.
foo($a[]);
?>
Alternatives
- Only use [] in writing context.
Cannot use [] for unsetting
Description
unset() removes a specific, existing element identified by an explicit key. The empty-bracket append syntax ($array[]) only has meaning in a write context, where it picks the next available integer key to create a new element; there is no such “next element” to remove, so combining the two is rejected at compile time.
Example
<?php
$array = [1, 2, 3];
unset($array[]);
?>
Alternatives
- Pass an explicit key to unset(), e.g. unset($array[2]);.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use a scalar value as an array
Description
Scalar values cannot be modified with the array syntax: for example, it makes no sense to modify the third indexed element on an integer.
The error message is a bit misleading, as strings are allowed to be manipulated that way: some scalar values are allowed. Arrays are, of course, allowed, and for objects, it depends if the class implements ArrayAccess or not.
This error message is used with write context. There is an equivalent error message for reading.
Example
<?php
$a = 123;
$a[3] = 2;
$b = true;
$a[3] = 4;
?>
Alternatives
- Cast the value to a string.
- Cast the value to an array.
- Use a better suited operator than this one.
- Test the type before using the array syntax on the value.
Cannot use anonymous class in constant expression
Description
PHP 8.1’s “new in initializers” allows object-creation expressions to appear in constant-expression contexts, such as default parameter values, property defaults, static variables, class constants and attribute arguments, as long as the class being instantiated is fixed and unambiguous. An anonymous class is declared and compiled at the exact spot it is written; allowing one inside a shared, deferred context like a property default would raise questions about when and how often it actually gets declared, so it remains disallowed there.
Example
<?php
class Foo {
public $bar = new class {};
}
?>
Alternatives
- Give the class a name, declare it separately, and use new Name(…) in the constant expression instead.
Related error messages
- cannot-use-dynamic-class-name-in-constant-expression
- static-“-is-not-allowed-in-compile-time-constants
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use argument unpacking after named arguments
Description
PHP 8.1 allows named arguments and argument unpacking (…$array) to be combined in the same call, but the unpacked array must come before any named arguments. Argument unpacking supplies its own set of positions/keys, and allowing it to appear after arguments already identified by name would make the resulting parameter order ambiguous, so it is rejected at compile time based on the call’s syntax alone.
Example
<?php
function foo($a, $b, $c) {}
$rest = ['c' => 3];
foo(a: 1, b: 2, ...$rest);
?>
Alternatives
- Move the unpacked array before the named arguments, adjusting keys as needed: foo(…$rest, a: 1, b: 2);
- Turn the unpacked array’s values into individual named arguments.
Related error messages
- cannot-combine-named-arguments-and-argument-unpacking
- cannot-use-positional-argument-after-named-argument-during-unpacking
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use auto-global as lexical variable
Description
A lexical variable is the variables used in the use part of a closure definition. These variable will be imported in the closure. In this case, the variable is an auto-global variable, which is included in every context, so this is useless.
Example
<?php
function () use ($_POST) { };
?>
Alternatives
- Remove the auto-global from the list of imported variable (in the use clause).
- Remove the use clause, if that variable is there alone.
Related error messages
- cannot-re-assign-$this
- cannot-re-assign-auto-global-variable-%s
- cannot-use-$this-as-global-variable
- cannot-use-$this-as-lexical-variable
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE
Description
There are two options for the filter extension to handle errors: either return null, or throw an exception. They are mutually exclusive, and can’t be used at the same time.
Example
<?php
// combining constants with |
filter_var( value: 'bob@example.com',
filter: FILTER_VALIDATE_EMAIL,
options: FILTER_NULL_ON_FAILURE | FILTER_THROW_ON_FAILURE,
);
// combining constants with +
filter_var( value: 'bob@example.com',
filter: FILTER_VALIDATE_EMAIL,
options: FILTER_NULL_ON_FAILURE + FILTER_THROW_ON_FAILURE,
);
// FILTER_NULL_ON_FAILURE + FILTER_THROW_ON_FAILURE = 402653184
filter_var( value: 'bob@example.com',
filter: FILTER_VALIDATE_EMAIL,
options: 402653184,
);
?>
Alternatives
- Use only one of the two constants.
- When providing the options as an integer, make sure the bytes 27 and 28 are not set at the same time.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use dynamic class name in constant expression
Description
“New in initializers” (PHP 8.1) lets new SomeClass(…) appear in constant-expression contexts, such as default parameter values, but only when the class name is written literally, or via self/parent, something resolvable without evaluating an arbitrary expression. A dynamic class name taken from a variable or another expression cannot be resolved once and for all in that fixed, deferred context, so it is rejected at compile time.
Example
<?php
$className = 'DateTime';
class Bar {
public function baz($obj = new $className()) {}
}
?>
Alternatives
- Use a literal class name instead of a variable.
- Move the object creation into the function body instead of the parameter default.
Related error messages
- cannot-use-anonymous-class-in-constant-expression
- static::-“-is-not-allowed-in-compile-time-constants
- cannot-use–“::class-”-on-%s
- static-“-is-not-allowed-in-compile-time-constants
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use dynamic function name in constant expression
Description
This error appears when the name of the function cannot be entirely resolved at compile time. Here, the array cannot be turned into a function or static method name. This also happens for variations on the name, such as using a boolean, an array, or any expression that cannot be resolved at compilation time.
Example
<?php
const Closure1 = ([])(...);
const Closure2 = (-1)(...);
const Closure3 = (true)(...);
var_dump(Closure);
?>
Alternatives
- Use a string for the name of the function or static method.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use dynamic method name in constant expression
Description
PHP 8.5 allows first-class callable syntax ((...)) to be used inside a constant expression – a global constant, a class constant, a static property default, a parameter default value, and so on – so that a static method can be turned into a Closure at compile time.
To build that closure, the method name must be resolvable at compile time. Here, the braced expression {[1, 2]} is not a simple, literal method name: it is an array, which cannot represent a method name at all. Since the compiler cannot fold it down to a plain string, it reports that a dynamic name was used.
This check only applies to static method calls (X::method(...)); the equivalent restriction for a plain function name is reported as ‘Cannot use dynamic function name in constant expression’. When the braced expression does resolve to a scalar value that simply is not a legal method name (such as an integer), PHP reports ‘Illegal method name’ instead.
Example
<?php
class X {
public static function foo() { return 1; }
}
const C = X::{[1, 2]}(...);
var_dump(C);
?>
Alternatives
- Use a literal string for the method name.
- Move the closure creation out of the constant expression, into ordinary code, where dynamic method names are allowed.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See constantExpressionMethodNameResolution85
Cannot use empty array elements in arrays
Description
Arrays can only hold values. There is not meaning in an empty slots in an array.
This problem happens at writing time, and cannot happen at execution time.
This problem looks very similar to the usage of list() with empty slots: yet, list() is allowed to skip all but at least one element. With the modern short syntax of arrays and list, it might be tricky to distinguish them.
Example
<?php
$a = [,,,];
$a = array(,,,);
[,,$x] = [1,2,3];
list(,,$x) = [1,2,3];
?>
Alternatives
- Spot consecutive commas in an array() syntax.
Cannot use empty array entries in keyed array assignment
Description
The list() (also known as [] on the left side of the = sign), can skip some values, by using consecutive commas. This feature is only available with positional list(), which assign the n-th argument to the n-th element of the array.
Since PHP 7.1, list() accepts named element: this feature match the keys with their equivalent in the array, instead of matching the positions. With that feature, skipping an element in the array is useless: it is also not accepted by the PHP engine.
Example
<?php
$array = ['a' => 1, 3, 'b' => 2];
['a' => $a, , 'b' => $b] = $array;
// valid usage
[$a, , $b] = array_values($array);
?>
Alternatives
- Remove the extra comma.
- Remove the keys and use a positional list().
Cannot use empty list
Description
list() must contain at least one non-empty element. Otherwise, it would attempt to load data into no variables, and that makes no sense.
Example
<?php
[,,,] = [1,2,3];
list(,,,) = [1,2,3];
?>
Alternatives
- Add at least one variable in the list() call.
- Remove the call to list().
Related error messages
Cannot use isset() on the result of an expression (you can use “null !== expression” instead)
Description
isset() is meant to check the existence of an data container, such as a variable, an array element, a property of an object. It is not meant to check if an expression is null, because it is not a data container.
Expressions are valid with isset within a data container, though.
Example
<?php
$a = 'a';
$b = 'b';
if (isset($a . $b)) {}
// recommended by the error itself
if ($a . $b !== null) {}
// expression are valid with isset within a data container
if (isset($array[$a . $b])) {}
if (isset(${$a . $b})) {}
?>
Alternatives
- Use a comparison to null with an expression.
Related error messages
Cannot use isset() on the result of an expression
Description
isset() checks whether a data container, such as a variable, an array element or an object property, exists and is not null; it needs an actual container to look up, not a computed value. Concatenating $a and $b produces a plain expression with no container behind it, so isset() cannot be applied to it directly.
Example
<?php
$a = 'a';
$b = 'b';
if (isset($a . $b)) {}
// recommended alternative
if ($a . $b !== null) {}
?>
Alternatives
- Compare the expression to null instead: $a . $b !== null.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use lexical variable %s as a parameter name
Description
It is not possible to use a parameter and import a variable of the same name. This would result in a naming conflict, and a data overwrite. All names should be distinct.
Example
<?php
function ($a) use ($a) {};
?>
Literal Examples
- Cannot use lexical variable $x as a parameter name
Alternatives
- Rename the variable in the use clause.
- Rename the parameter in the function clause.
Cannot use list() as standalone expression
Description
list() assigns values from an array to a list of variables (or data containers). As such, it is a write operation, which should be on the left side of an assignment, or in other write positions, such as a foreach() blind variables or inside another list. list() cannot be used in a read position, as in the code example: list() as not result.
list() also has a short syntax version, []. That short syntax is converted to an array automatically, so it doesn’t yield any error then.
Example
<?php
[list($a)];
// the second [] is not a list() but an array().
[[$a]];
?>
Alternatives
- Use array() or [] instead.
Related error messages
Cannot use list as key element
Description
Since PHP 7.1, foreach can destructure the value of each entry with list() (or its short [] syntax): foreach ($array as $key => list($a, $b)). The key part, on the other hand, is always a single target: a variable, a property, or an array offset. It cannot itself be a list() pattern, since a single array key has nothing to be destructured into several variables.
Example
<?php
$array = [['a', 'b'], 'c', 'd'];
foreach ($array as list($key) => $value) {
}
?>
Literal Examples
- Cannot use list as key element
Alternatives
- Use a plain variable for the key, and only destructure the value with
list().
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
cannot use multiple endian options
Description
The third option of gmp_import() must be either GMP_BIG_ENDIAN, GMP_NATIVE_ENDIAN or GMP_LITTLE_ENDIAN, but not at the same time.
Example
<?php
gmp_import('a', 1, GMP_BIG_ENDIAN | GMP_LITTLE_ENDIAN);
?>
Literal Examples
- gmp_import(): Argument #3 ($flags) cannot use multiple word order options
Alternatives
- Use the
GMP_NATIVE_ENDIAN. - Use the
GMP_BIG_ENDIAN. - Use the
GMP_LITTLE_ENDIAN. - Use the default option, by omitting this argument (default is
GMP_NATIVE_ENDIAN).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
cannot use multiple word order options
Description
The third option of gmp_import() must be either GMP_MSW_FIRST or GMP_LSW_FIRST, but not at the same time.
Example
<?php
gmp_import('a', 1, GMP_MSW_FIRST | GMP_LSW_FIRST);
?>
Literal Examples
- gmp_import(): Argument #3 ($flags) cannot use multiple endian options
Alternatives
- Use the
GMP_MSW_FIRST. - Use the
GMP_LSW_FIRST. - Use the default option, by omitting this argument (default is
GMP_MSW_FIRST).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use object of type %s as array
Description
An object is not an array: as such, it cannot use the array syntax [1], based on square brackets, but the object syntax, with the object operators -> and ?->.
A class may be made compatible with the array syntax, by implementing the ArrayAccess. Then, it is possible to use the array syntax.
The scalar types are also forbidden to use the array syntax, although they are currently generating a warning, while the same error yields a Fatal Error.
Example
<?php
class X {}
$x = new X;
echo $x[0];
?>
Literal Examples
- Cannot use object of type x as array
Alternatives
- Cast the object to array before using the array syntax.
- Implement the ArrayAccess interface on the class.
- Use the object operators on the object.
Related error messages
Related error messages
Cannot use object of type stdClass as array
Description
The array syntax $variable[index] is only available for arrays and strings. When used on objects, PHP emits a fatal error.
The boolean false and the null value still accept this behavior. The first is deprecated in PHP 8.1, and the second valid in PHP 8.3.
Example
<?php
$x = new Stdclass();
$x[0] = 1;
?>
Alternatives
- Check for type before using the array syntax.
- Keep using consistent types with each variables.
- Set type with properties to ensure they are consistent.
- Cast the object to array before usage.
In previous PHP versions, this error message used to be :ref:cannot-unset-offset-in-a-non-array-variable.
In more recent PHP versions, this error message is now :ref:cannot-unset-offset-in-a-non-array-variable.
Cannot use positional argument after argument unpacking
Description
It is not possible to put simple arguments after an unpacked argument. Said another way, the unpacked arguments must be the last one in the list.
This happens when using a mix of array unpacking and arguments. It also happens when spreading an array with a mix of numeric and string keys.
Example
<?php
// Valid, the unpacked argument is the last
foo($a, $b, ...$c);
// Also valid, the unpacked arguments are the last
foo($a, $b, ...$c, ...$d);
// Not valid
foo(...$a, $b, ...$c);
// This is invalid, as the numeric arguments are after the 'x'
$a = ['x' => [1], 13, 14];
foo(...$a);
// This is valid, as long as x is not argument 0 or 1. Then, it yields another error.
$a = [13, 14, 'x' => [1]];
foo(...$a);
?>
Alternatives
- Move the positional arguments to be beginning of the signature call.
- Sort the unpacked array with krsort() or ksort(), before or after PHP 8.2.
- Remove the positional arguments.
Related error messages
Cannot use positional argument after named argument during unpacking
Description
This error appears when using an array with a mix of integer and string keys, and spread it as arguments. The actual order of the array is used as the order of the arguments in the function call. Then, integer keys are used as positional arguments, and string keys are as named arguments.
Example
<?php
function foo($a, $b, $c) {}
// unpacking argument, but positional argument is misplaced
$arguments = ['a' => 1, 2, 'c' => 3];
foo(...$arguments);
// make everyone positional. It works since order is already correct
foo(...array_values($arguments));
?>
Alternatives
- Add the missing argument names to finish the argument array.
- Move the positional argument to the beginning of the array (array_unshift, or append it at the array creation), when the argument order makes it possible.
- Use ksort() on the keys, when it makes sense.
Related error messages
- named-parameter-$%s-overwrites-previous-argument
- cannot-use-argument-unpacking-after-named-arguments
Cannot use positional argument after named argument
Description
When using a mix of array unpacking and arguments, it is not possible to put the arguments after the unpacked argument. Said another way, the unpacked arguments must be the last one in the list.
Example
<?php
// Valid, the unpacked argument is the last
foo($a, $b, ...$c);
// Also valid, the unpacked arguments are the last
foo($a, $b, ...$c, ...$d);
// Not valid
foo(...$a, $b, ...$c);
?>
Alternatives
- Write the positional argument before the named ones in the call.
Related error messages
Cannot use result of built-in function in write context
Description
Binding a reference to the return value of a function ($var = &func();) only makes sense if that function itself returns by reference. Built-in, C-implemented functions never do, and unlike a user-defined function, where forgetting the & in the signature merely triggers a notice at run time, the engine can tell this is impossible for an internal function right away, and raises a compile-time error instead.
Example
<?php
$max = &max(1, 2, 3);
?>
Alternatives
- Drop the &, and assign the return value normally: $max = max(1, 2, 3);
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use string offset as an array
Description
It is possible to use the array syntax $s[$i] on a string, to access an individual character. And in general, it is also possible to chain the array syntax to access multi-dimensionnal elements $array[1][2].
Yet, the individual characters of a string are not arrays, so it is not possible to use that syntax with them, while reading it from the string.
On the other hand, it is possible to assign the character to a variable: PHP considers it then as a normal string.
Example
<?php
$string = '123';
unset($string[0][1]);
?>
Alternatives
- Remove the 2nd array syntax when working with a string.
- Assign the character to a variable, and then use it as a string.
Related error messages
Cannot use string offset as an object
Description
It is possible to use the array syntax $s[$i] on a string, to access an individual character. And in general, it is also possible to chain the array syntax to access properties $array[1]->p.
Yet, the individual characters of a string are never objects, so it is not possible to use that syntax with them, while reading it from the string.
Example
<?php
$string = '123';
unset($string[0]->a);
?>
Alternatives
- Remove the 2nd array syntax when working with a string.
Related error messages
Cannot use temporary expression in write context
Description
Literal values and constants, global or class, cannot be used for writing: they are immutable. When it is attempted nontheless, this error is displayed.
Those values must be placed in a container, such as a variable, array element, property or static property. That way, they become updatable.
The literal values may be hidden in a returned value, or by a call to native PHP functions which return literals. They may also be hidden in a foreach() call, which does implicit assignments.
This is also the case with the append $variable[] operator, and with object notations on a a constant.
Passing a dimension fetch on a temporary by reference is also not allowed.
The surprising error message comes from the temporary expression built by PHP, to allow a read access to the value. echo A->p; is a read access, while A->p = 3 is a write access.
Example
<?php
// This emits the error
A->p = 3;
// This is a syntax error
// A = 3;
// Attempt to append 1 to an empty literal array
[][] = 1;
array()[] = 1;
$a = array();
$a[] = 1;
$fn = function(&$ref) {};
$fn([0, 1][0]);
function goo() { return [0, 1][0];}
// The constant is hidden in the function goo()
$fn(goo());
function hoo($fn) {
// PHP provide literal values
$fn(func_get_args()[0]);
}
?>
Alternatives
- Store the literal value in a variable, a property or an array index before writing to it.
Related error messages
- [syntax-error,-unexpected-‘;’,-expecting-’’
- [syntax-error,-unexpected-token-“;”,-expecting-“->”-or-“?->”-or-““
- [syntax-error,-unexpected-token-“;”,-expecting-“->”-or-“?->”-or-“{”-or-““
- can’t-use-function-return-value-in-write-context
- can’t-use-method-return-value-in-write-context
Cannot use the %s modifier on a %s
Description
This is a generic error message for cases where a keyword cannot be used with a class structure. For example, a class constant cannot be abstract or static.
A special case is using final on a parameter: final is reserved for properties, although properties may be promoted, and also used as a parameter in a constructor. Then, it is not possible to declare the property final, or in the constructor.
final for class constant was also unavailable in PHP 8.0, and it is now a feature.
Example
<?php
class X {
private final const A = 1;
private abstract const B = 1;
private static const C = 1;
function __construct (
final public $p = 1
) {}
}
?>
Literal Examples
- Cannot use the final modifier on a class constant
- Cannot use the abstract modifier on a class constant
- Cannot use the static modifier on a class constant
- Cannot use the final modifier on a parameter
Alternatives
- Remove the option from the class constant definition.
- Upgrade to PHP 8.1 or later, for
finalon class constants.
In previous PHP versions, this error message used to be :ref:cannot-use-'static'-as-constant-modifier.
Cannot use the abstract modifier on a property hook
Description
It is not possible to make individual property hooks abstract. The keyword must be set at the property definition level, for all the hooks.
Example
<?php
abstract class X {
public $property {
abstract get;
}
}
?>
Alternatives
- Remove the abstract keyword, and put it on the property definition level.
Related error messages
Cannot use the abstract modifier on a property
Description
Properties cannot be abstract, as they are always available in the class where they are defined.
This will change in PHP 8.4, with property hooks and abstract hooks. Until then, abstract properties are not valid.
Example
<?php
abstract class X {
public abstract string $x;
}
?>
Alternatives
- Upgrade to PHP 8.4, and use hooked properties.
- Remove the abstract keyword.
- Use magic methods
__getand__setto define a custom alternative property.
In more recent PHP versions, this error message is now :ref:only-hooked-properties-may-be-declared-abstract.
Cannot use the final modifier on a parameter
Description
The final option is not available for promoted properties, until PHP 8.5. Until then, the property shall be final but not promoted, or it has to be declared the traditional way.
Example
<?php
class X {
function __construct(
public final int $i
) {}
}
?>
Alternatives
- Upgrade to PHP 8.5 or more recent.
- Remove the final property from the promoted property.
- Create the property in the class body.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use the final modifier on a property
Description
When a property is final, it cannot be overridden in a child class; when a class is private, it is only available in the current class.
Hence, a property cannot be final and private at the same time.
In this situation, the property may not final, as there are no property hooks.
Example
<?php
class X {
final private $property;
}
?>
Alternatives
- Remove the hooks, and use the magic methods __get/__set.
- Remove the final keyword.
- Remove the private keyword and use protected or public.
In more recent PHP versions, this error message is now :ref:property-cannot-be-both-final-and-private.
Cannot use the final modifier on an abstract class
Description
The options final and abstract are mutually exclusive. The first one prevents any redefinition by children, while the second one requests an implementation, and as such, a redefinition, in children classes.
It is the same message, whatever the order of the options.
Example
<?php
final abstract class X {}
abstract final class Z {}
?>
Alternatives
- Drop the
abstractoption. - Drop the
finaloption. - Drop both the options.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use the static modifier on a parameter
Description
It is not possible to use static as a type for a parameter. It is possible for a return value, but not for parameters, not properties.
Example
<?php
class X {
function foo(static $argument) {
}
}
?>
Alternatives
- Use self pseudo-type.
- Use the name of the class as type.
- Use one of the interface as type.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use the static modifier on a property hook
Description
It is not possible to make individual property hooks static. The keyword must be set at the property definition level, for all the hooks.
Example
<?php
class X {
public $property {
static get;
}
}
?>
Alternatives
- Remove the abstract keyword, and put it on the property definition level.
Related error messages
Cannot use trait %s
Description
An enum’s cases and its constants share a single namespace: a case and a constant cannot have the same name, whether the constant is declared directly in the enum or brought in through a trait.
Here, the trait HasColor declares a constant called Red, and the enum also declares a case called Red; composing the enum with the trait would leave two different things answering to the same name, so PHP refuses to use the trait.
This entry records only the first sentence of the actual engine message, which continues with , because %s::%s conflicts with enum case %s::%s, naming the trait, the constant, the enum and the case involved.
Example
<?php
trait HasColor {
const Red = 'red';
}
enum Color {
use HasColor;
case Red;
}
?>
Literal Examples
- Cannot use trait HasColor, because HasColor::Red conflicts with enum case Color::Red
Alternatives
- Rename the constant in the trait so it no longer collides with the enum case.
- Rename the conflicting case in the enum.
- Stop using the trait in this enum, and declare the constant directly in the enum, merging it with the case some other way.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use traits inside of interfaces. %s is used in %s
Description
The command use cannot be used in an interface to include a trait. The trait must be included at the class level, or in another trait.
Example
<?php
interface I {
use T;
}
?>
Literal Examples
- Cannot use traits inside of interfaces. T is used in I
Alternatives
- Use the trait in the target classes.
Cannot use try without catch or finally
Description
Try command have catch and finally clauses. While both are optional, they can’t be omitted both at the same time.
Example
<?php
try {}
?>
Alternatives
- Add a catch clause.
- Add a finally clause.
Cannot use unpacking in attribute argument list
Description
Attribute arguments are compiled into constant expressions, and evaluated only when the attribute is read through Reflection. The spread/unpacking operator ... needs a runtime array to unpack, which conflicts with this compile time, constant-only nature of attribute arguments.
Unpacking is therefore not allowed in the argument list of an attribute, even when the array being spread only contains constant values.
Example
<?php
#[Attribute]
class MyAttribute
{
public function __construct(int $a, int $b) {}
}
$args = [1, 2];
#[MyAttribute(...$args)]
class X {}
?>
Alternatives
- List each argument explicitly, instead of unpacking an array.
- Use named arguments instead, if this improves readability.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use variable $%pS twice
Description
The use clause of a closure lists the variables imported from the enclosing scope. Each variable can only appear once in that list: importing the same variable twice, whether by value or by reference, is redundant and not allowed.
This is checked at compile time, as the use list is processed.
Example
<?php
function foo() {
$a = 1;
return function () use ($a, $a) {
return $a;
};
}
?>
Literal Examples
- Cannot use variable $a twice
Alternatives
- Remove the duplicate entry in the
useclause.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Cannot use variable $%S twice
Description
The same variable cannt be mentioned twice in the use part of a closure definition. This would mean the same argument is defined twice, which is useless.
Example
<?php
$fn = function() use ($a, &$a) {
$a = 2;
};
?>
Literal Examples
- Cannot use variable $a twice
Alternatives
- Make all variables mentioned in the use expression unique (with or without the reference).
Case %s of backed enum %s must have a value
Description
In a backed enumeration, all the cases must have a value. There are no default values for cases, not automatic assignation. This applies to both int and string enumerations.
Example
<?php
enum E: int {
case A = 1;
case B;
}
?>
Literal Examples
- Case B of backed enum E must have a value
Alternatives
- Add all the missing values to the cases.
- Remove the type of the enum.
Case %s of non-backed enum %s must not have a value
Description
An enum is either purely a set of named cases (a pure enum), or it is a backed enum, where every case is associated with an int or string value declared after the enum name, like enum Suit: int.
Once an enum does not declare a backing type, none of its cases may be given a value. Assigning a value to a case, like case Hearts = 1;, requires the enum itself to declare a backing type.
Example
<?php
enum Suit
{
case Hearts = 1;
case Spades;
}
?>
Literal Examples
- Case Hearts of non-backed enum Suit must not have a value
Alternatives
- Remove the value from the case declaration, to keep the enum a pure enum.
- Add a backing type to the enum declaration, such as
enum Suit: int, so every case can carry a value.
Related error messages
- enum-case-type-%s-does-not-match-enum-backing-type-%s
- enum-backing-type-must-be-int-or-string
- duplicate-value-in-enum-%s-for-cases-%s-and-%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Case %s::%s does not exist
Description
This error is reported by the Reflection API, when trying to generate the informational object ReflectionEnumUnitCase, with a non-existing Case.
Example
<?php
enum E {
case a;
}
$reflectionEnum = new ReflectionEnum(E::class);
$reflectionEnum->getCase('b');
?>
Literal Examples
- Case E::b does not exist
Alternatives
- Make sure the case exists before trying to instantiate its relate object.
Case can only be used in enums
Description
case is a keyword which is reserved for enumerations enum. It cannot be used in other structures, such as traits, interfaces or classes.
Example
<?php
class X {
case A = 1;
}
?>
Alternatives
- Make the class an enumeration.
- Remove the case from the class.
Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead
Description
It is possible to use a semi-colon ; instead of a colon : after a case in a switch. This is deprecated in PHP 8.5, and will disappear in PHP 9.
Example
<?php
switch($a) {
case 1;
echo one;
break;
}
?>
Alternatives
- Replace the semicolon by a colon.
- Do not place a closing tag after a case value.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See case-with-semicolon
Charset “%s” is not supported, assuming UTF-8
Description
The provided character set, third argument, is not valid.
Example
<?php
htmlentities($a, $b, 'xxx');
?>
Literal Examples
- Charset “xxx” is not supported, assuming UTF-8
Alternatives
- Use a valid character set.
- Check for typos, or empty values.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Class “%s” not found
Description
This error message is reported when the class could not be loaded, or when the name of the class is invalid.
It appears when the classes are defined after they are required. It applies to classes in the same file, and never with autoloading.
It also appears when unserializing an enumeration: PHP cannot distinguish a class constant or an enumeration case, so it reports a class error. Yet, this is the enuneration missing.
Example
<?php
// No x definition in the code
new X;
// it is not possible to have a class, with the name '4f'
('4f')::c;
// it is not possible to have a class, with the name 'class'
('class')::c;
// it is not possible to have static, self or parent in a string to call a method
static::foo();
// unserializing an enumeration, but no such enumration.
print_r(unserialize("a:1:{i:0;E:3:"f:A";}"));
// B is defined after being required by A, so this is a fatal error.
class A extends B {}
class B extends C {}
class C {}
?>
Literal Examples
- Class “x” not found
- Class “4f” not found
- Class “class” not found
Alternatives
- Check spelling and namespace for that class.
- Create the required class.
- Check if the class is defined in an extension, and the extension is included in the current PHP engine.
- Check if the class is defined in a dependency, and the dependency is included in the current composer.json.
- Avoid using getInstance() on that attribute.
- Do not use static, parent or self in a string to call a method statically.
- Check that the enumeration is loaded.
- Put classes in different files, and use autoload.
Related error messages
Class %s cannot extend %s %s
Description
A class that is marked final cannot be extended. This error applies to a class that tries to use a final class as parent.
Example
<?php
final class X {}
class Y extends X {}
?>
Literal Examples
- Class T cannot extend class X
Alternatives
- Remove the
finalkeyword on the parent class. - Use composition in the intended child class.
Class %s cannot extend enum %s
Description
Enum are final classes, and cannot be extended: neither by other enum, nor by a class.
Example
<?php
class X extends E {}
enum E {}
?>
Literal Examples
- Class X cannot extend enum E
Alternatives
- Add a class that compose the enum, and extends that class.
- Remove the extension in the class.
Class %s cannot extend final class %s
Description
A final class is a class that cannot be extended. This means any class that attempts to use extends on this class fails.
This error is produced both by userland code and PHP native code, such as Generator, etc.
Example
<?php
class X extends Generator {}
?>
Literal Examples
- Class X cannot extend final class Generator
Alternatives
- Use composition on the final class, to include it in another class.
Related error messages
Class %s cannot implement both Iterator and IteratorAggregate at the same time
Description
This error appears when a class uses two or more interfaces, which are incompatible with one another. The incompatibility is based on name conflicts: two interfaces have a method with the same name.
There is a distinct error for constants. There is the same message for properties, since PHP 8.4.
Example
<?php
class A implements Iterator, IteratorAggregate {}
?>
Literal Examples
- Class A cannot implement both Iterator and IteratorAggregate at the same time
Alternatives
- Choose one or the other interface.
- Use the interface that is compatible with the parent classes.
Related error messages
Class %s cannot implement previously implemented interface %s
Description
It is not allowed to use several times the same interface in a implements clause, for classes, or extends for interfaces.
The message is a bit confusing, since the interface is not already implemented, but rather, used in the implements clause. In fact, PHP checks first the list of names of the clause, then it checks the signatures of the methods.
This error message is dependent on the use expresion, and also the calls to class_alias().
Example
<?php
use I as J;
interface I {}
// Multiple ways to reference an interface
class Foo implements I, \I, J {}
// This applies to interfaces too
interface Bar extends I, \I, J {}
?>
Literal Examples
- Class foo cannot implement previously implemented interface i
Alternatives
- Remove the duplicate interface name.
Class %s cannot use %s - it is not a trait
Description
This message comes from zend_class_use_internal_traits(), an internal engine API added to let a C extension attach traits to a class entry it registers, outside of the regular use statement compiled from PHP source (support for traits on internal classes was added late in the PHP 8.6 development cycle). It fires when one of the class entries passed in is not actually a trait.
There is no PHP userland API that reaches this function, so ordinary application code cannot trigger it; it can only show up as the result of a bug in an extension that registers its own classes and passes the wrong class entry as a trait.
The near-identical runtime message, %s cannot use %s - it is not a trait (without the leading word Class), is the one produced by an ordinary use TraitName; inside a PHP class body when TraitName refers to something other than a trait, such as an interface or an ordinary class.
Example
<?php
enum Color {
case Red;
}
class X {
use Color;
}
?>
Literal Examples
- x cannot use Color - it is not a trait
Alternatives
- If this appears while developing a PHP extension, check the class entries passed to
zend_class_use_internal_traits()and make sure each one was registered withZEND_ACC_TRAIT. - If this appears while using a third-party extension, report the issue to its maintainer, since it points to a bug in the extension rather than in the PHP script.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods
Description
A long as there is one absract method in a class, the whole class must be declared abstract. That way, it cannot be instantiated: if a method is missing a body for execution, this definitely must be impossible.
Example
<?php
class X {
abstract function foo() ;
}
?>
Literal Examples
- Class X contains 1 abstract method and must therefore be declared abstract or implement the remaining methods
Alternatives
- Remove the abstract option on the method(s) and give the a body block.
- Add the abstract keyword to the class.
Related error messages
- non-abstract-method-%s::%s()-must-contain-body
- anonymous-class-method-%s()-must-not-be-abstract
- %s-%s-contains-%d-abstract-method%s-and-must-therefore-be-declared-abstract-or-implement-the-remaining-method%s-(
- %s-%s-must-implement-%d-abstract-method%s-(
Class %s declares abstract method %s() and must therefore be declared abstract
Description
A class that contains an abstract method must also be declared abstract.
Example
<?php
class A {
abstract function foo() ;
}
?>
Alternatives
- Remove the
abstractmethod. - Remove the
abstractoption on the method and give it a body. - Add the
abstractoption to the class.
Related error messages
- %s-%s-contains-%d-abstract-method%s-and-must-therefore-be-declared-abstract-or-implement-the-remaining-method%s-(
- %s-method-%s::%s()-must-not-be-abstract
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Class %s does not have a property named %s
Description
The reflection extension allows the manipulation of various aspect of existing objects. Yet, it doesn’t allow the assignation of values to non-existing properties, static or not.
Example
<?php
class X { }
$rc = new ReflectionClass('X');
$rc->setStaticPropertyValue('property', 'value');
?>
Literal Examples
- Class X does not have a property named property
Alternatives
- Make sure the property exists before trying to assign it a value.
- Make sure the property is static.
Class %s implementing SessionHandlerInterface is missing the create_sid() method which will be required in PHP 9.0
Description
SessionIdInterface::create_sid() is currently optional: a class only needs it when it also implements SessionIdInterface (as SessionHandler does internally). PHP is moving toward merging SessionIdInterface into SessionHandlerInterface itself, so that every custom session handler is required to provide its own session-id generation strategy. Starting with this deprecation, any class implementing SessionHandlerInterface without a create_sid() method triggers a warning, because in PHP 9.0 the method will become mandatory and its absence will be a fatal error.
Example
<?php
class MySessionHandler implements SessionHandlerInterface {
public function open($path, $name): bool { return true; }
public function close(): bool { return true; }
public function read($id): string|false { return ''; }
public function write($id, $data): bool { return true; }
public function destroy($id): bool { return true; }
public function gc($max_lifetime): int|false { return 0; }
}
session_set_save_handler(new MySessionHandler());
session_start();
?>
Literal Examples
- Class MySessionHandler implementing SessionHandlerInterface is missing the create_sid() method which will be required in PHP 9.0
Alternatives
- Add a public
create_sid(): stringmethod to the class. - Extend
SessionHandlerinstead of implementingSessionHandlerInterfacedirectly; it already provides a defaultcreate_sid()implementation.
Related error messages
In more recent PHP versions, this error message is now :ref:class-%s-implementing-sessionhandlerinterface-is-missing-the-validateid()-method-which-will-be-required-in-php-9.0.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See sessionHandlerCompleteInterface
Class %s implementing SessionHandlerInterface is missing the validateId() method which will be required in PHP 9.0
Description
SessionIdInterface::validateId() is currently optional: a class only needs it when it also implements SessionIdInterface (as SessionHandler does internally). PHP is moving toward merging SessionIdInterface into SessionHandlerInterface itself, so that every custom session handler is required to validate incoming session identifiers before they are used. Starting with this deprecation, any class implementing SessionHandlerInterface without a validateId() method triggers a warning, because in PHP 9.0 the method will become mandatory and its absence will be a fatal error.
Example
<?php
class MySessionHandler implements SessionHandlerInterface {
public function open($path, $name): bool { return true; }
public function close(): bool { return true; }
public function read($id): string|false { return ''; }
public function write($id, $data): bool { return true; }
public function destroy($id): bool { return true; }
public function gc($max_lifetime): int|false { return 0; }
}
session_set_save_handler(new MySessionHandler());
session_start();
?>
Literal Examples
- Class MySessionHandler implementing SessionHandlerInterface is missing the validateId() method which will be required in PHP 9.0
Alternatives
- Add a public
validateId(string $id): boolmethod to the class. - Extend
SessionHandlerinstead of implementingSessionHandlerInterfacedirectly; it already provides a defaultvalidateId()implementation.
Related error messages
In previous PHP versions, this error message used to be :ref:class-%s-implementing-sessionhandlerinterface-is-missing-the-create_sid()-method-which-will-be-required-in-php-9.0.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See sessionHandlerCompleteInterface
Class %s is not a trait, Only traits may be used in ‘as’ and ‘insteadof’ statements
Description
It is not possible to use a class name in a use block: the block only uses traits information.
The class method have priority over the trait methods, so there is no need to explicitly solve such conflict. On the other hand, when the trait has to have priority, it has to be specified as such, using a trait name.
Any method defined in a parent class is assimilated to the current class, and has priority.
Example
<?php
class X {}
trait T {}
class Y extends X {
use T{ X::foo instead of T; };
}
?>
Literal Examples
- Class x is not a trait, Only traits may be used in ‘as’ and ‘insteadof’ statements
Alternatives
- Remove the use block entry that mentions the class.
- Fix the name of the class, with the name of a trait.
Class %s must implement interface %s as part of either %s or %s
Description
It is not possible to implement directly the mentioned interface. That interface is actually implemented by a selection of PHP native classes: these classes may be extended, and, as such, the children classes also implements the initial interface.
This error message is applicable to a few PHP native interfaces, such as Throwable (via Error and Exception) and Traversable (via Iterator and IteratorAggregate).
Example
<?php
class X implements Throwable {}
?>
Literal Examples
- Enum Foo must implement interface Traversable as part of either Iterator or IteratorAggregate
- Class X cannot implement interface Throwable, extend Exception or Error instead
Alternatives
- Extends one of the classes mentioned in the error message.
- Remove the implementats and its interface.
In more recent PHP versions, this error message is now :ref:%s-%s-must-implement-interface-%s-as-part-of-either-%s-or-%s.
Class constant %s::%s cannot have type %s
Description
Some native PHP types are not allowed with a class constant. This is the case of void, never and callable. Any mention of them, alone or in a compsed type generates this error.
Example
<?php
class X {
const callable|int A = 1;
}
?>
Literal Examples
- Class constant X::A cannot have type callable|int
Alternatives
- Remove any illegal type from the definition of the constant.
- Remove all types from the definition of the constant.
Related error messages
Class declarations may not be nested
Description
It is not allowed to define a class, trait, interface or enum inside another class, trait or enum.
Conditional classes, trait, interfaces or enum may be created, inside if/then, functions and closures, or also loop structures.
The error message is the same for all types of structures, and only mentions class.
Example
<?php
class X {
function foo() {
class Y {}
}
}
?>
Alternatives
- Use an anonymous class.
- Use a conditional class, with a if/then, in the global space.
- Use a function to store the definition and call it at will.
Related error messages
Classes must be first marked as attribute before being able to be registered as internal attribute class
Description
This error could not be reproduced so far. Help us by sending us any generating code.
Example
Alternatives
clone(): Argument #1 ($object) must be of type object, %s given
Description
This is the error message when an attempt of cloning is made on an piece of data that is not an object.
Example
<?php
clone(1);
?>
Literal Examples
- clone(): Argument #1 ($object) must be of type object, int given
- clone(): Argument #1 ($object) must be of type object, string given
- clone(): Argument #1 ($object) must be of type object, array given
Alternatives
- Check that the cloned value is actually an object.
In previous PHP versions, this error message used to be :ref:clone-method-called-on-non-object.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Closures in constant expressions must be static
Description
When defining a closure as a constant value, there cannot be any context value that are imported. This includes the current object $this which is included by default in any closure. To avoid this, the static option must be added to the closure.
Example
<?php
class X {
const MY = function () { return 1;}
}
?>
Alternatives
- Add the static option to the closure.
- Define the closure inside a method.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Constant %s already defined
Description
When a global constant is defined again, PHP reports a warning, and ignores the second definition.
This error applies to global constants only: class constants emit a fatal error, and a different message.
Example
<?php
const A = 1;
const A = 2;
echo A;
define('A', 3);
echo A;
?>
Literal Examples
- Constant A already defined
Alternatives
- Remove the second definition.
- Remove the first definition.
- Fix the name of one of the constants.
- Check if there are no missing namespace.
Related error messages
Constant %s is deprecated
Description
This error is emitted when a global constant is supported in the current PHP engine, but will be removed in a future version.
The error is emitted every time the constant is used: it may be for its actual intend, or anywhere else.
Example
<?php
error_reporting(E_STRICT);
?>
Literal Examples
- Constant E_STRICT is deprecated
Alternatives
- Stop using that global constant.
- Find the replacement for this global constant: it might be another constant, or a different command entirely.
Related error messages
Constant %s::%s is deprecated
Description
This error is emitted when a class constant is supported in the current PHP engine, but will be removed in a future version.
The error is emitted every time the class constant is used: it may be for its actual intend, or anywhere else.
The error message is also emitted with the usage of the Deprecated attribute, since PHP 8.4.
Example
<?php
class X {
#[Deprecated()]
public const D = deprecated;
}
echo X::D;
?>
Literal Examples
- Constant X::D is deprecated
Alternatives
- Stop using that class constant.
- Find the replacement for this class constant: it might be another constant, or a different command entirely.
Related error messages
Constant expression contains invalid operations
Description
The Constant expressions are the value of a constant, global or class, that is not a literal value. They are calculated.
Constant expressions allows literals, other constants, and most of the operators. Some elements are forbidden: variables, functions, methods and cast operators.
Properties are allowed, but only on enumeration’s cases. New and arrays are allowed, and so does the ternary and coalesce operators, leading to possible conditional constants expressions (sic). Magic constant are also OK.
Example
<?php
class X {
// invalid, because of the usage of the variable
const X = $a;
}
?>
Alternatives
- Remove the invalid elements or operations.
Related error messages
Constructor %s::%s() cannot declare a return type
Description
There can be no return type for a constructor method. It is called while creating a new instance of an object, but it doesn’t return the object itself. This is the case even if $this is available in the method.
Example
<?php
class X {
function __construct() : int {
}
}
?>
Literal Examples
- Constructor X::__construct() cannot declare a return type
Alternatives
- Remove the return type of the method.
Related error messages
- destructors-cannot-declare-a-return-type
- method-%s::__construct()-cannot-declare-a-return-type
- making-a-constructor-a-generator-is-deprecated
- returning-a-value-from-a-constructor-is-deprecated
In more recent PHP versions, this error message is now :ref:method-%s::__construct()-cannot-declare-a-return-type.
contains an invalid cURL option
Description
curl_setopt() uses a cURL option as second parameter. These options are PHP native constants, and use the prefix CURLOPT_, which resolve to an integer.
It is possible to use the equivalent integer to set a cURL option, for example via a variable. The value of this variable must be checked to be a valid cURL constant before usage.
Using another type instead of a cURL constant is reported as an error of type.
Example
<?php
$ch = curl_init(http://www.example.com/);
$fp = fopen(example_homepage.txt, w);
curl_setopt($ch, 12332, $fp);
curl_setopt($ch, 'abc', $fp);
?>
Alternatives
- Use the
CURLOPT_*constant. - Check that the intended value may be resolved as a
CURLOPT_*constant (CURLOPT_APPEND=== 50, so 50 may be used; etc.).
Related error messages
Related error messages
continue“ targeting switch is equivalent to “break
Description
The recommendation is to use break inside a switch, and continue in loops. Both keywords achieve the same feature of terminating the current structure and following up with the execution, they carry different human meanings.
Example
<?php
switch($a) {
case 1:
continue;
}
?>
Alternatives
- Use
break.
continue operator accepts only positive integers
Description
continue indicates the number of nested loop to continue in. The minimum is 1. 0 would be a no operation, and shall be skipped. Negative numbers or decimals make no sense.
Example
<?php
$a = [];
foreach($a as $b) {
continue 0;
}
?>
Alternatives
- Remove the continue command.
- Remove the 0.
Related error messages
Could not check compatibility between %s and %s, because class %s is not available
Description
This error message signals that PHP could not find all the needed classes and interfaces to reach a conclusion about the compatibility of V, compared to W.
PHP checks all the classes and interfaces whose definitions are already known, and, eventually, calls autoload to get the missing classes. When all avenues are exhausted, PHP yields this error.
In fact, if checking compatibility fails, the code will not run later anyway.
Example
<?php
class V {
function foo() : X { }
}
class W extends W {
function foo() : Y { }
}
?>
Literal Examples
- Could not check compatibility between V::foo() and W::foo(), because class X is not available
Alternatives
- Use existing classes or interfaces as type.
- Fix typos in type names.
- Add any missing class or interface.
Could not find trait %s
Description
A trait is named in a use expression inside a class, but it doesn’t exist, or is not yet loaded by PHP.
The trait may be included in a different use expression. Then, it generates a distinct error message.
Note that when the trait exists and is known to PHP, there is a distinct error message.
Example
<?php
trait A {
public function foo(){}
}
class B {
use A {
C::foo as tf;
}
}
?>
Literal Examples
- Could not find trait C
Alternatives
- Remove the expression that mentions the non-existing trait.
- Create the missing trait.
- Add the trait to the class.
Couldn’t open stream %s
Description
When opening a stream, or file, a mode of operation is needed.
There are several valid modes: ‘r’, ‘r+’, ‘w’, ‘w+’, ‘a’, ‘a+’, ‘x’, ‘x+’, ‘c’, ‘c+’, ‘e’. Check docs for details about them.
All other strings are not supported, and yield this error.
Example
<?php
//`+k' is not a valid mode for fopen
// k is not an open option
fopen($path, '+k');
//`+wr' is not a valid mode for fopen
// write-only w, read-only r and + are mutually exclusive
// w+, r+ and rw are all valid
fopen($path, '+wr');
?>
Alternatives
- Use only valid stream open modes.
Related error messages
In more recent PHP versions, this error message is now :ref:couldn't-open-stream:-%s.
Couldn’t open stream: %s
Description
When opening a stream, or file, a mode of operation is needed.
There are several valid modes: ‘r’, ‘r+’, ‘w’, ‘w+’, ‘a’, ‘a+’, ‘x’, ‘x+’, ‘c’, ‘c+’, ‘e’. Check docs for details about them.
All other strings are not supported, and yield this error.
Example
<?php
//`+k' is not a valid mode for fopen
// k is not an open option
fopen($path, '+k');
//`wr' is not a valid mode for fopen
// write-only w and read-only r are mutually exclusive
fopen($path, 'wr');
?>
Literal Examples
- Couldn’t open stream: ‘+k’ is not a valid mode for fopen
- Couldn’t open stream: Is a directory
- Couldn’t open stream: Inappropriate ioctl for device
- Couldn’t open stream: Invalid argument
Alternatives
- Use only valid stream open modes.
Related error messages
In previous PHP versions, this error message used to be :ref:couldn't-open-stream-%s.
Creating default object from empty value
Description
This deprecation message is emitted in PHP 7.x to signal that an object was created without instantiation. In the illustration code, $x does not exist before assigning it a property a, and a value. The created object is stdClass.
This error is specific to the creation of the variable: if $x was set with null, a different message was emitted.
Example
<?php
$x->a = 1;
?>
Alternatives
- Explicitly create the object before accessing its properties.
- Cast an array to
(object). - Instanciate a
stdClass.
In more recent PHP versions, this error message is now :ref:attempt-to-assign-property-"%s"-on-null.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See creatingObjectOnNull
Creation of dynamic property %s::$“ ZEND_LONG_FMT “ is deprecated
Description
This is the numeric-key twin of the more common Creation of dynamic property %s::$%s is deprecated notice. It fires when the property key being written is an integer rather than a string – most often while restoring an object with unserialize() from data whose property key was encoded as i:N; instead of the usual s:len:"name";. Since the class does not declare a property named after that integer and has not opted in with #[AllowDynamicProperties], PHP falls back to creating a dynamic property, but flags it as deprecated just like any other undeclared property write.
As of PHP 8.2, this deprecation also closes a gap where such integer-keyed properties could otherwise bypass the dynamic-property protections entirely.
Example
<?php
class Foo {
}
// PHP's serialization format allows an object property key to be
// stored as an integer ('i:0;') instead of a string ('s:1:"0";').
$serialized = 'O:3:"Foo":1:{i:0;s:1:"x";}';
$foo = unserialize($serialized);
var_dump($foo);
?>
Literal Examples
- Creation of dynamic property Foo::$0 is deprecated
Alternatives
- Declare the property in the class definition so the key, once cast to string, matches a known property.
- Add the #[AllowDynamicProperties] attribute to the class if dynamic properties are intentional.
- Sanitize or validate serialized data before calling unserialize(), rather than trusting arbitrary property keys.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See dynamicProperties
Creation of dynamic property %s::$%s is deprecated
Description
When PHP uses an undefined property for a writing access, it used to create that property on the fly. The property is created with public visibility, not type nor default value.
Since PHP 8.2, this is a deprecated feature. In a later version, by default, dynamic properties will be forbidden, and activated case by case, using sdtClass or the #[AllowDynamicProperties] attribute.
Example
<?php
class X {
public $property = 1;
}
$x = new X;
$x->property = 2;
// This is a dynamic property
$x->other = 3;
?>
Alternatives
- Declare the property in the class definition.
- Create an array and store the properties there.
- Create a stdClass object and store the properties there.
- Add the
#[AllowDynamicProperties].
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See dynamicProperties
CURLPIPE_HTTP1 is deprecated
Description
CURLPIPE_HTTP1 is a flag that used to enable HTTP/1.1 pipelining when passed to curl_multi_setopt() with the CURLMOPT_PIPELINING option. Support for HTTP/1.1 pipelining was removed from libcurl itself in version 7.62.0, because it proved fragile and was superseded by HTTP/2 multiplexing.
When PHP is linked against a libcurl older than 7.62.0, setting this flag still works but now raises an E_DEPRECATED notice. When linked against libcurl 7.62.0 or later (the common case on current systems), the same code instead raises an E_WARNING stating that CURLPIPE_HTTP1 is no longer supported, and the flag has no effect either way.
Example
<?php
$mh = curl_multi_init();
curl_multi_setopt($mh, CURLMOPT_PIPELINING, CURLPIPE_HTTP1);
?>
Alternatives
- Remove
CURLPIPE_HTTP1from the value passed tocurl_multi_setopt($mh, CURLMOPT_PIPELINING, ...). - Use
CURLPIPE_MULTIPLEXto enable HTTP/2 multiplexing instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See curl_multi_setopt
Current function is not a closure
Description
The Closure::getCurrent() method may only be called inside a closure or an arrow function.
This error message also applies to methods.
Example
<?php
function foo() {
echo Closure::getCurrent();
}
foo();
?>
Alternatives
- Remove the call to
Closure::getCurrent()from the function. - Turn the funciton into a closure or an arrow function.
DateTimeInterface can’t be implemented by user classes
Description
DateTimeInterface is an interface. It should be available for usage with the implements keyword, but the PHP engines forbids it. Instead, it is recommended to extends the DateTime or DateTimeImmutable classes.
On the other hand, DateTimeInterface is available to type arguments, properties, etc. or to use with instanceof and catch.
Example
<?php
class X implements DateTimeInterface {}
?>
Alternatives
- Extends DateTime class.
- Extends DateTimeImmutable class.
DateTimeZone object is unconstructed
Description
IntlTimeZone::fromDateTimeZone() converts a DateTimeZone object into an IntlTimeZone one. To do so, it reads the internal timezone data that DateTimeZone::__construct() normally sets up.
If it is given a DateTimeZone instance that was created without going through its constructor – for example via ReflectionClass::newInstanceWithoutConstructor(), or an object left in a broken state after a failed unserialize() – that internal data is missing, and the conversion cannot proceed.
Example
<?php
$tz = (new ReflectionClass(DateTimeZone::class))->newInstanceWithoutConstructor();
// The object exists, but __construct() was never called
IntlTimeZone::fromDateTimeZone($tz);
?>
Alternatives
- Always create the
DateTimeZonewithnew DateTimeZone($identifier)rather than bypassing its constructor. - If the object comes from unserialization, verify it succeeded and produced a valid object before using it.
- Wrap the call in a
try/catch(Error) if theDateTimeZoneinstance’s origin cannot be controlled.
Related error messages
- the-sqlite3-object-has-not-been-correctly-initialised-or-is-already-closed
- intllistformatter-object-is-already-constructed
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Declaration of %s must be compatible with %s
Description
Classes methods signature have to be compatible between a parent class and a child class. When the signatures are different, the caller has to figure out which object is being used, and how to call the method. Hence, PHP checks that methods are compatible.
Method signature compatibility applies to all methods, except for __construct, which may have completely different signatures one from another.
The error message requires compatible signatures, which means that some variations are possible, and others are not.
Authorized variations
- Add a new parameter, with a default value
- Make the returntype more general than the parent
- Make the parameter types stricter than the parent
- Add elements to a union type of a parameter
- Change the default value
- Change the names of the parameters (not recommended)
- Make the visibility stricter
Forbidden variations
- Add or remove a parameter
- Add or remove a default value
- Add or remove a parameter type
- Add or remove the return type
- Add or remove the reference option
- Add or remove the variadic option
- Add or remove the static option.
Example
<?php
class X {
function foo($a) {}
}
class Y extends X {
function foo() {}
}
?>
Literal Examples
- Declaration of x::foo() must be compatible with y::foo()
Alternatives
- Check the variations and fix them.
- Change the name of the method to a free one.
Declaration of %s::%s() must be compatible with %s::%s()
Description
Classes methods signature have to be compatible between a parent class and a child class. When the signatures are different, the caller has to figure out which object is being used, and how to call the method. Hence, PHP checks that methods are compatible.
Method signature compatibility applies to all methods, except for __construct, which may have completely different signatures one from another.
The error message requires compatible signatures, which means that some variations are possible, and others are not.
Authorized variations
- Add a new parameter, with a default value
- Make the returntype more general than the parent
- Make the parameter types stricter than the parent
- Add elements to a union type of a parameter
- Change the default value
- Change the names of the parameters (not recommended)
- Make the visibility stricter
Forbidden variations
- Add or remove a parameter
- Add or remove a default value
- Add or remove a parameter type
- Add or remove the return type
- Add or remove the reference option
- Add or remove the variadic option
- Add or remove the static option.
Example
<?php
class X {
function foo($a) {}
}
class Y extends X {
function foo() {}
}
?>
Literal Examples
- Declaration of y::foo() must be compatible with x::foo()
Alternatives
- Check the variations and fix them.
- Change the name of the method to a free one.
Related error messages
Declaration of case-insensitive constants is no longer supported
Description
The define() function used to create case sensitive and case insensitive constants. This was the usage of the third parameter.
Since PHP 8.0, only case sensitive constants may be declared, with const and with define().
Example
<?php
// the third parameter is now ignored
define('CONSTANT_NAME', 'constant value', true);
?>
Alternatives
- Declare variations of the constant name.
declare(%s) value must be a literal
Description
declare() directives (ticks, encoding, strict_types) are processed by the compiler while the file is being parsed, before any code actually runs. At that point, constants, variables, and function calls are not yet available, so only a literal value, such as 1, 0, or a quoted string, can be given as the directive’s value.
This applies equally to every directive: ticks, encoding, and strict_types all require a literal.
Example
<?php
define('TICK_VALUE', 1);
declare(ticks = TICK_VALUE) {
echo 'Done';
}
?>
Literal Examples
- declare(ticks) value must be a literal
- declare(strict_types) value must be a literal
- declare(encoding) value must be a literal
Alternatives
- Replace the constant, variable, or expression with its literal value.
Related error messages
- strict_types-declaration-must-have-0-or-1-as-its-value
- strict_types-declaration-must-be-the-very-first-statement-in-the-script
- encoding-declaration-pragma-must-be
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Declaring %s constant called namespace is deprecated
Description
namespace is a reserved word in PHP, but a historical lexer exception let it be used as the name of a class, interface, trait or enum constant, as well as a static property. PHP 8.6 deprecates that exception for constants, so that namespace can be reserved for a possible future ::namespace pseudo-constant, analogous to the existing ::class.
The deprecation notice is emitted when the constant is declared, not when it is used.
Example
<?php
class Foo {
const NAMESPACE = 'bar';
}
echo Foo::NAMESPACE;
?>
Literal Examples
- Declaring class constant “namespace” is deprecated
- Declaring interface constant “namespace” is deprecated
- Declaring enum constant “namespace” is deprecated
Alternatives
- Rename the constant to something other than NAMESPACE.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, namespace could be freely used as the name of a class/interface/trait/enum constant. As of PHP 8.6, declaring it emits a deprecation notice, reserving the word for a possible future ::namespace pseudo-constant.](Previously, namespace could be freely used as the name of a class/interface/trait/enum constant. As of PHP 8.6, declaring it emits a deprecation notice, reserving the word for a possible future ::namespace pseudo-constant.)
Decrement on empty string is deprecated as non-numeric
Description
The -- operator has special, Perl-inspired handling for strings: decrementing a numeric string decrements the number, and historically decrementing a non-numeric string (including the empty string) was silently treated as if it were 0, so ''-- produced -1. This ‘consider as 0’ behaviour is surprising, since it makes -- on a string do something completely different from what ++ does on the very same string.
As of PHP 8.3, decrementing an empty string emits this deprecation notice; the value is still coerced to 0 before the decrement for backward compatibility, but this implicit behaviour is intended to go away in PHP 9.0, as part of a broader effort to make ++/-- on strings saner and introduce str_increment() / str_decrement().
Example
<?php
$str = '';
$str--;
var_dump($str);
?>
Alternatives
- Check for an empty string explicitly before decrementing, and handle it as its own case rather than relying on the implicit 0.
- Cast to int first if a numeric decrement was actually intended: $n = (int) $str; $n–;
- Use str_decrement() when the goal is Perl-style string decrementing rather than numeric decrementing.
Related error messages
- decrement-on-non-numeric-string-has-no-effect-and-is-deprecated
- increment-on-non-alphanumeric-string-is-deprecated
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Decrement on non-numeric string has no effect and is deprecated
Description
Unlike ++, which performs a Perl-style alphanumeric string increment (turning 'z' into 'aa', for example), the -- operator was never given an equivalent behaviour for non-numeric strings: applying it to something like 'abc' simply leaves the string untouched. That asymmetry – ++ transforms the string but -- silently no-ops – is confusing and easy to miss, since no warning was previously raised.
As of PHP 8.3, decrementing a non-numeric, non-empty string emits this deprecation notice so the no-op is no longer silent. The string itself is still left unchanged, but relying on that will trigger a warning today and is expected to change behaviour in PHP 9.0.
Example
<?php
$str = 'abc';
$str--;
var_dump($str);
// still string(3) "abc" -- the decrement had no effect at all
?>
Alternatives
- Do not use – on strings that are not guaranteed to be numeric; check is_numeric() first if the intent really is arithmetic.
- If the goal was a Perl-style string decrement, use str_decrement() instead, which raises a ValueError for invalid input rather than doing nothing.
- Cast to int explicitly if an arithmetic decrement starting from 0 was intended: $n = (int) $str; $n–;
Related error messages
- decrement-on-empty-string-is-deprecated-as-non-numeric
- increment-on-non-alphanumeric-string-is-deprecated
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Decrement on type bool has no effect, this will change in the next major version of PHP
Description
Post decrement on a boolean leaves the value unchanged. While PHP updates strings, integers, floats with the post-decrement operator, booleans are immune.
Until PHP 8.3, it was silently done. In PHP 8.3, it raises a deprecation warning, and it will be removed in PHP 9.0.
Post increment, pre increment, as well as increment and decrement are affected by that warning. str_increment() and str_decrement() refuses to use boolean, due to type.
Example
<?php
$a = true;
$a++;
// $a = true
$b = false;
--$b;
// $b = false
?>
Alternatives
- Avoid initializing variables with booleans before decrementing them.
- In case of doubt, check the type before the decrement.
Related error messages
- increment-on-type-bool-has-no-effect,-this-will-change-in-the-next-major-version-of-php
- decrement-on-type-null-has-no-effect,-this-will-change-in-the-next-major-version-of-php
Related error messages
Decrement on type null has no effect, this will change in the next major version of PHP
Description
Pre or post increment on a null leaves the value unchanged. While PHP updates strings, integers, floats with the post- or pre-increment operators, null are immune.
Until PHP 8.3, it was silently done. In PHP 8.3, it raises a deprecation warning, and it will be removed in PHP 9.0.
Post increment, pre increment, as well as increment and decrement are affected by that warning. str_increment() and str_decrement() refuses to use null, due to type.
Example
<?php
$a = null;
$a--;
--$a;
// $a === null
?>
Alternatives
- Avoid initializing variables with null before decrementing them.
- In case of doubt, check the type before the increment.
Related error messages
- increment-on-type-bool-has-no-effect,-this-will-change-in-the-next-major-version-of-php
- decrement-on-type-bool-has-no-effect,-this-will-change-in-the-next-major-version-of-php
Related error messages
Default value for parameters with a %s type can only be %s or NULL
Description
The default value of the parameter is not compatible with the type of the same parameter. In the example here, the parameter $s is supposed to be an integer, but has a string as default value.
This error also applies to numeric strings: the default value must be of the same type, without any silent type juggling.
Example
<?php
function foo(int $s = 's') { }
function bar(int $s = '1') { }
?>
Alternatives
- Change the type of the parameter.
- Change the default value.
- Change the default value to NULL.
- Remove the default value.
- Remove the type value.
- Add a second union type to the parameter.
Related error messages
- cannot-use-%s-as-default-value-for-parameter-$%s-of-type-%s
- cannot-use-%s-as-default-value-for-property-%s::$%s-of-type-%s
In more recent PHP versions, this error message is now :ref:cannot-use-%s-as-default-value-for-parameter-$%s-of-type-%s.
Default value for property of type %s may not be null. Use the nullable type %s to allow null default value
Description
Typed properties can have a default value, but that default value must match the declared type. null is only a valid default when the type is explicitly nullable, written with a leading ?, such as ?int.
Without the ?, a scalar or class type like int or X does not accept null, even as a default value that is never read before being overwritten.
Example
<?php
class X
{
public int $value = null;
}
?>
Literal Examples
- Default value for property of type int may not be null. Use the nullable type ?int to allow null default value
Alternatives
- Make the property type nullable, for example
?intinstead ofint. - Remove the default value, and initialize the property in the constructor instead.
- Use a non-null default value that matches the declared type.
Related error messages
- readonly-property-%s::$%s-cannot-have-default-value
- typed-property-%s::$%s-must-not-be-accessed-before-initialization
- property-%s::$%s-cannot-have-type-%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Default value for property of type int may not be null. Use the nullable type ?int to allow null default value
Description
When an argument is typed, and has a null default value, PHP makes it automagically nullable. That is not the case for properties, which yields this error.
Example
<?php
class X {
private int $i = null;
}
function foo(int $i = null) { }
?>
Alternatives
- Add the nullable type to the type definition.
- Use another default value, within the current type domain.
Related error messages
define(): Argument #3 ($case_insensitive) is ignored and treated as false since declaration of case-insensitive constants is no longer supported, passing the argument explicitly is unnecessary
Description
Case-insensitive constants were deprecated in PHP 7.3 and their support was removed in PHP 8.0: the third argument of define() has been ignored and always treated as false ever since. This deprecation goes one step further and flags every explicit call that still passes a (falsy) value for $case_insensitive, since doing so no longer has any effect and only adds noise to the call.
Example
<?php
define('FOO', 'bar', false);
?>
Literal Examples
- define(): Argument #3 ($case_insensitive) is ignored and treated as false since declaration of case-insensitive constants is no longer supported, passing the argument explicitly is unnecessary
Alternatives
- Call
define()with only two arguments: the constant name and its value.
Related error messages
In more recent PHP versions, this error message is now :ref:define():-argument-#3-($case_insensitive)-is-ignored-since-declaration-of-case-insensitive-constants-is-no-longer-supported,-this-will-be-an-error-in-php-9.0.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See caseInsensitiveConstant
define(): Argument #3 ($case_insensitive) is ignored since declaration of case-insensitive constants is no longer supported, this will be an error in PHP 9.0
Description
Case-insensitive constants were deprecated in PHP 7.3 and their support was removed in PHP 8.0: passing true as the third argument of define() no longer makes the constant case-insensitive, and is simply ignored. This deprecation warns that the leniency is temporary: in PHP 9.0, passing a truthy value for $case_insensitive will stop being silently ignored and will instead raise a fatal error.
Example
<?php
define('FOO', 'bar', true);
?>
Literal Examples
- define(): Argument #3 ($case_insensitive) is ignored since declaration of case-insensitive constants is no longer supported, this will be an error in PHP 9.0
Alternatives
- Call
define()with only two arguments: the constant name and its value. - Use the
constkeyword instead ofdefine()if the constant does not need to be defined conditionally.
Related error messages
In previous PHP versions, this error message used to be :ref:define():-argument-#3-($case_insensitive)-is-ignored-and-treated-as-false-since-declaration-of-case-insensitive-constants-is-no-longer-supported,-passing-the-argument-explicitly-is-unnecessary.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See caseInsensitiveConstant
define(): Argument #3 ($case_insensitive) is ignored since declaration of case-insensitive constants is no longer supported
Description
The third argument of define() used to allow the creation of a case-insensitive global constant. The constant in the code would have been accessible with A or a, without distinction. This feature has been deprecated in PHP 7.3 and abandoned in PHP 8.0. For backward compatibility, the third argument is not reported as an error, but a warning. The constant is not case insensitive any way. Adding a fourth argument is a fatal error, and has no meaning.
Example
<?php
define('A', 'b', true);
?>
Alternatives
- Remove the third argument in the define() call.
In previous PHP versions, this error message used to be :ref:define():-declaration-of-case-insensitive-constants-is-deprecated.
define(): Declaration of case-insensitive constants is deprecated
Description
The third argument of define() used to allow the creation of a case-insensitive global constant. The constant in the code would have been accessible with A or a, without distinction. This feature has been deprecated in PHP 7.3 and abandoned in PHP 8.0. For backward compatibility, the third argument is not reported as an error, but a warning. The constant is not case insensitive any way. Adding a fourth argument is a fatal error, and has no meaning.
Example
<?php
define('A', 'b', true);
?>
Alternatives
- Remove the third argument in the define() call.
In more recent PHP versions, this error message is now :ref:define():-argument-#3-($case_insensitive)-is-ignored-since-declaration-of-case-insensitive-constants-is-no-longer-supported.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See caseInsensitiveDefine
Defining a custom assert() function is not allowed,
Description
assert() is a PHP native function, used to create assertions. To avoid confusion, or redefinition of this function, it is not allowed to create a custom version of this function, even in a namespace.
Example
<?php
namespace X;
function assert() {}
?>
Alternatives
- Give another name to that function.
- Make it a method.
- Make it a Closure.
Related error messages
Delimiter must not be alphanumeric, backslash, or NUL byte
Description
The first character of a regex is the delimiter, that delimits the regex. There is a first and a last delimiter.
In the case of this error, the first regex character is of invalid type. It cannot be alphanumeric (a-z, A-Z and digits), the backslash \ nor the nul byte chr(0).
Note that if the first characters are white spaces, such as space, tabulation, new line, they are ignored as potential delimiter.
Example
<?php
preg_match('a[bc]a', 'abc');
?>
Alternatives
- Use a non-alphanumeric character, like
/,#.
Related error messages
Related error messages
In previous PHP versions, this error message used to be :ref:delimiter-must-not-be-alphanumeric,-backslash,-or-nul.
Delimiter must not be alphanumeric, backslash, or NUL
Description
The first character of a regex is the delimiter, that delimits the regex. There is a first and a last delimiter.
In the case of this error, the first regex character is of invalid type. It cannot be alphanumeric (a-z, A-Z and digits), the backslash \ nor the nul byte chr(0).
Note that if the first characters are white spaces, such as space, tabulation, new line, they are ignored as potential delimiter.
Example
<?php
preg_match('a[bc]a', 'abc');
?>
Alternatives
- Use a non-alphanumeric character, like
/,#.
Related error messages
Related error messages
In previous PHP versions, this error message used to be :ref:delimiter-must-not-be-alphanumeric-or-backslash.
In more recent PHP versions, this error message is now :ref:delimiter-must-not-be-alphanumeric,-backslash,-or-nul-byte.
Delimiter must not be alphanumeric or backslash
Description
The first character of a regex is the delimiter, that delimits the regex. There is a first and a last delimiter.
In the case of this error, the first regex character is of invalid type. It cannot be alphanumeric (a-z, A-Z and digits), nore the backslash \.
Note that if the first characters are white spaces, such as space, tabulation, new line, they are ignored as potential delimiter.
Later, the NUL character (chr(0)) was added to the list of the forbidden characters.
Example
<?php
preg_match('a[bc]a', 'abc');
?>
Alternatives
- Use a non-alphanumeric character, like
/,#.
Related error messages
Related error messages
In more recent PHP versions, this error message is now :ref:delimiter-must-not-be-alphanumeric,-backslash,-or-nul.
Deriving $_SERVER[‘argv’] from the query string is deprecated. Configure register_argc_argv=0 to turn this message off
Description
When the register_argc_argv INI directive is enabled and PHP is running under a non-CLI SAPI (such as CGI/FastCGI), $_SERVER['argv'] and $_SERVER['argc'] used to be reconstructed from the raw query string, splitting it on + the same way a shell would split command-line arguments. This behaviour only makes sense for the CLI SAPI, where a real argument vector exists, and is now deprecated for every other SAPI.
To reproduce this message, run a script under the CGI SAPI with a non-empty query string, for instance: php-cgi -d register_argc_argv=1 with QUERY_STRING=foo=bar set in the environment, the way a web server would when forwarding a request.
Example
<?php
var_dump($_SERVER['argv']);
?>
Alternatives
- Set
register_argc_argv=0in php.ini to silence the message;$_SERVER['argv']will simply not be populated outside of the CLI SAPI. - Use
$_GETto read individual query string parameters instead of parsing$_SERVER['argv']. - Use
$_SERVER['QUERY_STRING']if the raw, unparsed query string is needed.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See register_argc_argv
Destructors cannot declare a return type
Description
There can be no return type for a destructor method. It is called while destroying an existing instance of an object, and the object won’t be available at the end.
Example
<?php
class X {
function __destruct() : int {}
}
?>
Alternatives
- Remove the return type of the method.
Related error messages
- constructor-%s::%s()-cannot-declare-a-return-type
- method-%s::%s()-cannot-declare-a-return-type
- method-%s::__construct()-cannot-declare-a-return-type
- making-a-destructor-a-generator-is-deprecated
- returning-a-value-from-a-destructor-is-deprecated
Direct instantiation of WeakReference is not allowed, use WeakReference::create instead
Description
A WeakReference holds a reference to an object without preventing that object from being destroyed. Such objects must be created with the static method WeakReference::create(), which takes the object to watch as its argument. The new WeakReference() syntax is not allowed, and it throws an Error.
WeakReference::create() also returns the same WeakReference instance each time it is called with the same object, so comparing two references with === tells whether they point to the same object.
Example
<?php
$object = new stdClass();
// WeakReference objects can only be created with WeakReference::create()
$reference = new WeakReference();
?>
Literal Examples
- Direct instantiation of WeakReference is not allowed, use WeakReference::create instead
Alternatives
- Replace
new WeakReference($object)withWeakReference::create($object). - Once created, call
get()on the reference to retrieve the object, ornullif it has been destroyed.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Directive ‘report_memleaks’ is deprecated
Description
report_memleaks controls whether the Zend Memory Manager reports memory leaks detected during an unclean shutdown (for example when a fatal error occurs). This diagnostic is only meaningful on debug builds of PHP, since a production, non-debug build does not track individual allocations well enough to produce a useful report.
Because the directive is only relevant to internal debugging builds and not to application code, it is deprecated as of PHP 8.5.0.
Example
<?php
ini_set('report_memleaks', '0');
?>
Alternatives
- Remove references to
report_memleaksfromphp.iniand from the code; the directive has no practical effect on non-debug builds. - Use a dedicated memory profiler (e.g. Valgrind, a debug build of PHP) when investigating memory leaks.
Disabling session.use_only_cookies INI setting is deprecated
Description
session.use_only_cookies is marked for deprecation. When that directive will be removed, the feature will be set to always on.
Example
<?php
if (!ini_get('session.use_only_cookies')) {
die('it is recommended to only use cookies for sessions.');
}
?>
Alternatives
- Set
session.use_only_cookiesto on in php.ini. - Remove usage of ini_get() with
session.use_only_cookiesin the code. - Remove usage of ini_set() with
session.use_only_cookiesin the code.
Related error messages
Division of PHP_INT_MIN by -1 is not an integer
Description
In the specific case of the integer division of PHP_MIN_INT by -1, a specific error is reported: the result is not an integer.
In fact, - PHP_INT_MIN = PHP_INT_MAX + 1: PHP_INT_MIN is larger than PHP_INT_MAX, in absolute value. It implies that multiplying, or dividing it by -1, cannot be represented as a integer.
Since the intdiv() has a return type of int, returning a float is not possible. Hence, the specific error.
Any other argument is valid, as it will be within the range of the integers.
Last, using the / operator works, since the operator doesn’t have a return type.
Example
<?php
intdiv(PHP_MIN_INT, -1);
?>
Alternatives
- Check both operands before feeding them to the intdiv() function.
- Use
/, and then check if it is an integer or not. - Convert the values to float, and then, convert the result of the division to integer.
Duplicate declaration of static variable $%s
Description
It is not allowed anymore to declare twice a static variable in a method. This is spotted at compile time.
Example
<?php
function foo() {
static $a;
++$a;
static $a;
}
?>
Literal Examples
- Duplicate declaration of static variable $a
Alternatives
- Remove all the static declarations, but one: keep the earliest one.
Duplicate named parameter $%s
Description
Parameter shall only be passed once. For named parameters, this means that the same name shall only be used once when calling the method.
This problem is never raised with positional arguments, which are automatically indexed.
There is a distinct error message when this happens to in method calls.
Example
<?php
function foo($b, $b) {}
#[MyAttribute(a: 'A', a: 'A')]
class Test {}
?>
Literal Examples
- Duplicate named parameter $a
- Duplicate named parameter $b
Alternatives
- Remove the names of the parameters.
- Change the name of all the duplicate named parameters, but one.
- Remove the duplicates named parameters, but one.
Related error messages
Duplicate parameter name $%s for function %s%s%s()
Description
It is not allowed to have several times the same parameter in a method, closure or function signature. All the parameters must have different names.
This error appears only in PHP debug mode.
Example
<?php
function foo($a, $a, $a) {}
?>
Literal Examples
- Duplicate parameter name $a for function foo()
Alternatives
- Remove the parameters with duplicate names.
- Rename the parameters with duplicate names.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Duplicate type %s is redundant
Description
When declaring a complex type, each part of the type must be unique. This means that a type can only be mentioned once.
This constraint is actually easier to explain than to detail: of course, it is important to avoid repeating the same type, yet types may be declared with different case, with or without initial slash, with a local alias, or also with a class_alias().
Then, there is also the possiblity for the type to be part of a composed type, such as bool (which is true|false), or mixed, or iterable, etc.
Only the first redundant type is reported.
Example
<?php
function foo() : A|a|\a|\A {}
function goo() : bool|false {}
?>
Literal Examples
- Duplicate type a is redundant
- Duplicate type false is redundant
Alternatives
- Remove types that are double.
- Remove the types.
Related error messages
- type-contains-both-true-and-false,-bool-must-be-used-instead
- type-%s-contains-both-iterable-and-array
- type-%s-contains-both-object-and-a-class-type
- type-%s-is-redundant-as-it-is-more-restrictive-than-type-%s
- null-cannot-be-marked-as-nullable
- type-%s-cannot-be-part-of-an-intersection-type
- type-%s-is-redundant-with-type-%s
In previous PHP versions, this error message used to be :ref:type-%s-contains-both-iterable-and-array.
Duplicate value in enum %s for cases %s and %s
Description
When an enumeration is backed, either string or int, the values used in the cases must all be distinct. There cannot be any duplicate value. This problem is only reported at execution time, when one of the cases is used.
Example
<?php
enum E: int {
case A = 1;
case B = 1;
}
E::A;
?>
Literal Examples
- Duplicate value in enum E for cases A and B
Alternatives
- Make sure all the cases are distinct.
Related error messages
Dynamic class names are not allowed in compile-time class constant references
Description
It is not possible to create a constant while using a variable, or similar containers. The expression must be static.
Example
<?php
$foo = 'a';
const A = $foo::C;
?>
Alternatives
- Use define().
- Make the value expression static.
elements must be between %d and %d
Description
imagesetstyle() takes an array of color indexes (and, optionally, the special value IMG_COLOR_TRANSPARENT) describing a repeating line style, later used by imageline() when drawing with IMG_COLOR_STYLED. Each element is converted to a C int internally.
Starting in PHP 8.5, GD’s array-accepting functions validate that every element actually fits in a native int instead of silently truncating it. Passing a value outside the int range, such as PHP_INT_MIN on a 64-bit build, now raises a ValueError naming the offending argument, instead of wrapping or misbehaving.
Example
<?php
$im = imagecreatetruecolor(10, 10);
imagesetstyle($im, [gdTransparent, PHP_INT_MIN]);
?>
Literal Examples
- imagesetstyle(): Argument #2 ($style) elements must be between -2147483648 and 2147483647
Alternatives
- Only use color indexes and style values that fit within a 32-bit signed integer range (between
-2147483648and2147483647).
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Empty delimiter
Description
The explode() function doesn’t work without a non-empty delimiter. Use an alternative, such as str_split().
Example
<?php
print_r(explode('', 'abc')); // Not possible with an empty delimiter
print_r(str_split(1, 'abc'));
?>
Alternatives
- Use str_split() to split the string into individual characters.
- Access to the different elements.
Related error messages
In more recent PHP versions, this error message is now :ref:cannot-be-empty.
Enabling session.use_trans_sid INI setting is deprecated
Description
session.use_trans_sid is marked for deprecation. When that directive will be removed, the feature will also be removed. Trans ID are session ID that are propagated via GET (in the URL) and POST (in the HTTP headers).
Example
<?php
if (!ini_get('session.use_trans_sid')) {
die('it is recommended to not use trans id for sessions.');
}
?>
Alternatives
- Set
session.use_trans_sidto off in php.ini. - Remove usage of ini_get() with
session.use_trans_sidin the code. - Remove usage of ini_set() with
session.use_trans_sidin the code.
Related error messages
- disabling-session.use_only_cookies-ini-setting-is-deprecated
- usage-of-session.trans_sid_hosts-ini-setting-is-deprecated
- usage-of-session.trans_sid_tags-ini-setting-is-deprecated
Encoding declaration pragma must be
Description
The declare(encoding = ...) pragma sets the source encoding PHP uses to parse the rest of the script, so, like strict_types, it has to be known before anything else in the file is compiled. It must therefore be the very first statement in the script, exactly like the strict_types declaration.
The full message reads: Encoding declaration pragma must be the very first statement in the script. In practice, this directive only has an effect when the zend.multibyte ini setting is enabled; otherwise it is silently ignored, but the placement rule is still enforced.
Example
<?php
echo 'Hello';
declare(encoding = 'ISO-8859-1');
?>
Literal Examples
- Encoding declaration pragma must be the very first statement in the script
Alternatives
- Move the
declare(encoding = ...)statement to be the very first statement in the file. - Remove any characters or statements placed before the opening
<?phptag.
Related error messages
- strict_types-declaration-must-be-the-very-first-statement-in-the-script
- namespace-declaration-statement-has-to-be
- declare(%s)-value-must-be-a-literal
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Entry %s does not exist and cannot be deleted
Description
PHP reports failure when trying to remove a file that does not exists in a phar archive. This error message is specific to the Phar::delete method.
Example
<?php
try {
$phar = new Phar('/tmp/myphar.phar');
$phar->addFromString('foo.txt', 'hello');
unset($phar);
$phar = new Phar('/tmp/myphar.phar');
$phar->delete('/oops');
} catch (Exception $e) {
// handle errors
print $e->getMessage();
}
?>
Literal Examples
- Entry oops does not exist and cannot be deleted
Alternatives
- Check if the file exists before removing it.
Related error messages
Enum “%s” not found
Description
This error could not be reproduced so far. Help us by sending us any generating code.
Example
Alternatives
Enum %s cannot implement the Serializable interface
Description
Enumeration cannot be serialized: they are created as needed by the PHP engine, during execution, and they will again at the next execution.
Example
<?php
enum E implements Serializable {
case A;
}
?>
Literal Examples
- Enum E cannot implement the Serializable interface
Alternatives
- Remove the
serializableimplements. - Make this enumeration a class.
Related error messages
Enum %s cannot include magic method %s
Description
Some magic methods are not allowed in an enumeration. __get, __set, __isset, __unset, __construct, __destruct, __sleep, __wakeup, __serialize, __unserialize, __toString, __set_state, __clone and __debugInfo.
This also means that some other magic methods are allowed : __call, __callStatic and __invoke.
Example
<?php
enum E {
function __get($a) {}
}
?>
Literal Examples
- Enum e cannot include magic method __get
- Enum e cannot include magic method __set
- Enum e cannot include magic method __destruct
Alternatives
- Remove the magic method from the enumeration.
- Turn the enumeration into a class.
Related error messages
Enum %s cannot include properties
Description
Enumeration cannot define a property. They can only define constants and methods.
Enum can use a trait, and import several methods. Traits can also define properties, which are mixed with the host. On the other hand, enum cannot define properties: when a trait is used by an enumeration, it should not have any properties. It is also the case for traits of traits.
Example
<?php
enum D {
private $p = 1;
}
trait T {
private int $property;
}
enum E {
use T;
}
?>
Alternatives
- Remove the property from the trait.
- Split the trait in two traits, and include the new trait that has no property.
Enum backing type must be int or string
Description
Backed enumeration have a name and a value for each case. The type of that value is specified next to the enumeration name, and can only by string or int. All other values are forbidden.
Example
<?php
enum E: A {
case B;
}
?>
Literal Examples
- Enum backing type must be int or string, A given
Alternatives
- Remove the type on the enumeration and its cases.
- Use one of the valid types with the enumeration.
Related error messages
Enum case type %s does not match enum backing type %s
Description
Enumeration may be backed with a scalar type, int or string. When doing so, each case must have a value of that type. And no type juggling happens, so '1' is not an integer, while 1 is not a string. The types must match perfectly one with another.
Example
<?php
enum E : string {
case A = 1;
}
?>
Alternatives
- Change the type on the enumeration to fit the value.
- Change the type on the value to fit the enumeration.
- Remove types and values.
Related error messages
Enum case value must be compile-time evaluatable
Description
The value of a backed enumeration, string or integer, cannot be build with constant (global or classe). It can only be build with literal values.
This limitation was removed in PHP 8.2.
Example
<?php
enum Foo: string {
case A = '/' . A;
case B = '/' . __FILE__;
}
?>
Alternatives
- Upgrade to PHP 8.2.
- Replace the constants with literal values.
Enums are not compatible with %s
Description
It is not possible to use an object as backing for the arrayobject class. Enums cases are objects, of the type of the enum. Hence, this is not possible.
Example
<?php
enum Foo {
case Bar;
}
new ArrayObject(Foo::Bar);
?>
Alternatives
- Put the value of the case in an array.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Error at offset %zd of %zd
Description
Unserialize() reads a string, and parse it to produce a value: integer, string, array, object… It uses a specific format, and when there isn’t enough information to successfully run the parse, this error message is emitted.
Example
<?php
unserialize("an invalid string");
?>
Alternatives
- Catch the returned value of the function: when it is null, an error occurred.
Related error messages
exponent cannot have a fractional part
Description
The exponent argument, aka the second, must be an integer value. It might be negative, or even zero, but it cannot be with a decimal separator.
PHP tries to round it, so float values with only zeros after the decimal separator may work.
Example
<?php
echo bcpow('4.2', '3.2', 2); // 74.08
?>
Alternatives
- Check the argument with
is_int(). - Round the argument to an integer.
Extra data starting at offset %d of %zd bytes
Description
Some extra data were found while processing the serialized string. They are not needed, so they should not be there. It is recommended to investigate why too much data was provided, as it may devolve in a security issue.
There is no way to check the amount of needed data before unserializing the string.
Example
<?php
// 1 3 are too much in this string.
print_r(unserialize('O:1:"a":1:{s:8:"property";s:3:"yes". '1 3';}));
?>
Literal Examples
- Extra data starting at offset 31 of 3 bytes
Alternatives
- Catch the warning and review the string after execution.
- Set up a validation of the incoming string, such as a check sum.
Failed opening required %s (include_path=%s)
Description
This error appears when PHP cannot reach the file for inclusion with require or require_once.
The file may not exist, or the path has a typo and does not point to the actual file. Note that PHP searches for the file once, when the path starts with a leading /. Otherwise, PHP uses the provided path with all the paths provided in the include_path, and stops at the first found file.
The file may be configured no read permissions, making it unavailable for the web server or anyone running the current code.
Parenthesis have no impact on this error.
This error applies only to require and require_once. It does not apply to include and include_once, which reports the same message but proceeds with execution and does not stop with a fatal error. Note that the underlying problem is the same, but the reaction of the inclusions are not the same.
Example
<?php
require '/not/a/path/to/a/file.inc';
?>
Literal Examples
- Failed opening required include.php (include_path=‘.:’)
Alternatives
- Check for typos in the file name.
- Check for typos in the path name.
- Check for permissions to reach the file.
- Check for include_path to provide the correct path prefix.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Failed to create closure from callable: %s
Description
This error message signals that the Closure class could not check the availability of the method to create a closure.
In the illustration code, the class A does not exists. The new Closure is checked at calling time of Closure::fromCallable.
The description of the problem is at the end of the error message, and may vary depending on the situation.
Example
<?php
Closure::fromCallable(['a', 'b']);
?>
Literal Examples
- Failed to create closure from callable: class a does not exist
Alternatives
- Pass the array around, and call
Closure::fromCallableat the last moment. - Create a hard coded closure.
Related error messages
Failed to evaluate a trait precedence (%s). Method of trait %s was defined to be excluded multiple times
Description
The insteadof operator resolves a conflict between two or more traits that define a method with the same name: it picks the version to keep, and implicitly excludes that method from the traits listed after insteadof.
Each trait can only be marked as excluded, for a given method, once. Here, B is listed twice in the same insteadof clause for hello(), which is redundant: PHP has nothing more to learn from the second mention, and rejects the declaration outright, rather than silently ignoring the duplicate.
The same error also occurs when the same trait ends up excluded twice for the same method through two separate precedence rules, not just within a single insteadof list.
Example
<?php
trait A {
public function hello() { echo 'A'; }
}
trait B {
public function hello() { echo 'B'; }
}
class X {
use A, B {
A::hello insteadof B, B;
}
}
?>
Literal Examples
- Failed to evaluate a trait precedence (hello). Method of trait B was defined to be excluded multiple times
Alternatives
- Remove the duplicate trait name from the insteadof list.
- Check whether the trait is already excluded for that method by another precedence rule.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Failed to open stream from socketpair
Description
This error could not be reproduced so far. Help us by sending us any generating code.
Example
Alternatives
Failed to open stream: Too many open files
Description
This error has two aspects: first, PHP tried to read a file and failed. This is the first part, where files are mentioned as streams. Streams are a more generic version of files: they may be local files, on the file system, or they may be remote, via any kind of protocol, or even, created on the fly by other processes.
The second aspect is a detailed version of the previous: the file failed to be read because the current process has reached the maximum number of possible files to read. This is a system limit, which prevents processes to open an unlimited number of files. Usually, reaching such limit means that the code is opening files carelessly.
To check this limit, run the system command ulimit -n on Linux systems.
Example
<?php
parse_ini_file('/path/to/file.ini');
?>
Alternatives
- Review the code to limit the number of opened files and sockets.
- Raise the limit of opened files for the process, by using
ulimit -n 10000(or more, if necessary).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Failed to set memory_limit to %zd bytes. Setting to max_memory_limit instead (currently: %zd bytes)
Description
PHP 8.5 introduced the max_memory_limit INI directive, an administrator-controlled ceiling on how high memory_limit may be raised, whether from php.ini, the command line, or a runtime call to ini_set(). Any attempt, from any of these sources, to set memory_limit above max_memory_limit triggers this warning, and the effective limit is clamped down to max_memory_limit instead.
max_memory_limit defaults to -1 (no ceiling), so it must be configured first, and it is a PHP_INI_SYSTEM directive: it can only be set in php.ini or on the command line, never with ini_set().
To reproduce this message on the command line: php -d max_memory_limit=64M script.php, where script.php is the code above.
Example
<?php
ini_set('memory_limit', '128M');
echo ini_get('memory_limit'), "\n";
?>
Alternatives
- Lower the requested
memory_limitto a value at or belowmax_memory_limit. - Raise
max_memory_limitin php.ini if the script genuinely needs more memory. - Do not treat the return value of
ini_set('memory_limit', ...)as authoritative; re-read it withini_get('memory_limit')afterwards.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See max_memory_limit
Failed to update the scheme
Description
This is an internal, defensive error. Uri\Rfc3986\Uri::withScheme() asks the bundled uriparser library to replace the scheme component; the library can only report success or a syntax error (surfaced as the-specified-scheme-is-malformed). This exception is thrown for any other, unexpected result code, which should not be reachable from PHP userland — it exists purely as a safety net, not as a condition an application is expected to trigger.
Example
Alternatives
- This should not occur during normal use; if it does, it indicates a bug in the URI extension or the bundled uriparser library rather than a mistake in your code.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Failed to update the userinfo
Description
This is an internal, defensive error. Uri\Rfc3986\Uri::withUserInfo() asks the bundled uriparser library to replace the userinfo component; the library can only report success, a missing-host condition (cannot-set-a-userinfo-without-having-a-host), or a syntax error (the-specified-userinfo-is-malformed). This exception is thrown for any other, unexpected result code, which should not be reachable from PHP userland — it exists purely as a safety net, not as a condition an application is expected to trigger.
Example
Alternatives
- This should not occur during normal use; if it does, it indicates a bug in the URI extension or the bundled uriparser library rather than a mistake in your code.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Fetching properties on non-enums in constant expressions is not allowed
Description
Constant expressions are expressions that build the value of a constant. A subset of the features of PHP are available in these expressions.
In particular, objects are allowed, but it is not possible to fetch properties nor call methods. In fact, properties are allowed, but on a specific type of object: enumeration cases.
Example
<?php
class Y {
public $y = 1;
}
const Y = new Y();
enum Z : string {
case Z = 'foo';
}
class X {
const XZ = Z::z->value;
const X = Y->y;
}
// OK
echo X::XZ;
//Fetching properties on non-enums in constant expressions is not allowed
echo X::X;
?>
Alternatives
- Do not use properties in constant expressions.
Related error messages
FFI API is restricted by “ffi.enable” configuration directive
Description
FFI is an extension that allows loading C libraries, and building C data structure from PHP. This is a powerful interface, that comes with possible security concerns. Not only FFI must be compiled with PHP, but it also has to be allowed in the php.ini file to be executable.
Since this error message is provided by FFI, it means FFI is installed on the system, but it is not enabled in the php.ini.
Example
<?php
// create FFI object, loading libc and exporting function printf()
$ffi = FFI::cdef(
"int printf(const char *format, ...);", // this is a regular C declaration
"libc.so.6");
?>
Alternatives
- Enable FFI in the php.ini.
Filename cannot be empty
Description
fopen()’s first argument is of type string, though the empty string is not allowed, as it does not lead to any file.
This check prevents using an empty string, or its equivalent as null or false, to access a file.
This error also applies to file_get_contents and file_put_contents(). It doesn’t apply to unlink and rmdir.
Example
<?php
fopen('', 'r');
?>
Alternatives
- Check the name of the file with empty() before using it with fopen().
- Check the name of the file against ‘’ (empty string) before using it with fopen().
In more recent PHP versions, this error message is now :ref:path-cannot-be-empty.
filter validation failed: filter %s not satisfied by ‘%s’
Description
PHP 8.5 adds the FILTER_THROW_ON_FAILURE flag, usable with filter_var(), filter_var_array(), filter_input() and filter_input_array(). When it is set and the chosen filter (e.g. FILTER_VALIDATE_EMAIL) rejects the value, a Filter\FilterFailedException is thrown instead of the function returning false, naming both the filter and the offending value.
Example
<?php
filter_var('not-an-email', FILTER_VALIDATE_EMAIL, FILTER_THROW_ON_FAILURE);
?>
Literal Examples
- filter validation failed: filter validate_email not satisfied by ‘not-an-email’
Alternatives
- Wrap the call in a try/catch and handle
Filter\FilterFailedException. - Do not pass FILTER_THROW_ON_FAILURE if you prefer to check the return value for
falseinstead.
Related error messages
- filter-validation-failed:-not-an-array-(got-%s)
- filter-validation-failed:-object-of-type-%s-has-no-__tostring()-method
- cannot-use-both-filter_null_on_failure-and-filter_throw_on_failure
In more recent PHP versions, this error message is now :ref:filter-validation-failed:-not-an-array-(got-%s).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
filter validation failed: not an array (got %s)
Description
The FILTER_REQUIRE_ARRAY flag asks the filter functions to treat the input as an array and filter each element. If the value is not actually an array, this normally makes the function return false. When FILTER_THROW_ON_FAILURE is combined with FILTER_REQUIRE_ARRAY, that same situation instead throws Filter\FilterFailedException naming the type that was received.
Example
<?php
filter_var('a', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY | FILTER_THROW_ON_FAILURE);
?>
Literal Examples
- filter validation failed: not an array (got string)
Alternatives
- Pass an array when using FILTER_REQUIRE_ARRAY, or drop that flag if a scalar is expected.
- Wrap the call in a try/catch and handle
Filter\FilterFailedException.
Related error messages
- filter-validation-failed:-filter-%s-not-satisfied-by-%s
- filter-validation-failed:-object-of-type-%s-has-no-__tostring()-method
In previous PHP versions, this error message used to be :ref:filter-validation-failed:-filter-%s-not-satisfied-by-%s.
In more recent PHP versions, this error message is now :ref:filter-validation-failed:-object-of-type-%s-has-no-__tostring()-method.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
filter validation failed: object of type %s has no __toString() method
Description
The filter functions convert their input to a string before applying a filter. If the input is an object without a __toString() method, that conversion is impossible; normally the function returns false (or null/the default option, depending on the flags used). With FILTER_THROW_ON_FAILURE set, this instead throws Filter\FilterFailedException naming the offending class.
Example
<?php
filter_var(new stdClass(), FILTER_VALIDATE_EMAIL, FILTER_THROW_ON_FAILURE);
?>
Literal Examples
- filter validation failed: object of type stdClass has no __toString() method
Alternatives
- Only pass objects that implement
__toString(), or convert the value to a string yourself first. - Wrap the call in a try/catch and handle
Filter\FilterFailedException.
Related error messages
- filter-validation-failed:-filter-%s-not-satisfied-by-%s
- filter-validation-failed:-not-an-array-(got-%s)
- %s::__tostring()-must-return-a-string
In previous PHP versions, this error message used to be :ref:filter-validation-failed:-not-an-array-(got-%s).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
foreach() argument must be of type array|object
Description
foreach() works on arrays or objects.
For the arrays, all the elements of the array are read.
For the objects, it is either the public properties, read like an array; or the object has the Iterator interface: then, there is a list of specific methods to implements, which control how the object is traversed; the object may be a generator, which is a method that uses the yield keyword; finally, the object may be a PHP native iterator, or a child of them.
Then, any other type is forbidden to be used with foreach(). This means all scalars elements, including string, integer and null.
Example
<?php
$source = null;
foreach($source as $x) { }
?>
Alternatives
- Check that the source of the foreach can be used with is_iterable().
Related error messages
In previous PHP versions, this error message used to be :ref:invalid-argument-supplied-for-foreach().
func_get_arg() cannot be called from the global scope
Description
func_get_arg() returns the list of arguments used when calling a function or method. As such, it must be inside a function to be useful.
Example
<?php
func_get_arg(0);
?>
Alternatives
- Remove func_get_arg() calls from the global space (outside any function).
- Move the func_get_arg() calls inside a function.
Related error messages
- func_get_args()-cannot-be-called-from-the-global-scope
- func_num_args()-must-be-called-from-a-function-context
func_get_args() cannot be called from the global scope
Description
func_get_args() returns the list of arguments used when calling a function or method. As such, it must be inside a function to be useful.
Example
<?php
func_get_args();
?>
Alternatives
- Remove func_get_args() calls from the global space (outside any function).
- Move the func_get_args() calls inside a function.
Related error messages
- func_get_arg()-cannot-be-called-from-the-global-scope
- func_num_args()-must-be-called-from-a-function-context
func_num_args() must be called from a function context
Description
func_num_arg() returns the number of arguments used when calling a function or method. As such, it must be inside a function to be useful.
Example
<?php
func_num_args();
?>
Alternatives
- Remove func_num_args() calls from the global space (outside any function).
- Move the func_num_args() calls inside a function.
Related error messages
- func_get_args()-cannot-be-called-from-the-global-scope
- func_get_arg()-cannot-be-called-from-the-global-scope
Function %pS() does not exist
Description
The ReflectionFunction constructor requires the name of an existing user-defined or internal function. When the given name does not match any declared function, the Reflection API cannot build the requested introspection object and throws a ReflectionException instead.
Example
<?php
$reflection = new ReflectionFunction('does_not_exist');
?>
Literal Examples
- Function does_not_exist() does not exist
Alternatives
- Check the function name for typos.
- Make sure any file declaring the function has been included before creating the
ReflectionFunction. - Use
function_exists()to check the function is available before reflecting on it.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Function %s() is deprecated%S
Description
PHP native functions get deprecated, before being removed. This message is here to help with refactoring the code to more modern syntax, and get ready for upcoming versions.
Example
<?php
// One of the deprecated functions
echo strftime(1);
?>
Literal Examples
- Function strftime() is deprecated since 8.1, use IntlDateFormatter::format() instead
Alternatives
- Use the suggestion from the error message.
Related error messages
Function libxml_disable_entity_loader() is deprecated since 8.0, as external entity loading is disabled by default
Description
This warning signals that PHP is not using this function anymore: the features of loading external entities has been disabled, for security purposes: loading entities from a remote server without checking them was a serious vulnerability.
The deprecation warning warns the user that this feature is already inactive.
Example
<?php
libxml_disable_entity_loader(true);
?>
Alternatives
- Remove the call to libxml_disable_entity_loader().
Function name must be a string
Description
When calling a function dynamically, the name of the function, in the $method variable, must be a string, and the function must exist.
Some other scalars, such as integer, might be used as function name, although it will fail.
Example
<?php
$method = new stdClass;
$method();
?>
Alternatives
- Only use string names for dynamic call to functions.
- Cast the variable to string before using it.
In more recent PHP versions, this error message is now :ref:object-of-type-%s-is-not-callable.
Generated salt too short
Description
password_hash() creates a random salt for each hash. This error is thrown when the salt that was generated is shorter than the length the hashing algorithm needs, so the hash cannot be built.
Application code cannot fix this directly, as the salt is created inside PHP. It points to a problem with the random data or with the PHP build, and it is rare.
Example
Literal Examples
- Generated salt too short
Alternatives
- Check that
random_bytes()works on the system, for example by callingrandom_bytes(16)in a small script. - Check the PHP build, and reinstall PHP if it is a custom or damaged build.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Generator return type must be a supertype of Generator
Description
When a method or a function uses a yield keyword, it becomes a generator. It also means that the return type of this method must be Generator, or any other of its supertypes: Traversable, Iterator, Generator or iterable.
There is no way to set a type on the yielded values: only on the returned values. In this case, it will be a Generator. Strangely, any value in a return expression is also valid.
It may also be simply removed, and left implicit.
Example
<?php
function foo() : X {
yield 1;
return true;
}
?>
Alternatives
- Use the return type
Generator.
Generators cannot return values using “return”
Description
In PHP 5.x, generators were not allowed to have return values. This feature was added in PHP 7.0, and, after running the full course, generator deliver their return value when calling the getReturn method.
Example
<?php
function foo() {
yield 1;
return 2;
}
?>
Alternatives
- Upgrade to PHP 7.0 or more recent.
- Use a global variable to export data from the method.
Get hook of backed property %s::%s with set hook may not return by reference
Description
When a property is a virtual property, the get hook cannot return a reference.
Example
<?php
class A {
public $prop;
}
class B extends A {
private $_prop;
public $prop {
&get => $this->_prop;
set { $this->_prop = $value; }
}
}
?>
Literal Examples
- Get hook of backed property B::$prop with set hook may not return by reference
Alternatives
- Make the virtual property a concrete one.
- Remove the reference.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
get hook of property %s::$%s must not have a parameter list
Description
The get hook property cannot be specified with a parameter list: not with a parameter, nor even with the empty parenthesis.
Example
<?php
class X {
private int $p {
get($a) => 1;
}
private int $q {
get() => 1;
}
}
?>
Literal Examples
- get hook of property X::$p must not have a parameter list
Alternatives
- Remove the parenthesis that follows the
getkeyword, and their content.
Related error messages
- %s-hook-of-property-%s::$%s-must-accept-exactly-one-parameters
- type-of-parameter-$%s-of-hook-%s::$%s::set-must-be-compatible-with-property-type
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
get_called_class() must be called from within a class
Description
get_called_class() returns the name of the current class. It emits an error when it cannot find the current class.
get_called_class() can only be called from within a class, trait or enumeration. It may be called from a static closure, as long as the closure is created inside a class.
Example
<?php
get_called_class();
?>
Alternatives
- Use the magic constant CLASS.
- Use the function inside a class, enumeration or trait.
get_defined_functions(): Setting $exclude_disabled to false has no effect
Description
The first (and only) parameter of the PHP native function get_defined_functions() is deprecated since PHP 8.0 and will disappear in PHP 9.
Example
<?php
$list = get_defined_functions(false);
?>
Alternatives
- Remove all parameter usage when calling get_defined_functions(), and fetch the list of disabled functions another way.
- Check that the parameter is never false before usage.
get_defined_functions(): The $exclude_disabled parameter has no effect since PHP 8.0
Description
The $exclude_disabled parameter of the function get_defined_functions() function is unused since PHP 8.0. In PHP 7.0, it used to remove the disabled function from the result of this function.
Example
<?php
print_r(get_defined_functions(false));
?>
Alternatives
- Remove the parameter from any call to get_defined_functions().
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See get_defined_functions
Handling Base64 via mbstring is deprecated; use base64_encode/base64_decode instead
Description
Since PHP 8.2, several encodings were dropped from mbstring, including base64.
This is a deprecation, so the feature is available until PHP 9.
Example
<?php
mb_convert_encoding('foo', 'base64');
?>
Alternatives
- It is recommended to use the
base64_encode()andbase64_decode()functions to do this.
Related error messages
- handling-uuencode-via-mbstring-is-deprecated;-use-convert_uuencode-convert_uudecode-instead
- handling-html-entities-via-mbstring-is-deprecated;-use-htmlspecialchars,-htmlentities,-or-mb_encode_numericentity-mb_decode_numericentity-instead
- handling-html-entities-via-mbstring-is-deprecated;-use-htmlspecialchars,-htmlentities,-or-mb_encode_numericentity-mb_decode_numericentity
- handling-qprint-via-mbstring-is-deprecated;-use-quoted_printable_encode-quoted_printable_decode-instead
- handling-qprint-via-mbstring-is-deprecated;-use-quoted_printable_encode-quoted_printable_decode
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See mb_convert_encoding
Handling HTML entities via mbstring is deprecated; use htmlspecialchars, htmlentities, or mb_encode_numericentity/mb_decode_numericentity instead
Description
Since PHP 8.2, several pseudo-encodings were dropped from mbstring, including HTML-ENTITIES, which converted characters to and from their HTML numeric/named entity representation.
This functionality overlapped with dedicated, better-maintained functions, and its removal simplifies the mbstring encoding conversion tables. It remains usable until PHP 9, when it will be removed entirely.
Example
<?php
mb_convert_encoding('foo', 'HTML-ENTITIES');
?>
Alternatives
- Use
htmlspecialchars()orhtmlentities()to encode text as HTML entities. - Use
mb_encode_numericentity()/mb_decode_numericentity()for numeric entity conversion.
Related error messages
- handling-qprint-via-mbstring-is-deprecated;-use-quoted_printable_encode-quoted_printable_decode-instead
- handling-base64-via-mbstring-is-deprecated;-use-base64_encode-base64_decode-instead
- handling-uuencode-via-mbstring-is-deprecated;-use-convert_uuencode-convert_uudecode-instead
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See mb_convert_encoding
Handling HTML entities via mbstring is deprecated; use htmlspecialchars, htmlentities, or mb_encode_numericentity/mb_decode_numericentity
Description
Since PHP 8.2, several encodings were dropped from mbstring, including html.
This is a deprecation, so the feature is available until PHP 9.
Example
<?php
mb_convert_encoding('foo', 'html');
?>
Alternatives
- It is recommended to use the
htmlspecialchars(),htmlentities(),mb_encode_numericentity(),mb_decode_numericentity()functions to do this.
Related error messages
- handling-base64-via-mbstring-is-deprecated;-use-base64_encode-base64_decode-instead
- handling-qprint-via-mbstring-is-deprecated;-use-quoted_printable_encode-quoted_printable_decode
- handling-uuencode-via-mbstring-is-deprecated;-use-convert_uuencode-convert_uudecode-instead
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See mb_convert_encoding
Handling QPrint via mbstring is deprecated; use quoted_printable_encode/quoted_printable_decode instead
Description
Since PHP 8.2, several pseudo-encodings were dropped from mbstring, including qprint (Quoted-Printable), a text encoding that represents non-ASCII bytes using =XX sequences.
This functionality overlapped with the dedicated quoted_printable_encode()/quoted_printable_decode() functions provided by the standard extension. It remains usable until PHP 9, when it will be removed entirely.
Example
<?php
mb_convert_encoding('foo', 'qprint');
?>
Alternatives
- Use
quoted_printable_encode()andquoted_printable_decode()instead ofmb_convert_encoding()with theqprintencoding.
Related error messages
- handling-html-entities-via-mbstring-is-deprecated;-use-htmlspecialchars,-htmlentities,-or-mb_encode_numericentity-mb_decode_numericentity-instead
- handling-base64-via-mbstring-is-deprecated;-use-base64_encode-base64_decode-instead
- handling-uuencode-via-mbstring-is-deprecated;-use-convert_uuencode-convert_uudecode-instead
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See mb_convert_encoding
Handling QPrint via mbstring is deprecated; use quoted_printable_encode/quoted_printable_decode
Description
Since PHP 8.2, several encodings were dropped from mbstring, including QPrint.
This is a deprecation, so the feature is available until PHP 9.
Example
<?php
mb_convert_encoding('foo', 'qprint');
?>
Alternatives
- It is recommended to use the
quoted_printable_encode()andquoted_printable_decode()functions to do this.
Related error messages
- handling-base64-via-mbstring-is-deprecated;-use-base64_encode-base64_decode-instead
- handling-html-entities-via-mbstring-is-deprecated;-use-htmlspecialchars,-htmlentities,-or-mb_encode_numericentity-mb_decode_numericentity
- handling-uuencode-via-mbstring-is-deprecated;-use-convert_uuencode-convert_uudecode-instead
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See mb_convert_encoding
Handling Uuencode via mbstring is deprecated; use convert_uuencode/convert_uudecode instead
Description
Since PHP 8.2, several encodings were dropped from mbstring, including uuencode.
This is a deprecation, so the feature is available until PHP 9.
Example
<?php
mb_convert_encoding('foo', 'uuencode');
?>
Alternatives
- It is recommended to use the
convert_uuencode()andconvert_uudecode()functions to do this.
Related error messages
- handling-base64-via-mbstring-is-deprecated;-use-base64_encode-base64_decode-instead
- handling-html-entities-via-mbstring-is-deprecated;-use-htmlspecialchars,-htmlentities,-or-mb_encode_numericentity-mb_decode_numericentity
- handling-qprint-via-mbstring-is-deprecated;-use-quoted_printable_encode-quoted_printable_decode
- handling-qprint-via-mbstring-is-deprecated;-use-quoted_printable_encode-quoted_printable_decode-instead
- handling-html-entities-via-mbstring-is-deprecated;-use-htmlspecialchars,-htmlentities,-or-mb_encode_numericentity-mb_decode_numericentity-instead
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See mb_convert_encoding
has #[\Override] attribute, but no matching parent method exists
Description
Override is a PHP attribute, that checks if a method is actually overriding the same method from a parent class. This means that there should be a method in one of the parent class, that have the same name.
When no such method is found, it signals that the method with the attribute is now orphaned. It should be renamed, to fit another method.
The error is emitted when a method has the Override but no such method exists in the parent; it is also emitted when Override is used in a class or an interface that has no parent. No error is emitted on traits or enums.
This error is a compile time error, when PHP can solve it at compile time: this means both the class with the Override attribute, and the parent class is available at compile time. It is also an execution time error, when the Override is set in a method in a trait.
Example
<?php
#[Attribute]
class X {}
class Y extends X {
#[Override]
function foo() {}
}
?>
Alternatives
- Remove the Override attribute.
- Rename the current method with the name of a method in the parents.
- Remove the method.
- Rename one of the parent method to use the name of the current method.
Related error messages
has a malformed IPv6 address, closing square bracket missing
Description
SNMP::__construct() accepts an IPv6 $hostname wrapped in square brackets, such as [::1] or [::1]:1161 for a non-default port. The closing ] is what tells the parser where the address ends and an optional :port suffix begins.
If the hostname starts with [ but never contains a matching ], the address cannot be parsed. As of PHP 8.6, this now throws a ValueError instead of emitting a warning and leaving the session half-constructed.
Example
<?php
$snmp = new SNMP(SNMP::VERSION_2c, '[::1', 'public');
?>
Literal Examples
- SNMP::__construct(): Argument #2 ($hostname) has a malformed IPv6 address, closing square bracket missing
Alternatives
- Make sure a bracketed IPv6
$hostnameis properly closed, e.g.[::1]or[::1]:1161.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, this emitted an E_WARNING (“Malformed IPv6 address, closing square bracket missing”) and left the SNMP object without a usable session, instead of throwing.](Previously, this emitted an E_WARNING (“Malformed IPv6 address, closing square bracket missing”) and left the SNMP object without a usable session, instead of throwing.)
Hooked properties cannot be readonly
Description
The readonly keyword is not allowed on hooked properties. On the other hand, it is possible to emulate that feature, by writing the set method.
Example
<?php
class X {
public readonly string $x {
get => $this->x;
set { if (!isset($this->x)) $this->x = $value;}
}
}
?>
Alternatives
- Use the
sethook to emulate readonly. - Omit the readonly keyword.
- Remove the property hooks from the property definition.
Illegal class name
Description
Illegal class name is a compile-time error when the type of a value, used for a class is not valid.
The expressions that use classes are the following : static method call, static property call, static constant call, and static class ($a::class).
The valid types are strings, static class (A::class), identifiers (such as A or \A), method calls (foo()) that returns one of the previous types or data containers holding an object or a class name as a string. On the other hand, boolean, null, integers, float, array() are invalid; some strings are not valid, such as ‘4foo’, though PHP only detects these are execution time, with a different error message.
This kind of error is very rare, as it prevents the code to run.
Example
<?php
array()::t;
(2)::$t;
(true)::t();
//Illegal classname, as integer cannot be a classname
strlen($string)::$property;
// This is valid until execution, where class 4f cannot be found
('4f')::$t;
?>
Alternatives
- Do not use invalid types values to access a class.
Related error messages
Illegal function name
Description
This error messages appears when there is an attempt to create a closure from a function, whose name is not a valid function. Numbers, such as float and integers, are not valid function name, and yield this error. Negative numbers, and other types yield a distinct error.
Example
<?php
const Closure = (0)(...);
var_dump(Closure);
?>
Alternatives
- Use a string, instead of a number. Check that the string is a valid name for a function or a static method.
- Ensures that the name is a static expression, and that each element may be resolved at compile time.
Related error messages
- cannot-use-dynamic-function-name-in-constant-expression
- illegal-method-name
- cannot-use-dynamic-method-name-in-constant-expression
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Illegal method name
Description
PHP 8.5 allows first-class callable syntax ((...)) to be used inside a constant expression, so that a static method call can be turned into a Closure at compile time. To build that closure, the compiler needs the method name as a string that it can resolve at compile time.
Here, the braced expression {0} is a compile-time constant, but it is an integer, not a string, so it cannot be used as a method name. PHP reports this as an illegal method name.
This differs from ‘Cannot use dynamic method name in constant expression’, which is reported when the braced expression cannot be resolved to a constant value at all (for example, because it depends on a variable or is a non-scalar value such as an array).
Example
<?php
class X {
public static function foo() { return 1; }
}
const C = X::{0}(...);
var_dump(C);
?>
Alternatives
- Use a string, instead of a number or another scalar, for the method name.
- Ensure the method name is a literal string, or an expression that PHP can resolve to one at compile time.
Related error messages
- cannot-use-dynamic-method-name-in-constant-expression
- illegal-function-name
- cannot-use-dynamic-function-name-in-constant-expression
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See constantExpressionMethodNameResolution85
Illegal offset type in isset or empty
Description
PHP only uses integers and strings as array index. While certain other types may be converted silently to those types, as null or boolean, objects and arrays yield an illegal type for index.
This error is is specific to isset and empty: these functions are usually very silent, yet an dedicated error message was created for the type check.
This error is reported at compile time when PHP can detect the type then, otherwise, it is reported at execution time.
Example
<?php
$array = [1];
var_dump(isset($array[[]]));
?>
Alternatives
- Convert these types into a string or a integer first.
- Cast these types into a string or a integer first.
Related error messages
- cannot-access-offset-of-type-%s-in-isset-or-empty
- cannot-access-offset-of-type-%s-on-%s
- illegal-offset-type-in-unset
- illegal-offset-type
Illegal offset type in unset
Description
PHP only uses integers and strings as array index. While certain other types may be converted silently to those types, as null or boolean, objects and arrays yield an illegal type for index.
This error is is specific to unset: this function is usually very silent, yet an dedicated error message was created for the type check.
This error is reported at compile time when PHP can detect the type then, otherwise, it is reported at execution time.
Example
<?php
$array = [1];
unset($array[[]]);
?>
Alternatives
- Convert these types into a string or a integer first.
- Cast these types into a string or a integer first.
Related error messages
- cannot-access-offset-of-type-%s-in-isset-or-empty
- cannot-access-offset-of-type-%s-on-%s
- illegal-offset-type
- illegal-offset-type-in-isset-or-empty
Illegal offset type
Description
PHP only uses integers and strings as array index. While certain other types may be converted silently to those types, as null or boolean, objects and arrays yield an illegal type for index.
This error is reported at compile time when PHP can detect the type then, otherwise, it is reported at execution time.
Example
<?php
$a = new Stdclass;
$array = [$a => 2];
$array[$a] = 1;
$array[$array] = 3;
?>
Alternatives
- Convert these types into a string or a integer first.
- Cast these types into a string or a integer first.
Related error messages
- cannot-access-offset-of-type-%s-in-isset-or-empty
- cannot-access-offset-of-type-%s-on-%s
- illegal-offset-type-in-unset
- illegal-offset-type-in-isset-or-empty
illegal string offset
Description
String shall use the array syntax, with the square brackets. Then, the index in that syntax must be an integer, or must be cast to integer.
When the index cannot be converted to an integer, this warning is displayed. PHP proceeds to cast the value to integer, and use it. It will often be 0, but not always.
An extended error also appear if the result of the conversion is larger than the length of the string.
Example
<?php
var_dump(foobar[4foo]);
// displays 'a' + a warning
var_dump(foobar[-4foo]);
// displays 'o' + a warning
?>
Alternatives
- Use a cast operator to make the conversion explicit.
- Check the type of the index to be integer before using it.
- Use substr() to access a specific offset.
Related error messages
Implicit conversion from float %.*H to int loses precision
Description
This warning is emitted when a float is passed to a typed value that requires an integer. The float is truncated, not rounded, to an integer, and passed.
This becomes a Fatal error when strict_types is actived.
The float might be a valid integer, when it has no decimal part: then, no error is emitted.
Example
<?php
function foo(int $a): int {
// At return time
return $a - 0.5;
}
// At call time
foo(1.1);
?>
Literal Examples
- Implicit conversion from float 1.1 to int loses precision
- Implicit conversion from float 0.5 to int loses precision
Alternatives
- Cast the float to integer before using it with a typed resource.
- Round the float to integer before using it with a typed resource.
Related error messages
- implicit-conversion-from-float-string–“%s-”-to-int-loses-precision
- the-float-%.*h-is-not-representable-as-an-int,-cast-occurred
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See implicitConversionToInt
Implicit conversion from float-string “%s” to int loses precision
Description
Bitshift operators and bitwise operators work on integers, not on floats. When a string is provided, it may be converted to integer or float: in the second case, the deprecation warning is emitted.
The warning is not emitted when the conversion lands on an integer.
Example
<?php
// Extract from php-src/Zend/tests/float_to_int/warnings_string_float_literals.phpt
$var = '1.5'|3;
$var = '1.5'&3;
$var = '1.5'^3;
$var = '1.5' << 3;
$var = '1.5' >> 3;
$var = 3 << '1.5';
$var = 3 >> '1.5';
//OK : PHP is smart enough to round this to integer
((1 / 35) * 35) | 3;
//Implicit conversion from float 0.9999999999999999 to int loses precision
//The rounding is not sufficient
((1 / 35) * 7 * 5 ) | 3;
// valid, conversion gives an integer
$var = '14.00000000'|3;
// still valid, conversion does not handle 0.0000000000000001 precision
$var = '13.0000000000000001'|3;
?>
Literal Examples
- Implicit conversion from float-string “1.5” to int loses precision
- Implicit conversion from float-string “0.9999999999999999” to int loses precision
Alternatives
- Cast the string to integer before using it with bitshift or bitwise operators.
- Round the string to integer before using it with bitshift or bitwise operators.
- Simplify the expressions before using it with bitshift or bitwise operators.
Related error messages
- implicit-conversion-from-float-string-“%s”-to-int-loses
- implicit-conversion-from-float-string–“%s-”-to-int-loses-precision
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See implicitConversionToInt
Implicit conversion from float-string “%s” to int loses precision
Description
In cases where integers are required, PHP applies a type cast and convert floats and strings into integers. In many cases, that conversion is eponymous, with 1.0 (float) or ‘10’ being obviously converted to their integer equivalent.
When the conversion is not flawless, in particular when there is a significant decimal part in the float number, this conversion is deleting a part of the value. This message is meant to raise awareness about it.
Situations where this may happens are varied : index in arrays or strings, operators that works on integers, such as bitshift; logical and bitwise operators, etc.
This is a variation of the error ‘A non-numeric value encountered’, where the value could not be converted sanely to an integer.
Example
<?php
$a = [1.23 => 3];
?>
Literal Examples
- Implicit conversion from float-string “1.23” to int loses
Alternatives
- Explicitly cast the value to integer.
- Check if the value is an integer before usage.
Related error messages
- a-non-numeric-value-encountered
- a-non-well-formed-numeric-value-encountered
- implicit-conversion-from-float-string-“%s”-to-int-loses-precision
- implicit-conversion-from-float-string–“%s-”-to-int-loses-precision
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See implicitConversionToInt
Implicit conversion from float-string "%s" to int loses precision
Description
In weak typing mode (the default), a string argument passed where an int parameter is declared is coerced automatically, provided the string is numeric. When that string looks like a float rather than an integer – e.g. '1.5' – PHP still coerces it, by first converting it to a float and then truncating that float to an int, silently discarding the fractional part.
As of PHP 8.1, this specific case – a float-shaped string being coerced down to an int and losing precision in the process – emits a deprecation notice. It is a sibling of the same underlying helper that also fires for float array keys and for bitwise/bitshift operators applied to float-like strings, which are documented separately since they are different call sites in practice.
Example
<?php
function double(int $x) {
return $x * 2;
}
// Weak typing lets a numeric string be passed where an int is
// declared, but '1.5' cannot become an int without losing the .5.
var_dump(double('1.5'));
?>
Literal Examples
- Implicit conversion from float-string “1.5” to int loses precision
Alternatives
- Round or cast the value explicitly before calling the function: double((int) round((float) $x)).
- Declare the parameter as int|float and handle both cases inside the function.
- Validate the input is an integer-shaped string (e.g. with ctype_digit()) before relying on implicit coercion.
Related error messages
- implicit-conversion-from-float-string-“%s”-to-int-loses
- implicit-conversion-from-float-string-“%s”-to-int-loses-precision
- implicit-conversion-from-float-%.*h-to-int-loses-precision
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See implicitConversionToInt
Inconsistent insteadof definition. The method %s is to be used from %s
Description
The insteadof rule picks, for a given method name, the trait it should be taken from, and implicitly excludes that same method from every trait listed after insteadof.
Here, A::foo insteadof A, B says both that foo should come from A, and that A’s own foo should be excluded, which is a direct contradiction. PHP’s full message continues with , but %s is also on the exclude list naming the trait found in both places – a part not captured in this templated entry, which only records the first sentence.
Note that listing a trait that is not otherwise involved in the conflict after insteadof is fine and does not raise this error; it is specifically excluding the trait the method is kept from that is inconsistent.
Example
<?php
trait A {
public function foo() {}
}
trait B {
public function foo() {}
}
class C {
use A, B {
A::foo insteadof A, B;
}
}
?>
Literal Examples
- Inconsistent insteadof definition. The method foo is to be used from A
Alternatives
- Remove the trait providing the winning method from its own exclude list, keeping only the other conflicting traits after
insteadof. - Rewrite the rule as
A::foo insteadof B;if onlyB’sfooshould be excluded.
Related error messages
- a-precedence-rule-was-defined-for-%s::%s-but-this-method-does-not-exist
- failed-to-evaluate-a-trait-precedence-(%s).-method-of-trait-%s-was-defined-to-be-excluded-multiple-times
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Increment on non-alphanumeric string is deprecated
Description
Incrementing a string in a variable is an old darling PHP feature. As long as the last character is an ascii letter, it is incremented to the next ascii value, or wrap to a.
This feature is deprecated since PHP 8.3, and it is replaced by a call to str_increment() and str_decrement() (the last one is a new feature).
Example
<?php
// Increment on non-alphanumeric string is deprecated! (in PHP 8.5)
$a = 'aaa';
echo ++$a;
// Increment on non-alphanumeric string is deprecated
$a = 'aaa!';
echo ++$a;
?>
Alternatives
- Use str_increment().
- Change the generating system entirely.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See incrementNonAlphanumeric
Increment on non-numeric string is deprecated, use str_increment() instead
Description
PHP 8.3 introduced str_increment() and str_decrement(), which update strings by changing the last character’s ascii code. It mirrors a famous PHP easter egg, where a string may be incremented with the ++ operator.
In PHP 8.5, this feature is deprecated, and a warning is emitted. There is no deprecation warning for decrementing, as the feature was not implemented on strings.
Example
<?php
$string = 'aa';
++$string;
echo $string;
?>
Alternatives
- Use str_increment(), instead of
++on string variables.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See incrementNonAlphanumeric
Increment on type bool has no effect, this will change in the next major version of PHP
Description
Post increment on a boolean leaves the value unchanged. While PHP updates strings, integers, floats with the post-increment operator, booleans are immune.
Until PHP 8.3, it was silently done. In PHP 8.3, it raises a deprecation warning, and it will be removed in PHP 9.0.
Post increment, pre increment, as well as increment and decrement are affected by that warning. str_increment() and str_decrement() refuses to use boolean, due to type.
Example
<?php
$a = true;
$a++;
// $a = true
$b = false;
--$b;
// $b = false
?>
Alternatives
- Avoid initializing variables with booleans before incrementing them.
- In case of doubt, check the type before the increment.
Related error messages
- decrement-on-type-bool-has-no-effect,-this-will-change-in-the-next-major-version-of-php
- decrement-on-type-null-has-no-effect,-this-will-change-in-the-next-major-version-of-php
Related error messages
Index invalid or out of range
Description
This error message is returned by the SplFixedArray object, when trying to access indices outside the validity interval. A SplFixedArray has a limited number of elements, set at the beginiing, or updated laster with setSize().
On a regular array, accessing an undefined index is a warning, not a fatal error.
A different message is emited when the index is not an integer.
Example
<?php
$object = new SplFixedArray(3);
$object[1] = 3;
echo $object[1]; // OK
echo $object[0]; // OK, returns null
echo $object[-1];
//Fatal error: Uncaught RuntimeException: Index invalid or out of range
?>
Alternatives
- Check the size of the array before accessing one of the index.
- Check that the index is zero or more.
- Use a regular array.
Indirect modification of %s::$%s is not allowed
Description
While it is possible to create references on object’s properties, it is not possible to do so on a property with a hook. The property hook is returned by value, by default.
Example
<?php
class X {
public $byRef {
get {
$x = 42;
return $x;
}
}
}
$x = new X();
$y = &$x->byRef;
?>
Literal Examples
- Indirect modification of X::$byRef is not allowed
Alternatives
- Add
&before thegethook. - Make the property a normal property, without hooks.
- Avoid using a reference on a property hook.
Related error messages
Indirect modification of overloaded element of %s has no effect
Description
The variable $object is an object. Since it implements the ArrayAccess interface, it may also use the array syntax, for example with the brackets and index.
While the syntax makes $object looks like an array, not all operations are available. It is possible to get an index’s value, or to give it a new value; but it is not possible to use the increment or decrement operators : those are both a get and a set, and this is not supported by the ArrayAccess interface.
Here, the notion of ‘overloaded’ applies to the object properties: they are not data containers, as usual, but replaced (overloaded) with method calls.
There are different variations of that situation : for example, an append on the value at an index is not possible either. In fact, the interface returns a value (not a reference), and the append applies to a value, that is not linked the original array.
Besides the ArrayAccess, there are several native PHP classes that triggers these warning: ArrayObject, ArrayIterator, PDORow or ArrayAccessImpl.
Example
<?php
class ObjectOne implements ArrayAccess {
function offsetGet($index): mixed {
echo __METHOD__ . "($index)\n";
return 2;
}
function offsetExists($index): bool { return true; /**/ }
function offsetSet($index, $newval): void { /**/ }
function offsetUnset($index): void { /**/ }
}
$object = new ObjectOne;
$object[2]++;
$object[2][3] = 2;
?>
Literal Examples
- Indirect modification of overloaded element of $object has no effect
Alternatives
- Use an actual array to handle those edge cases.
- Write the ObjectOne class to handle these operation with a method call.
Related error messages
Indirect modification of overloaded property %s::$%s has no effect
Description
The variable $object is an object. Since it implements the __get magic method, any property is available.
While the syntax makes $object->something looks like a actual property and an array, not all operations are available. It is possible to get any property’s value, or to give it a new value; but it is not possible to use the append operator : this is not supported by the magic method.
There are different variations of that situation : for example, an increment or decrement on the value on a property is not possible either.
There is no call that will relay to the magic method that this property is being appended or incremented.
Example
<?php
class OneObject {
function __get($var) { }
}
$object = new OneObject;
$object->something[] = 'bar';
?>
Literal Examples
- Indirect modification of overloaded property OneObject::$something has no effect
Alternatives
- Use an actual data container to represent a property.
Related error messages
Input number is larger than PHP_INT_MAX, precision has been lost in conversion
Description
bindec(), octdec(), hexdec() and base_convert() all share the same internal conversion routine, which accumulates the result in a zend_long for as long as it fits, then switches to a double once the value would overflow. Once that switch happens, the number is only an approximation: a double only has 53 bits of mantissa, so digits beyond that are rounded away.
PHP 8.6 emits a notice the moment this switch occurs, to make the precision loss visible instead of silently returning an inexact float.
Example
<?php
echo hexdec('FFFFFFFFFFFFFFFF');
?>
Literal Examples
- Input number is larger than PHP_INT_MAX, precision has been lost in conversion
Alternatives
- Use the GMP or BCMath extensions to convert arbitrarily large numbers between bases without losing precision.
- Validate the input length against the base before conversion, so it is guaranteed to fit in a native integer.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, bindec(), octdec(), hexdec() and base_convert() silently returned a float once the number no longer fit in an integer, without any indication that precision had been lost. As of PHP 8.6, this now emits an E_NOTICE.](Previously, bindec(), octdec(), hexdec() and base_convert() silently returned a float once the number no longer fit in an integer, without any indication that precision had been lost. As of PHP 8.6, this now emits an E_NOTICE.)
instanceof expects an object instance, constant given
Description
Until PHP 7.3, PHP required an object as the left operand of instanceof. In recent versions, PHP does not emit an error anymore, and returns null.
Although the function reports a constant problem, the error is reported with literal values, and not with constants.
Constants were allowed to receive objects in PHP 8.1.
Example
<?php
null instanceof A::class;
?>
Alternatives
- Upgrade to PHP 7.3 or more recent.
- Chech the left operand with
is_object(), before using instanceof.
Instantiation of class Closure is not allowed
Description
The Closure class is a PHP native class, which cannot be directly instantiated. It must be created with other syntaxes, such as the closure syntax, function () {};, first class callable foo(...), or arrow functions fn () => 1;.
Example
<?php
new Closure();
?>
Alternatives
- Use the closure syntax.
- Use the arrow function syntax.
- Use the first class callable syntax.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Instantiation of mysqli_stmt without providing the $query parameter is deprecated
Description
mysqli_stmt’s constructor accepts an optional $query string, which, when given, prepares the statement immediately. Omitting it produces an object that is not fully initialized: most of its properties and methods throw until prepare() is called explicitly, which is a confusing two-step state for a class whose entire purpose is to represent a prepared statement. PHP 8.6 deprecates constructing (or calling mysqli_stmt_init() / mysqli::stmt_init()) without a query.
Example
<?php
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');
$stmt = new mysqli_stmt($link);
?>
Alternatives
- Pass the SQL statement directly to the constructor:
new mysqli_stmt($link, $query), or usemysqli_prepare()/$mysqli->prepare(). - If you need the two-step flow, call
$stmt->prepare($query)immediately after construction to avoid using the object while uninitialized.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Interface “%s” not found
Description
This error message is reported when the interface could not be loaded, or when the name of the class is invalid.
Example
<?php
// '4f' is not a valid name for an interface
('4f')::c;
// it is not possible to name a class 'interface'
('interface')::c;
?>
Literal Examples
- Interface “4f” not found
- Interface “interface” not found
Alternatives
- Check spelling and namespace for that interface.
- Create the required interface.
- Check if the interface is defined in an extension, and the extension is included in the current PHP engine.
- Check if the interface is defined in a dependency, and the dependency is included in the current composer.json.
- Do not use static, parent or self in a string to call a method statically.
Related error messages
In previous PHP versions, this error message used to be :ref:interface-%s-cannot-implement-itself.
Interface %s cannot contain non abstract method %s()
Description
In an interface, there can only be methods signature, and no method body. Aka, this means only the semi-colon after the method signature, et no body block.
Methods in an interface are considered abstract by default. There is no need to add such explicit option, nor is it even legal to use it there.
Hence, in an interface, there are only abstract methods: methods without a body. The abstract keyword is implicit in an interface; When the interface is partially implemented by a class, the remaining methods must be declared abstract in that class.
If some methods have to be made concrete (aka, not abstract), it is possible to create an abstract class, with a mix of abstract and concrete methods, which can then be extended by the target class.
Example
<?php
interface I {
function foo() {}
function bar() ;
}
abstract class CI {
function foo() {}
abstract function bar() ;
}
?>
Literal Examples
- Interface I cannot contain non abstract method foo()
Alternatives
- Remove all bodies in an interface’s method.
- Turn the interface into an abstract class.
- Move the concrete class to a trait, and use the trait, along with the interface.
Related error messages
Interface %s cannot extend class %s
Description
An interface must extends another interface. It cannot extends a class, nor a trait, nor an enum.
Also, a class cannot extends an interface: it must implement it.
Example
<?php
class X {}
interface I extends X {}
?>
Literal Examples
- Interface I cannot extend class C
Alternatives
- Turn the original class into an interface.
- Make the original interface into an class.
- Split the class into a class and an interface, and extends the latter.
Interface %s cannot implement itself
Description
An interface can extend another interface, to expand its list of methods. It cannot extends itself, as it is useless.
Example
<?php
interface I extends I {}
?>
Literal Examples
- Interface I cannot implement itself
Alternatives
- Extend another interface.
- Do not extend the current interface.
In more recent PHP versions, this error message is now :ref:interface-"%s"-not-found.
Interface method %s::%s() must not be final
Description
A method in an interface cannot be final, as it has to be implemented: it is actually abstract. The same method, in the implementing class, may be final.
Example
<?php
interface X {
final function foo();
}
?>
Literal Examples
- Interface method X::foo() must not be final
Alternatives
- Remove the
finaloption in the interface, add it to any implementing class, or its children.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Interfaces may not include properties
Description
Interfaces can define methods and constants, but they can’t define properties. Actually, they can only define properties with a property hook, as the property hooks are methods.
Example
<?php
interface I {
private $property;
}
?>
Alternatives
- Upgrade PHP version to 8.4.
- Turn the interface in an abstract class.
- Turn the interface in a trait.
- Add a property hook to a property.
In previous PHP versions, this error message used to be :ref:interfaces-may-only-include-hooked-properties.
Interfaces may only include hooked properties
Description
PHP 8.4 introduced the support for properties in interfaces. Although, the properties must have a property hook, aka one associated method that deals with get and set operations on that property.
Example
<?php
interface I {
public $property;
public $propertyWithHook {
// This is an abstract property
get;
};
}
?>
Alternatives
- Add an identity hook, such as
get => $this->property = $value;, which is the default behavior. - Turn the interface into an abstract class.
- Turn the interface into a trait.
In more recent PHP versions, this error message is now :ref:interfaces-may-not-include-properties.
Internal function %s%s%s() does not accept named variadic arguments
Description
Internal (C-implemented) functions with a variadic parameter, such as array_merge()’s ...$arrays, only ever have a single name for that parameter. When a call spreads an array with string keys into such a function using ..., PHP tries to match each key against a parameter name, and every key besides the one matching the variadic parameter’s own name is rejected, since there is no other named slot for it to bind to.
This restriction is specific to internal functions: user-defined variadic functions accept arbitrary named arguments into their variadic parameter without complaint.
Example
<?php
$parts = ['x' => [1], 'y' => [2]];
array_merge(...$parts);
?>
Literal Examples
- Internal function array_merge() does not accept named variadic arguments
Alternatives
- Apply array_values() to the array before spreading it into the internal function, so its keys are reset to plain integers and no longer interpreted as parameter names.
In previous PHP versions, this error message used to be :ref:array_merge()-does-not-accept-unknown-named-parameters.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.6, the same ArgumentCountError was thrown, but worded “%s%s%s() does not accept unknown named parameters” (e.g. “array_merge() does not accept unknown named parameters”), without the “Internal function” prefix and without naming variadic arguments specifically as the cause.](Prior to PHP 8.6, the same ArgumentCountError was thrown, but worded “%s%s%s() does not accept unknown named parameters” (e.g. “array_merge() does not accept unknown named parameters”), without the “Internal function” prefix and without naming variadic arguments specifically as the cause.)
IntlListFormatter object is already constructed
Description
IntlListFormatter, added in PHP 8.5, wraps ICU’s list formatter to render lists such as "a, b, and c" according to locale rules. Like other intl classes, its constructor guards against being run twice on the same object: the first successful call allocates the underlying ICU formatter, and a second call would leak that resource and leave the object in an inconsistent state.
Calling __construct() explicitly a second time – directly, or indirectly through code that re-runs construction on an already built instance – throws this error.
Example
<?php
$formatter = new IntlListFormatter('en_US');
// Calling the constructor a second time on the same instance
$formatter->__construct('fr_FR');
?>
Alternatives
- Create a new
IntlListFormatterinstance instead of reusing and reconstructing the same object. - Never call
__construct()manually after the object has already been created withnew.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Invalid argument supplied for foreach()
Description
foreach() works on arrays or objects. For the array, all the elements of the array are read; for the objects, it is either the public properties, read like an array, or the Iterator interface, which uses specific methods.
Then, any other type is forbidden to be used with foreach(). This means all scalars elements, including string, integer and null.
Example
<?php
foreach(1234 as $b) {
echo $b;
}
?>
Alternatives
- Check that the source of the foreach can be used with is_iterable().
In more recent PHP versions, this error message is now :ref:foreach()-argument-must-be-of-type-array|object.
Invalid characters passed for attempted conversion, these have been ignored
Description
This error is emitted when a character outside the range of validity is used.
In the example above, the octdec() function converts a string from octal to decimal. Octals are written with figures from 0 to 8. In this case, 9 is excluded.
The same error is emitted with the other maths bases : for example, using ‘a’ in a decimal, or ‘X’ in a hexadecimal, etc.
Example
<?php
// 9 is not an octal and can't be converted
$decimal = octdec(342391);
// same as above, but the 9 is hidden with the octal notation (starts with 0)
$decimal = octdec(01234567);
?>
Alternatives
- Check that the characters are in the correct range before attempting the conversion.
Invalid indentation - tabs and spaces cannot be mixed
Description
Since PHP 7.3, HEREDOCS and NOWDOCS syntax allows the text to be indented by the same amount than the closing tag (here X). The indentation must be built with only spaces or only tabulations, and cannot be a mix of both.
Example
<?php
$x = <<<X
classic text
X // one tabulation + one space
?>
Alternatives
- Make the indentation spaces only.
- Make the indentation tabulations only.
Invalid numeric literal
Description
This error reports an invalid number, hardcoded in the source code.
Numbers are written with digits, without delimiters such as simple or double quotes. Then, they are converted in PHP’s internal representation of a number, and this is where error may arise.
In particular, integers have an upper and lower limit, PHP_INT_MAX and PHP_INT_MIN. Although, in that case, they are turned into a float, with loss of precision but no warning.
Then, PHP supports binary, octal and hexadecimal format. In the case above, the o signals an octal number, written with digits from 0 to 7. 8 is not allowed, and is not parsed by PHP.
This is also the case for illegal characters in binary (anything other than 1 and 0), or hexadecimal (anything other than digits, and letters from a and f).
An old convention was to consider octal any number that starts with a leading 0.
Example
<?php
echo 0o78;
echo 078;
?>
Alternatives
- Fix the number and use valid digits.
- Drop the initial 0 to make the number decimal, not octal.
- Add quotes to make this number a string, not a parsed number.
Invalid UTF-8 codepoint escape
Description
PHP supports unicode as escape sequence. They are used in double-quoted strings, and use the \u{73} format. The digits must represent a valid unicode codepoint: here, 73 represents the ASCII letter s.
When the prefix \u{ is detected, PHP tries to understand the next characters as an integer. When this is not the case, it fails the codepoint detection and stops.
In particular, it is not possible to use the _ number separator in these sequences.
Example
<?php
$a = "\u{fgh}";
echo \u{1F4_18};
?>
Alternatives
- Check the values inside the curly braces: chances are it needs to be replaced with smaller values.
- If there is no intent to use unicode codepoint, add
\to make PHP handle it as a literal value.
Related error messages
Related error messages
Invalid UTF-8 codepoint escape: Codepoint too large
Description
PHP supports unicode as escape sequence. They are used in double-quoted strings, and use the \u{73} format. The digits must represent a valid unicode codepoint: here, 73 represents the ASCII letter s.
When a valid escape sequence is detected, PHP use the integer between the curly braces. Unicode comprises 1,114,112 code points in the range 0 to 10FFFF. Beyond that value, codepoint are undefined, and do not represent anything anymore.
Example
<?php
$a = "\u{ffffff}";
?>
Alternatives
- Check the values inside the curly braces: chances are it needs to be replaced with smaller values.
Related error messages
Related error messages
Io\Poll\Handle cannot be implemented by user classes
Description
PHP 8.6 introduces a native Polling API (Io\Poll) for waiting on readiness of multiple I/O resources at once, backed by epoll or kqueue at the system level. Io\Poll\Handle is the marker interface that identifies a resource as pollable; it declares no methods of its own.
Every concrete handle type must register a low-level php_poll_handle_ops operations table that tells the polling backend how to obtain the underlying file descriptor and check the handle’s validity. Userland classes have no way to provide that table, so implementing Io\Poll\Handle directly from PHP code is rejected with a fatal error at class-declaration time, rather than producing a handle that would silently fail to work with the poller.
Example
<?php
class MyHandle implements Io\Poll\Handle {
}
?>
Literal Examples
- Io\Poll\Handle cannot be implemented by user classes
Alternatives
- Use one of the internal classes that already implement Io\Poll\Handle (such as a stream or socket resource wrapper), instead of implementing the interface yourself.
- Wrap or compose an existing pollable resource rather than trying to make an arbitrary object pollable.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
‘%s’ is an invalid class name
Description
This error is emitted when a fully qualified name is used as a type (property, constant, parameter, returntype), and that cannot be a valid name. For example, this applies to \self, \static, \parent. Other keywords, such as true, null get a different error message.
Note also that all keywords are not covered with this error message, and some have slipped through the checks: for example, \interface, \class, \enum, \resource… are all valid code. In fact, PHP won’t create objects of such types, so this makes such type unusable.
Example
<?php
class X {
function foo(\self $s) {}
}
?>
Literal Examples
- ‘\self’ is an invalid class name
- ‘\parent’ is an invalid class name
- ‘\static’ is an invalid class name
Alternatives
- Do not use PHP keywords as fully qualified name with a type.
Related error messages
is an invalid offset
Description
The requested value could not be found in the underlying array.
Indeed, the SplDoublyLinkedList has only 3 elements, none with the 4 index.
The problem also arise when using add method, with an index that is negative, or beyond the current last element of the list.
Traditional PHP array do not report this error: they return null, with the Undefined array key warning.
Example
<?php
$a = new SplDoublyLinkedList();
$array = [1,2,3];
foreach($array as $k => $v){
$a->add($k,$v);
// error when writing on an index out of bound
// the first $k + 1 is beyond the count of the list (0), and fails.
$a->add($k + 1,$v);
}
// error when accessing an index out of bound
print $a[4];
?>
Literal Examples
- SplDoublyLinkedList::add(): Argument #1 ($index) is out of range
Alternatives
- Check that the index in positive, and below the current number of elements in the list.
Related error messages
is an unsupported rounding mode
Description
This error is generated when a rounding error is used with bcround() or the BCMath\Number::round() method is used.
Example
Alternatives
- Check documentation for the valid rounding enumerations.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
is not a valid codepoint
Description
Some functions uses integers to represents UTF-8 characters, on top of their string representation. When an integer is provided, it has to represent an actual character, in the UTF-8 range.
In particular, the character cannot be negative, or bigger than 55296.
Example
<?php
mb_substitute_character(-10);
?>
Alternatives
- Check for the integer value before using it: it must be between 0 and 55296.
- Use a string representation, with an escape sequence.
Iterator %s returned an invalid value (must return a string, a stream, or an SplFileInfo object)
Description
Phar::buildFromIterator() (and PharData::buildFromIterator()) adds one archive entry per value produced by the given iterator. Each value it receives must be either a string (the content of the file), a stream resource, or an SplFileInfo object (or subclass, such as SplFileObject) pointing at the file to add; the corresponding key is used as the entry’s path inside the archive.
If the iterator yields anything else, such as an integer, an array, or a plain object that is not an SplFileInfo, PHP cannot turn it into archive content and throws this UnexpectedValueException, naming the iterator’s class.
Example
<?php
class MyIterator implements Iterator {
private array $items = ['a.txt', 42, 'b.txt'];
private int $pos = 0;
public function current(): mixed { return $this->items[$this->pos]; }
public function key(): mixed { return $this->pos; }
public function next(): void { $this->pos++; }
public function rewind(): void { $this->pos = 0; }
public function valid(): bool { return isset($this->items[$this->pos]); }
}
$phar = new PharData('/tmp/archive.tar');
$phar->buildFromIterator(new MyIterator());
?>
Literal Examples
- Iterator MyIterator returned an invalid value (must return a string, a stream, or an SplFileInfo object)
Alternatives
- Make sure every value the iterator yields is a string, a stream resource, or an SplFileInfo (e.g. SplFileObject) instance.
- Use RecursiveDirectoryIterator or a similar built-in filesystem iterator, which naturally yields SplFileInfo objects.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Iterator does not support rewinding
Description
Iterators are executed one way, and cannot be rewind: once they have reached the end of their list of value, they stay there. Some Iterator subclasses are able to rewind at the beginning of the list, though.
Example
<?php
$XML = <<< XML
<root>
<item>1</item>
<item>2</item>
<item>3</item>
</root>
XML;
$dom = new DomDocument();
$dom->loadXml($XML);
$items = $dom->getElementsByTagName('item');
echo 'Count: '.count($items).PHP_EOL;
echo 'Count: '.iterator_count($items->getIterator()).PHP_EOL;
$it = new IteratorIterator($items);
echo 'Count: '.iterator_count($it).PHP_EOL;
echo 'Count: '.iterator_count($it).PHP_EOL;
?>
Alternatives
- Create a second iterator, based on the first one, and run the second operation with it.
- Replace the usage of the Iterator by a subclass, that accepts rewind, such as ArrayIterator.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
JIT is incompatible with third party extensions that override zend_execute_ex(). JIT disabled.
Description
The root cause is that PHP’s JIT has a fundamental incompatibility with extensions that override the engine’s core execution handler zend_execute_ex().
When such an extension is loaded, PHP proactively disables JIT and shows that warning.
This issue goes far beyond just debuggers and coverage tools. Any extension that instruments code, like profilers, APMs, and security modules, can trigger it.
- Debuggers & Code Coverage:
xdebug,pcov,xhprof,pinba,suhosin - Performance & APM Tools:
blackfire,newrelic,tideways_xhprof,ddtrace,solarwinds - Security Modules:
bt_security_notice,bt_safe,imunify360 - Async & Server Frameworks
swoole - PHP Internals & Testing (Zend DTrace, uopz (User Operations for Zend), Zend Observer API (older implementations))
- Other APM & Instrumentation:
skywalking
Note: the list above is not exhaustive.
Example
Alternatives
- Manage Development vs Production: for extensions that are meant for development, like
xdebugandpcov, the simplest solution is to only load them in your development environment, such as by using differentphp.inifiles. - Check for Alternative APIs or Versions: the newer
Zend Observer APIis the most JIT-friendly method for instrumenting code. Modern versions of tools likenewrelicmay support JIT by using this API, so always consult an extension’s latest documentation. - Consult Vendor Docs: many vendors provide specific JIT guidance. For instance, specific settings can be used to allow JIT to work with
imunify360. - Disable JIT by setting opcache.jit=disable in the php.ini or via
-ddirective.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
jump into a finally block is disallowed
Description
It is not possible to make a goto, when the label is in a finally block. It is OK to do the goto call when both goto and label are in the finally block, though.
Example
<?php
goto theLabel;
try {}
catch (Exception) {}
finally {
theLabel:
$a++;
}
?>
Alternatives
- Replace the goto call with something else.
- Move the goto in the finally block.
- Move the label out of the finally block.
Related error messages
jump out of a finally block is disallowed
Description
It is not possible to make a goto, when the label is in a finally block. It is OK to do the goto call when both goto and label are in the finally block, though.
Example
<?php
try {}
catch (Exception) {}
finally {
goto theLabel;
}
theLabel:
$a++;
?>
Alternatives
- Replace the goto call with something else.
- Move the goto after the finally block.
- Move the label in the finally block.
Related error messages
Key element cannot be a reference
Description
In a foreach() loop, the value may be a reference, when it needs to be updated. The key, on the other hand, cannot be changed, and hence, cannot have a reference.
Example
<?php
foreach($array as &$key => $value) {}
?>
Alternatives
- Remove the reference from the key.
- Use array_flip() to make the keys the values, and update them, then use the same function again.
Keys must be of type int|string during array unpacking
Description
Argument unpacking is the transformation of an array into a list of arguments. With arrays, the keys can only be integers or strings: they will be used for positional and named arguments, respectively.
Argument unpacking also applies to iterator and generator. In that case, it is possible to have keys that are not of type integer or string: they might be of any type. Yet, the unpacking of arguments needs these types to understand what kind of arguments is involved.
Any other type is forbidden : null, boolean, float (even without decimal part), and objects with __toString() magic methods. There is not type juggling applied, with or without strict_types directive.
Example
<?php
function foo(...$args) {
var_dump($args);
}
function gen() {
yield 1.23 => 123;
yield '2.34' => 234;
}
try {
print_r([...gen()]);
} catch (Error $ex) {
echo 'Exception: ' . $ex->getMessage() . PHP_EOL;
}
?>
Alternatives
- Ensure the iterator yields only integer or string types.
- Ensure the generator yields only integer or string types.
Label ‘%s’ already defined
Description
A goto label has been defined twice or more. This is not allowed, as the goto call won’t be able to decide which label to reach.
Note that a single unused label is allowed, and is considered dead code.
Multiple identical labels are possible, in different method contexts.
Example
<?php
function foo() {
C:
C:
// valid code, though dead and unused
D:
}
function bar() {
// valid code, though dead and unused
D:
}
?>
Literal Examples
- Label ‘C’ already defined
Alternatives
- Remove duplicate label.
- Rename duplicate label.
- Move the duplicate label to a distinct method.
Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs
Description
PDO supports a uri: DSN prefix: instead of passing the real DSN, an application could pass uri: followed by a URI, and PDO would fetch the actual DSN string from the resource that URI points to. The URI could name a local file, but could also be a remote URL fetched through a stream wrapper.
Fetching connection credentials from an arbitrary, potentially remote, URI on every connection is risky: with drivers such as SQLite it could be abused to read arbitrary files on the server, and remote URIs add an unpredictable performance cost and an extra trust boundary. This lookup mechanism is therefore deprecated.
Example
<?php
$pdo = new PDO('uri:file:///etc/myapp/dsn.txt');
?>
Alternatives
- Read the DSN from the file yourself in userland code (for example with
file_get_contents()against a local, trusted path) and pass the resulting string directly to thePDOconstructor.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Making a constructor a Generator is deprecated
Description
Using yield anywhere in the body of __construct() turns it into a Generator function. Because a Generator’s body only starts running once it is iterated (and nothing iterates a constructor), the code inside such a constructor never runs when the object is created with new: initialization is silently skipped.
Since this pattern is virtually always a mistake, PHP 8.6 deprecates making a constructor a Generator.
Example
<?php
class X {
public function __construct() {
yield 1;
}
}
new X;
?>
Literal Examples
- Making a constructor a Generator is deprecated
Alternatives
- Move the code that uses
yieldinto a separate, regular method, and call it (or return its Generator) explicitly instead of relying on__construct(). - If the constructor only needs to assign properties, replace
yieldwith plain assignments.
Related error messages
- making-a-destructor-a-generator-is-deprecated
- returning-a-value-from-a-constructor-is-deprecated
- constructor-%s::%s()-cannot-declare-a-return-type
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See constructorAsGenerator
Making a destructor a Generator is deprecated
Description
Using yield anywhere in the body of __destruct() turns it into a Generator function. A Generator only starts executing once something iterates it, but nothing iterates the return value of a destructor: PHP just calls it during garbage collection and discards the result. As a consequence, the body of such a destructor never actually runs, silently skipping any cleanup code it contains.
Since this pattern is virtually always a mistake, PHP 8.6 deprecates making a destructor a Generator.
Example
<?php
class X {
public function __destruct() {
yield 1;
}
}
$x = new X;
unset($x);
?>
Literal Examples
- Making a destructor a Generator is deprecated
Alternatives
- Move the code that uses
yieldinto a separate, regular method that__destruct()calls directly. - If the destructor only needs to release resources, replace
yieldwith plain statements.
Related error messages
- making-a-constructor-a-generator-is-deprecated
- returning-a-value-from-a-destructor-is-deprecated
- destructors-cannot-declare-a-return-type
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See destructorAsGenerator
Match expressions may only contain one default arm
Description
match() expression may have one default entry, but no more than that. It is the same than for switch().
Example
<?php
$a = match($b) {
default => 1;
default => 2;
}
?>
Alternatives
- Remove one of the default arm.
- Remove all the default arms.
Related error messages
Maximum depth of %d exceeded. The depth limit can be changed using the max_depth unserialize() option
Description
PHP 7.4 introduced an option with the unserialize() function. It is called max_depth and it limits the number of nesting levels that unserialize allows, when producing the PHP structures. This saves memory and processing power.
Example
<?php
// 4 levels of nesting
$a = [[[[]]]];
$string = serialize($a);
print_r(unserialize($string, ['max_depth' => 2]));
?>
Literal Examples
- Maximum depth of 2 exceeded. The depth limit can be changed using the max_depth unserialize() option
Alternatives
- Remove the option from the call to unserialize().
- Check the string and count the level of nesting, before calling unserialize().
Maximum execution time of %d second%s exceeded
Description
This error indicates that the application has been running for longer than an acceptable amount of time: by default, 30 seconds.
To avoid working indefinitely on a task, PHP cancels its execution.
It is common to set this duration to low levels, so as to keep execution time short. In a production environement, any such error should be investigated, and refactored.
Example
<?php
// an infinite loop that will break beyond max execution time, eventually
for(;;) {}
?>
Literal Examples
- Maximum execution time of 30 seconds exceeded
Alternatives
- Write faster PHP code.
- Write lighter PHP code.
- Update the configuration directive max_execution_time for the whole application.
- Update the configuration directive max_execution_time for a part of the application.
Method %pS::%pS() does not exist
Description
The ReflectionMethod constructor requires the name of a method that actually exists on the given class (or object). When no such method is declared, either directly on the class or via one of its parents, traits or interfaces, the Reflection API cannot build the requested introspection object and throws a ReflectionException instead.
Example
<?php
class X {}
$reflection = new ReflectionMethod('X', 'doesNotExist');
?>
Literal Examples
- Method X::doesNotExist() does not exist
Alternatives
- Check the method name for typos, including its case.
- Use
method_exists()orReflectionClass::hasMethod()to check the method is available before reflecting on it.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Method %s::%s() cannot be static
Description
Some PHP special methods cannot be static. This is the case of all the PHP magic methods, such as the constructor __construct, the destructor __destruct, and all the others: __call(), __callStatic(), __get(), __set(), __isset(), __unset(), __sleep(), __wakeup(), __serialize(), __unserialize(), __toString(), __invoke(), __set_state(), __clone() and __debugInfo().
Example
<?php
class X {
static function __construct() {}
}
?>
Literal Examples
- Method x::__construct() cannot be static
Alternatives
- Make a static method that can call the method that would be static. Be aware, this will require the building of an object, as a static method does not set
$this.
Related error messages
Method %s::%s() cannot declare a return type
Description
There can be no return type for certain methods, such as the constructor and the desctructor.
The constructor is called while creating a new instance of an object, but it doesn’t return the object itself.This is the case even if $this is available in the method.
The destructor is called while destroying an instance, and shall not return anything.
Theses methods must remain without a return type: not void, not mixed, not never, or anthing else.
Example
<?php
class X {
function __construct() : int { }
function __destruct() : string { }
}
?>
Literal Examples
- Method X::__construct() cannot declare a return type
- Method X::__destruct() cannot declare a return type
Alternatives
- Remove the return type of the method.
Related error messages
Method %s::%s() must be static
Description
The magic methods __set_state and __callStatic must be static. These are the only magic methods that must be static.
Example
<?php
class X {
function __set_state($state) {}
}
?>
Alternatives
- Add
staticto the method signature, and remove all$thisin its body. - Remove the methods.
Method %s::%s() must take exactly 1 argument
Description
This error reports that a method requires one and only one argument. It applies to methods such as __set_state() and __get.
It may be surprising that it is a compile time error. Actually, the faulty method is a magic method, so PHP already knows what signature is expected for that method.
Example
<?php
class X {
function __set_state() {}
}
?>
Literal Examples
- Method X::__set_state() must take exactly 1 argument
Alternatives
- Use one argument for this method.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Method %s::%s() must take exactly 2 arguments
Description
This error reports that a method requires two and only two arguments. It applies to methods such as __set().
It may be surprising that it is a compile time error. Actually, the faulty method is a magic method, so PHP already knows what signature is expected for that method.
Example
<?php
class X {
function __set() {}
}
?>
Literal Examples
- Method X::__set() must take exactly 2 arguments
Alternatives
- Use one argument for this method.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Method %s::%s cannot be #[\NoDiscard] error_type
Description
The #[\NoDiscard] attribute marks a function, method or closure so that the engine emits a warning whenever a caller ignores its return value. A number of magic methods – __clone, __set, __unset, __wakeup and __unserialize – are expected to always behave as if declared : void: PHP calls them purely for their side effect and never looks at, or exposes, any value they might return. Marking one of them #[\NoDiscard] is therefore meaningless, and PHP rejects it at compile time.
This is the same wording as the message used for __construct and __destruct (see method-%s::%s-cannot-be-#[–nodiscard]), but produced by a different internal check: those two magic methods are not even allowed to declare a return type at all, whereas the methods covered here are simply always treated as implicitly void. The trailing ‘error_type’ in this file’s identifier is an artifact of how this catalog extracts messages from the PHP source; it is not part of the text PHP actually displays.
Example
<?php
class X {
#[\NoDiscard]
public function __clone() {}
}
$x = new X();
clone $x;
?>
Literal Examples
- Method X::__clone cannot be #[\NoDiscard]
- Method X::__set cannot be #[\NoDiscard]
- Method X::__unset cannot be #[\NoDiscard]
- Method X::__wakeup cannot be #[\NoDiscard]
- Method X::__unserialize cannot be #[\NoDiscard]
Alternatives
- Remove the
#[\NoDiscard]attribute from the magic method. - If a discardable-value warning is needed, move the logic to a regular, non-magic method and mark that one instead.
Related error messages
- method-%s::%s-cannot-be-#[–nodiscard]
- a-void-%s-does-not-return-a-value
- a-never-returning-%s-does-not-return-a-value
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Method %s::%s cannot be #[\NoDiscard]
Description
The #[\NoDiscard] attribute marks a function, method or closure so that the engine emits a warning whenever a caller ignores its return value. Certain magic methods, such as __construct, __destruct, __clone and __wakeup, are always invoked for their side effect and never return a usable value to the caller (new returns the object itself, not the constructor’s return value), so attaching #[\NoDiscard] to them is meaningless and rejected at compile time.
Example
<?php
class X {
#[\NoDiscard]
public function __construct() {}
}
new X();
?>
Literal Examples
- Method X::__construct cannot be #[\NoDiscard]
Alternatives
- Remove the
#[\NoDiscard]attribute from the magic method. - If a discardable-value warning is needed, move the logic to a regular, non-magic method and mark that one instead.
Related error messages
- a-void-%s-does-not-return-a-value
- a-never-returning-%s-does-not-return-a-value
- method-%s::%s-cannot-be-#[–nodiscard]-error_type
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Method %s::__construct() cannot declare a return type
Description
There can be no return type for a constructor method. It is called while creating a new instance of an object, but it doesn’t return the object itself. This is the case even if $this is available in the method.
Example
<?php
class X {
function __construct() : int {
}
}
?>
Literal Examples
- Method X::__construct() cannot declare a return type
Alternatives
- Remove the return type of the method.
Related error messages
- destructors-cannot-declare-a-return-type
- constructor-%s::%s()-cannot-declare-a-return-type
- returning-a-value-from-a-constructor-is-deprecated
In previous PHP versions, this error message used to be :ref:constructor-%s::%s()-cannot-declare-a-return-type.
Method %s::__toString() must not throw an exception, caught %s: %s
Description
Until PHP 8.0, __toString could not throw exception, and would end up with this error. In PHP 8.0, it is now possible.
Example
<?php
class X {
function __toString() {
throw new \Exception('error');
}
function foo() {
throw new \Exception('error');
}
}
?>
Literal Examples
- Method X::__toString() must not throw an exception, caught Exception: error
Alternatives
- Upgrade to PHP 8.0.
- Store the error in another property, and check the property in another method, after the call to
__toString.
Method name must be a string
Description
When using a dynamic syntax to call a method, the name of the method must be a string. It cannot be any other type, as no type juggling will take place. In particular, objects with toString are not converted to their string value.
Although method names have a specific format, this is not checked here, and the string is used raw.
Note that there is not equivalent for dynamic property names: they are cast to string as needed.
Example
<?php
class X {
static function foo() {}
}
$b = 1;
X::$b();
?>
Alternatives
- Cast the variable to string first, with
(string). - Check if the variable is a string before using it.
- Use a switch to hardcode the method name.
Methods with the same name as their class will not be constructors in a future version of PHP; %s has a deprecated constructor
Description
In PHP 4, the constructor of a class was the method with the same name as the class. In the example, the X::X method is the constructor. This was deprecated in PHP 7.0, in favor of using the __construct method.
During the deprecation phase, the eponymous method was still used as the constructor, if the __construct method was not available.
Example
<?php
class X {
function X() {}
}
?>
Alternatives
- Rename the eponymous method to
__construct. - Crete the
__constructmethod, and make it call the eponymous method.
Missing format specifier at end of string
Description
This error is related to the parsing of the format string. In the first example, PHP finds two % characters, and expect each time to be followed by a format character. When the % is at the end of the string, there is no more character to parse, hence the error message.
Also, note the second illustration, which uses a dot . after the %. This is a padding character, so the parser set it aside, and then, look for the format character itself, while reaching the end of the line.
This error applies to printf(), sprintf(), vprintf(), vsprintf().
Example
<?php
printf('%s %', 'a', 'b');
printf('%s %.', 'a', 'b');
?>
Alternatives
- Add the missing format character at the end of the line.
- Remove the final % char in the format line.
- Add another % at the end of the line, to make it a literal % char in the format.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Modification of SplObjectStorage during getHash() is prohibited
Description
SplObjectStorage internals are not reentrant during hashing.
Example
<?php
class WatchfulStorage extends SplObjectStorage {
public SplObjectStorage $sideStorage;
public function getHash(object $object): string {
$this->sideStorage->offsetSet(new stdClass());
return spl_object_hash($object);
}
}
$watch = new WatchfulStorage();
$watch->sideStorage = new SplObjectStorage();
try {
$watch->offsetSet(new stdClass());
echo "offsetSet succeeded, sideStorage count=".count($watch->sideStorage)."\n";
} catch (\Error $e) {
echo "Error: ".$e->getMessage()."\n";
}
?>
Alternatives
- Do not change the object during hashing. Change it with another method call.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See splObjectStorageGetHashMutation86
Module “%s” is already loaded
Description
The current configuration of the PHP engine include twice the same extension. The first extension is loaded and the last extension is omitted. The features are available, and the log will be filled with the warning.
PHP uses several distinct files to list the extensions to load, such as php.ini, cond.d/*.ini, and the SAPI configuration files, including the web server, CLI’s php.ini, etc.
Example
Literal Examples
- Module “imagick” is already loaded
Alternatives
- Find the duplicate extension configuration and remove all of the, but one.
Related error messages
Multiple %s modifiers are not allowed
Description
A single modifier keyword (final, static, readonly, or a visibility keyword such as public, protected, private) is enough to apply that property to a class member. Repeating the same kind of modifier twice in a declaration is redundant and rejected by the parser.
This is a generic, templated message: the concrete modifier name takes the place of %s. There are dedicated, more specific messages for each modifier family: final, static, readonly, and the access-type (visibility) modifiers.
Example
<?php
class X {
final final function foo() {}
}
?>
Literal Examples
- Multiple final modifiers are not allowed
- Multiple static modifiers are not allowed
- Multiple readonly modifiers are not allowed
- Multiple access type modifiers are not allowed
Alternatives
- Remove the duplicate modifier, keeping only one occurrence.
Related error messages
- multiple-final-modifiers-are-not-allowed
- multiple-static-modifiers-are-not-allowed
- multiple-readonly-modifiers-are-not-allowed
- multiple-access-type-modifiers-are-not-allowed
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Multiple access type modifiers are not allowed
Description
Only one visibility option is necessary to set the visibility of a property. Two is overkill or could be impossible, so PHP reports it.
This message applies to private, protected and public options.
This message appears when compiling PHP 8.4+ code, with asymmetric visibility, against PHP 8.3 or older. In that case, protected(set) is not recognized as a token, and only the protected part is used, leading to the error.
There are similar messages for multiple readonly, or multiple static.
Example
<?php
class X {
private private static A $b;
}
class Y
{
public protected(set) string $name;
}
?>
Alternatives
- Drop the extra visibility, and keep only one.
- Compile with PHP 8.4 and more recent.
- Remove asymmetric visibility.
Related error messages
- multiple-static-modifiers-are-not-allowed
- multiple-readonly-modifiers-are-not-allowed
- multiple-%s-modifiers-are-not-allowed
Multiple final modifiers are not allowed
Description
One mention of the final option is sufficient to make a method so.
Example
<?php
class X {
final final function foo() {}
}
?>
Alternatives
- Keep only one mention of
final.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Multiple readonly modifiers are not allowed
Description
Only one readonly option is necessary to make a property read-only. Two is overkill, and not needed, so PHP reports it.
There are similar messages for multiple visibility, or multiple static.
Example
<?php
class X {
private readonly readonly A $b;
}
readonly readonly class Y {
}
?>
Alternatives
- Drop the extra readonly, and keep only one.
- Drop all the readonly options.
Related error messages
- multiple-static-modifiers-are-not-allowed
- multiple-access-type-modifiers-are-not-allowed
- multiple-%s-modifiers-are-not-allowed
Multiple static modifiers are not allowed
Description
Only one static option is necessary to make a property static. Two is overkill, and not needed, so PHP reports it.
There are similar messages for multiple readonly, or multiple static.
Multiple static on a closure or arrow function leads to a parse error.
Example
<?php
class X {
private static static A $b;
private static static function a() {}
}
static static function () {};
?>
Alternatives
- Drop the extra static, and keep only one.
- Drop all the static options.
Related error messages
- multiple-readonly-modifiers-are-not-allowed
- multiple-access-type-modifiers-are-not-allowed
- multiple-%s-modifiers-are-not-allowed
must be a bitmask of POSIX_F_OK, POSIX_R_OK, POSIX_W_OK, and POSIX_X_OK
Description
posix_access() checks whether the current process can access a file in a given way. Its $flags argument only accepts a bitmask built from POSIX_F_OK (existence), POSIX_R_OK (readable), POSIX_W_OK (writable), and POSIX_X_OK (executable).
As of PHP 8.6, passing a value with bits set outside of that set throws a ValueError, instead of forwarding an unvalidated flag value straight to the underlying access() system call.
Example
<?php
posix_access('/etc/passwd', 999);
?>
Literal Examples
- posix_access(): Argument #2 ($flags) must be a bitmask of POSIX_F_OK, POSIX_R_OK, POSIX_W_OK, and POSIX_X_OK
Alternatives
- Build
$flagsforposix_access()only out ofPOSIX_F_OK,POSIX_R_OK,POSIX_W_OK, andPOSIX_X_OK, combined with|as needed.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, an out-of-range $flags value was passed through to the underlying access() call unchecked instead of being rejected.](Previously, an out-of-range $flags value was passed through to the underlying access() call unchecked instead of being rejected.)
must be a callable, null given
Description
The PDOStatement::fetchAll() accepts a 2nd argument as a callback. That method processes the returning rows before they are returned by the method itself. By default, the method returns arrays, and doesn’t need the callback. When the callback is provided, it must be a valid callback, and, as such, can’t be null.
This error is the same as Argument #%d ($name) must be of type %s, %s given, but is specific to the PDO extension, and the PDOStatement::fetchAll(). The original problem is also the same.
Example
<?php
// Connection to the database
$db = new Pdo();
// Dummy valid SQL query
$stmt = $db->query('SELECT * FROM table');
try {
var_dump($stmt->fetchAll(PDO::FETCH_FUNC, NULL));
} catch (\Throwable $e) {
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
}
?>
Alternatives
- Remove the second
$callbackargument in the call to thePDOStatement::fetchAll()method. - Use a valid second
$callbackargument in the call to thePDOStatement::fetchAll()method.
Related error messages
must be a combination of MSG_OOB, MSG_PEEK, MSG_WAITALL, MSG_DONTWAIT, MSG_ERRQUEUE, and MSG_CMSG_CLOEXEC for AF_PACKET sockets
Description
PHP 8.6 adds raw AF_PACKET support to socket_recvfrom(). On a packet socket, only a finite subset of MSG_* flags is safe to use for receiving: MSG_OOB, MSG_PEEK, MSG_WAITALL, MSG_DONTWAIT, MSG_ERRQUEUE, and MSG_CMSG_CLOEXEC. Notably, MSG_TRUNC is excluded, since on a packet socket it makes recvfrom() report the untruncated frame length, which can exceed the supplied buffer.
Passing any flag outside this set on an AF_PACKET socket throws a ValueError, instead of risking a buffer-size mismatch.
Example
<?php
$socket = socket_create(AF_PACKET, SOCK_RAW, 0);
socket_recvfrom($socket, $data, 2048, MSG_TRUNC, $address, $port);
?>
Literal Examples
- socket_recvfrom(): Argument #4 ($flags) must be a combination of MSG_OOB, MSG_PEEK, MSG_WAITALL, MSG_DONTWAIT, MSG_ERRQUEUE, and MSG_CMSG_CLOEXEC for AF_PACKET sockets
Alternatives
- When calling
socket_recvfrom()on an AF_PACKET socket, only combine flags from MSG_OOB, MSG_PEEK, MSG_WAITALL, MSG_DONTWAIT, MSG_ERRQUEUE, and MSG_CMSG_CLOEXEC.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be a concrete class
Description
stream_wrapper_register() and stream_filter_register() associate a class name with a protocol (or filter) name; the streams layer instantiates that class itself whenever the protocol is opened or the filter is applied. Passing an abstract class, or an interface, means there is nothing the streams layer could ever instantiate.
Previously, this only failed later, when PHP actually tried to open a stream using the unusable class. As of PHP 8.6, both functions check that the class is instantiable up front and throw immediately, instead of registering a class that is guaranteed to fail on first use.
Example
<?php
abstract class MyProtocol {}
stream_wrapper_register('myproto', MyProtocol::class);
?>
Literal Examples
- stream_wrapper_register(): Argument #2 ($class) must be a concrete class
Alternatives
- Register a concrete (non-abstract) class that implements the expected stream wrapper or filter interface.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be a finite value
Description
This error is raised when a parameter was provided with an infinite value.
Infinite values are generated by maths functions such as atan or log, and also with the INF and NAN constants. Infinite values are considered to be typed float.
For example, stream_socket_client() and stream_socket_accept() require a $timeout parameter, and it is tempting, but not valid, to provide INF.
Example
<?php
$fp = stream_socket_client(tcp://www.example.com:80, $errno, $errstr, INF);
?>
Alternatives
- Use a very large, but finite float value, such as
PHP_FLOAT_MAX, which will be valid until the end of the universe, even in nanoseconds.
Related error messages
must be a list array
Description
This error is reported when the provided list of parameters, in mysqli_stmt_execute() or mysqli::stmt_execute() is not a list: the index must start at 0, and be auto-generated.
Example
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');
mysqli_query($link, 'CREATE TEMPORARY TABLE myCity LIKE City');
/* Prepare an insert statement */
$stmt = mysqli_prepare($link, 'INSERT INTO myCity (Name, CountryCode, District) VALUES (?,?,?)');
$val1 = 'Stuttgart';
$val2 = 'DEU';
$val3 = 'Baden-Wuerttemberg';
/* Execute the statement */
mysqli_stmt_execute($stmt, [$val1, $val2, 'val' => $val3]);
?>
Alternatives
- Check that no index is explicitly named in the array of parameters.
- Apply array_values() to make the array a list.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be a list of %s
Description
Uri\WhatWg\InvalidUrlException::__construct() accepts an $errors argument describing every WHATWG URL validation failure that occurred. That argument must be a list (contiguous, zero-based keys) whose every value is an instance of Uri\WhatWg\UrlValidationError. Any other array shape — associative keys, non-sequential indices, or elements that are not UrlValidationError objects — is rejected with this ValueError.
Example
<?php
new Uri\WhatWg\InvalidUrlException(
'bad url',
['not a validation error object'],
);
?>
Literal Examples
- Uri\WhatWg\InvalidUrlException::__construct(): Argument #2 ($errors) must be a list of Uri\WhatWg\UrlValidationError
Alternatives
- Pass an array of
Uri\WhatWg\UrlValidationErrorinstances only, built witharray_values()if it might have gaps or string keys. - Let the WHATWG URL parser construct and throw this exception itself, rather than constructing it manually.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be a multiple of argument #2 ($word_size)
Description
The second option of gmp_import() configures the number of bytes to take in the string to build the number. Each GMP digit will be read over $word_size characters. When the string has a length that is not a multiple of the size of each word, GMP will run short of a few bytes, and emits the error.
Example
<?php
gmp_import('aa', 3);
?>
Literal Examples
- Argument #1 ($data) must be a multiple of argument #2 ($word_size)
Alternatives
- Check that the string length is a multiple of the 2nd argument of
gmp_import(). - Use a word length that is a factor of the string length.
- Use a word length of 1, which works all the time, yet may not yield the expected result.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be a user-defined class name, internal class name given
Description
class_alias() creates an alias for a class, an enumeration, an interface or a trait. Until PHP 8.3, it was only possible to create such aliases with custom structures, and it was not possible to do it with PHP native classes.
Example
<?php
class_alias(stdClass::class, MyClass::Class);
?>
Alternatives
- Upgrade to PHP 8.3 or more recent.
- Create a class that extends the PHP native class, and create an alias on this custom class.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See classAliasWithInternalClass
must be a valid charset
Description
This is a Windows only error. It is related to converting a string to another encoding, and failing. No information is available about it.
Example
Alternatives
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be a valid class name, %s given
Description
get_parent_class() expects an argument, which must be either an object, or a valid class name. The object’s class name will be used; for the valid class name, it is recommended to use the ::class operator on the class name, and also, to check if the class exists first.
Example
<?php
$a = 1;
get_parent_class($a);
?>
Literal Examples
- must be a valid class name, null given
- must be a valid class name, integer given
Alternatives
- Check that the parameter is an object.
- Make the string a valid class name, with the
::classoperator. - Check if the string is an existing class, with a call to
class_exists().
must be a valid comparison operator
Description
version_compare() compares version strings, using an operator, passed as third parameter. Until PHP 8.1, unknown operators are ignored, and use the default value.
Nowadays, it is generating a fatal error.
Valid operators are : <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne
Note that the 3rd parameter is case sensitive, so NE also yields the error.
Example
<?php
version_compare('1.2.4', '1.2.3', '?');
?>
Alternatives
- Use a valid operator.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See version_compare
must be a valid context engine ID
Description
SNMP::setSecurity()’s $contextEngineId argument is expected to be a hex-encoded SNMPv3 context engine ID, which the extension decodes back to raw bytes before handing it to the underlying Net-SNMP session.
As of PHP 8.6, a value that cannot be decoded as hex throws a ValueError, instead of silently leaving the context engine ID unset on the session.
Example
<?php
$snmp = new SNMP(SNMP::VERSION_3, 'localhost', 'user');
$snmp->setSecurity('authPriv', 'SHA', 'authpass', 'AES', 'privpass', '', 'not-hex');
?>
Literal Examples
- SNMP::setSecurity(): Argument #7 ($contextEngineId) must be a valid context engine ID
Alternatives
- Pass a valid hex-encoded string as the $contextEngineId argument to SNMP::setSecurity(), or omit it to leave the context engine ID unset.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, this emitted an E_WARNING (“Bad engine ID value ‘%s’”) and left the context engine ID unset, instead of throwing.](Previously, this emitted an E_WARNING (“Bad engine ID value ‘%s’”) and left the context engine ID unset, instead of throwing.)
must be a valid encoding, “%s” given
Description
The encoding arguments, in any mb_ function, must be a supported encoding. Otherwise, the mbstring extension doesn’t know how to handle it.
The current list of encodings is available with the function mb_list_encodings(). Encoding names are case insensitive.
The list of supported encoding depends on the PHP version. Some are added or removed, depending on the version.
Example
<?php
print mb_chr(128024, 'UTF-8')); // emoji of an elephant
//Argument #2 ($encoding) must be a valid encoding, "elephpant" given
print mb_chr($value, 'elephpant'));
?>
Literal Examples
- must be a valid encoding, “qprint” given
- must be a valid encoding, “uuencode” given
Alternatives
- Check the encoding with mb_list_encodings() before using one.
must be a valid method name
Description
The ReflectionMethod requires a method name to be instantiated. It is recommended to specify it with 2 arguments, the first being the class, or one of its objects, and the second being the method name.
When only one argument is provided, the string must have the class::method format.
Example
<?php
$method = new ReflectionMethod('c');
?>
Alternatives
- Use two arguments to call this method.
- Use the correct format to reprsent a method in a string.
Related error messages
must be a valid normalization form
Description
Normalizer::normalize() and Normalizer::isNormalized() accept a $form argument built from ICU’s Unicode normalization forms: Normalizer::FORM_D, ::FORM_KD, ::FORM_C (the default), ::FORM_KC, or ::FORM_KC_CF. Any other integer does not correspond to a form ICU knows how to normalize to.
This has thrown a ValueError since PHP 8.0; PHP 8.6 only corrected a typo in the message text itself, which previously doubled the word “a”.
Example
<?php
Normalizer::normalize('café', 999);
?>
Literal Examples
- Normalizer::normalize(): Argument #2 ($form) must be a valid normalization form
- Normalizer::isNormalized(): Argument #2 ($form) must be a valid normalization form
Alternatives
- Pass one of Normalizer::FORM_D, ::FORM_KD, ::FORM_C, ::FORM_KC, or ::FORM_KC_CF as the $form argument.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [PHP 8.0 through 8.5 threw the same ValueError but with a typo in the message: “must be a a valid normalization form” (doubled “a”).](PHP 8.0 through 8.5 threw the same ValueError but with a typo in the message: “must be a a valid normalization form” (doubled “a”).)
must be a valid rounding mode (RoundingMode::*)
Description
PHP has 4 rounding modes, to be used with the round() native function. They are PHP_ROUND_HALF_UP, PHP_ROUND_HALF_DOWN, PHP_ROUND_HALF_EVEN, PHP_ROUND_HALF_ODD; there is also RoundingMode and its cases : RoundingMode::HalfAwayFromZero, RoundingMode::HalfTowardsZero, RoundingMode::HalfEven, RoundingMode::HalfOdd, RoundingMode::TowardsZero, RoundingMode::AwayFromZero, RoundingMode::NegativeInfinity, RoundingMode::PositiveInfinity.
Any value that is not typed RoundingMode or is typed int but outside the 4 supported values and the default behavior of 0, produces this error message. In particular, false and null are not
Although the error message recommends using RoundingMode, the historical PHP_ROUND_* are still valid. It might be wise to start migrating to the new enumeration.
The GMP rounding function (via gmp_div_q()) works as previously. BCmath has no rounding function.
Example
<?php
// Generates the error
print $a = round(1.2, 2, 333);
// Generates the error
print $a = round(1.2, 2, 0);
// Generates the error
print $a = round(1.2, 2, false);
?>
Alternatives
- Use a valid enum case to configure the round() function.
- Use a valid PHP_ROUND_* constant to configure the round() function.
- Remove the 3rd parameter altogether: this means using PHP_ROUND_HALF_UP.
must be between 1 and %lu
Description
gmp_root() and gmp_rootrem() compute the integer part of the $nth root of $num. Internally, $nth is passed to GMP as an unsigned long, so it must be at least 1 and cannot exceed the platform’s ULONG_MAX.
As of PHP 8.6, an $nth outside this range throws a ValueError naming the exact upper bound, instead of only rejecting non-positive values and letting an oversized $nth overflow when narrowed to an unsigned long.
Example
<?php
gmp_root('27', PHP_INT_MAX);
?>
Literal Examples
- gmp_root(): Argument #2 ($nth) must be between 1 and 18446744073709551615
- gmp_rootrem(): Argument #2 ($nth) must be between 1 and 18446744073709551615
Alternatives
- Pass an $nth argument to gmp_root()/gmp_rootrem() between 1 and PHP_INT_MAX (or the platform’s ULONG_MAX, whichever is smaller).
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, gmp_root() rejected only $nth <= 0 (“must be greater than 0”) and gmp_rootrem() rejected only $nth < 1 (“must be greater than or equal to 1”), without an upper bound.](Previously, gmp_root() rejected only $nth <= 0 (“must be greater than 0”) and gmp_rootrem() rejected only $nth < 1 (“must be greater than or equal to 1”), without an upper bound.)
must be between 1 and 7
Description
When processing days of the week as an integers, the days are represented by the integers from 1 (Monday) to 7 (Sunday). Other values are non used, and are reported as faulty.
Example
<?php
$c = new IntlGregorianCalendar(NULL, 'pt_PT');
try {
var_dump($c->setMinimalDaysInFirstWeek(0));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
?>
Alternatives
- Use an integer with a value between 1 and 7.
%s(): Argument #%d ($%s) must be contained in argument #%d ($%s)
Description
strpos() searches for a string called $needle in another string called $haystack, starting at the offset passed as third argument, and called $offset.
The offset must be smaller than the full length of the $haystack: otherwise, PHP starts to search beyond the end of the data, and that will always fail.
This error message is shared by several PHP native and extension functions, namely mbstring and iconv: strpos(), strrpos(), stripos(), strripos(), mb_strpos(), mb_strrpos(), mb_stripos(), mb_strripos(), iconv_strpos and iconv_strrpos.
Before PHP 8.0, the failure was reported as a non-blocking warning. Since PHP 8.0, it is a fatal error.
Example
<?php
var_dump(strpos('abc', 'a', 4));
?>
Literal Examples
- strpos(): Argument #3 ($offset) must be contained in argument #1 ($haystack)
Alternatives
- Check that the offset is not beyond the length of the string.
- Use a try catch around this methodcall.
- Lengthen the source string.
In previous PHP versions, this error message used to be :ref:offset-not-contained-in-string..
must be either CASE_LOWER or CASE_UPPER
Description
array_change_key_case() converts every string key of an array to either all-lowercase or all-uppercase. Its second argument only accepts two values: CASE_LOWER (the default) or CASE_UPPER.
Previously, passing any other integer was silently treated as CASE_LOWER. As of PHP 8.6, the function validates the argument up front and throws a ValueError for anything else, instead of quietly falling back to the default.
Example
<?php
$array = ['FOO' => 1, 'BAR' => 2];
array_change_key_case($array, 2);
?>
Literal Examples
- array_change_key_case(): Argument #2 ($case) must be either CASE_LOWER or CASE_UPPER
Alternatives
- Pass either
CASE_LOWERorCASE_UPPERas the second argument toarray_change_key_case().
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
[Previously, any value other than CASE_UPPER was silently treated as CASE_LOWER.](Previously, any value other than CASE_UPPER was silently treated as CASE_LOWER.)
must be either Spoofchecker::LTR or Spoofchecker::RTL
Description
PHP 8.6 adds Spoofchecker::getBidiSkeleton() and Spoofchecker::areBidiConfusable(), which compute (or compare) the visual skeleton of a string for a given text direction, used to detect visually-confusable identifiers that mix left-to-right and right-to-left scripts. Both methods take a $direction argument that only accepts two values: Spoofchecker::LTR or Spoofchecker::RTL.
Passing any other integer raises a ValueError, since ICU’s bidi skeleton algorithm only knows how to reason about text in one of these two directions.
Example
<?php
$checker = new Spoofchecker();
$checker->getBidiSkeleton(99, 'paypal');
?>
Literal Examples
- Spoofchecker::getBidiSkeleton(): Argument #1 ($direction) must be either Spoofchecker::LTR or Spoofchecker::RTL
- Spoofchecker::areBidiConfusable(): Argument #1 ($direction) must be either Spoofchecker::LTR or Spoofchecker::RTL
Alternatives
- Pass either
Spoofchecker::LTRorSpoofchecker::RTLas the$directionargument.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be empty when class provided in argument #1 ($class) does not have a constructor
Description
The class referenced in the PDO::fetchObject method does not have a constructor. No argument will be handed to it, so there is no need to pass that argument.
Example
<?php
class X
{
public $id;
protected $val;
private $val2;
}
$stmt->execute(); // STMT is a PDO statement
try {
var_dump($stmt->fetchObject(X::class, [0]));
} catch (\Throwable $e) {
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
}
?>
Alternatives
- Omit the second argument.
- Use an empty array for the second argument.
- Use a null value for the second argument.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be empty when class provided in argument #2 ($class) does not have a constructor
Description
The class referenced in the PDO::fetchAll method does not have a constructor. No argument will be handed to it, so there is no need to pass that argument.
Example
<?php
class X
{
public $id;
protected $val;
private $val2;
}
$stmt->execute(); // STMT is a PDO statement
try {
var_dump($stmt->fetchAll(PDO::FETCH_CLASS, X::class, [0]));
} catch (\Throwable $e) {
echo $e::class, ': ', $e->getMessage(), \PHP_EOL;
}
?>
Alternatives
- Omit the third argument.
- Use an empty array for the third argument.
- Use a null value for the third argument.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be greater than 0
Description
This error is reported when a parameter is expected to be an integer, strictly positive. This is the case with the second argument of str_split().
Example
<?php
str_split('abc', 0);
?>
Literal Examples
- str_split(): Argument #2 ($length) must be greater than 0
Alternatives
- Use a valid value for the parameter: a positive and non zero integer, for example 1, 2, 3…
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be greater than or equal to 1
Description
The second argument of gmp_import() is the number of characters to read in the original string, to build a GMP digit. This size must be 1 or larger, and the string’s length must be a multiple of that number.
Example
<?php
gmp_import('11', -2);
?>
Literal Examples
- Argument #2 ($word_size) must be greater than or equal to 1
Alternatives
- Use the default value of 1, by omitting it.
- Use a postive number as second argument.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be less than 4294967295 bytes
Description
sodium_crypto_pwhash() and sodium_crypto_pwhash_str() derive a key, or a storable hash, from a password using the Argon2 algorithm. Internally, libsodium tracks the length of the password (and of the derived key or salt) in a 32-bit unsigned integer, so any input of 4294967295 bytes (2^32 - 1) or more cannot be represented and can never be processed.
As of PHP 8.6, these out-of-range length checks throw a ValueError naming the offending argument. Earlier versions threw a generic SodiumException instead for the same underlying condition.
Example
<?php
$hash = sodium_crypto_pwhash_str(str_repeat('a', 4294967295), SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE);
?>
Literal Examples
- sodium_crypto_pwhash_str(): Argument #1 ($password) must be less than 4294967295 bytes
Alternatives
- Do not pass passwords, salts or derived keys anywhere near 4 GB in size; hash a digest of the material instead if it is genuinely that large.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be less than argument #2 ($max)
Description
gmp_random_range() returns a random GMP number in the inclusive range [$min, $max]. That range only makes sense when $min is strictly less than $max.
This has thrown a ValueError for a non-positive range since PHP 8.0; PHP 8.6 only corrected the argument name referenced in the message, from the stub’s actual parameter name $max (it previously said $maximum, which never matched the real signature).
Example
<?php
gmp_random_range(10, 5);
?>
Literal Examples
- gmp_random_range(): Argument #1 ($min) must be less than argument #2 ($max)
Alternatives
- Make sure $min is strictly less than $max when calling gmp_random_range().
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [PHP 8.0 through 8.5 threw the same ValueError but referenced the second argument as “$maximum”, which did not match the function’s actual $max parameter name.](PHP 8.0 through 8.5 threw the same ValueError but referenced the second argument as “$maximum”, which did not match the function’s actual $max parameter name.)
must be MYSQLI_INIT_COMMAND, MYSQLI_SET_CHARSET_NAME, MYSQLI_SERVER_PUBLIC_KEY, or one of the MYSQLI_OPT_* constants
Description
mysqli_options() (and mysqli::options()) only understand a fixed set of option constants: MYSQLI_INIT_COMMAND, MYSQLI_SET_CHARSET_NAME, MYSQLI_SERVER_PUBLIC_KEY, and the various MYSQLI_OPT_* constants. Each of these expects a specific value type (string, bool or int), which the function needs to know in order to validate and forward the value correctly.
Before PHP 8.6, passing an option value that mysqli_options() did not recognize was silently ignored: the call returned false without telling the caller why. As of PHP 8.6, an unrecognized option now throws a ValueError instead.
Example
<?php
$mysqli = mysqli_init();
mysqli_options($mysqli, 999999, true);
?>
Literal Examples
- mysqli_options(): Argument #2 ($option) must be MYSQLI_INIT_COMMAND, MYSQLI_SET_CHARSET_NAME, MYSQLI_SERVER_PUBLIC_KEY, or one of the MYSQLI_OPT_* constants
Alternatives
- Pass one of the documented
MYSQLI_INIT_COMMAND,MYSQLI_SET_CHARSET_NAME,MYSQLI_SERVER_PUBLIC_KEYorMYSQLI_OPT_*constants as the option argument.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be no longer than %d characters
Description
IntlNumberRangeFormatter::createFromSkeleton()’s $locale argument is validated against ICU’s internal locale-name length limit before being parsed, the same limit enforced elsewhere across the intl extension.
Passing a $locale string longer than that limit throws a ValueError, instead of handing an oversized buffer to ICU’s locale parser.
Example
<?php
IntlNumberRangeFormatter::createFromSkeleton(
'',
str_repeat('a', 200),
IntlNumberRangeFormatter::COLLAPSE_AUTO,
IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE
);
?>
Literal Examples
- IntlNumberRangeFormatter::createFromSkeleton(): Argument #2 ($locale) must be no longer than 156 characters
Alternatives
- Use a locale identifier no longer than ICU’s maximum locale length (156 characters) when calling IntlNumberRangeFormatter::createFromSkeleton().
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be odd if argument #1 ($num) is negative
Description
gmp_root() and gmp_rootrem() compute the integer part of the $nth root of $num. A negative number only has a real $nth root when $nth is odd (for example, the cube root of -27 is -3), so an even $nth combined with a negative $num has no meaningful integer result.
This validation has thrown a ValueError since PHP 8.0; PHP 8.6 only corrected the argument name referenced in the message, from the stub’s actual parameter name $num (it previously said $a, which never matched the real signature).
Example
<?php
gmp_root(-27, 4);
?>
Literal Examples
- gmp_root(): Argument #2 ($nth) must be odd if argument #1 ($num) is negative
- gmp_rootrem(): Argument #2 ($nth) must be odd if argument #1 ($num) is negative
Alternatives
- Only request an even $nth root of a negative $num if you actually mean a complex result; otherwise pass a non-negative $num or an odd $nth to gmp_root()/gmp_rootrem().
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [PHP 8.0 through 8.5 threw the same ValueError but referenced the first argument as “$a”, which did not match the function’s actual $num parameter name.](PHP 8.0 through 8.5 threw the same ValueError but referenced the first argument as “$a”, which did not match the function’s actual $num parameter name.)
must be of type %s, %s given
Description
This error message reports that the types of the provided arguments are not compatible with the expected types.
Such a conflict appears in various situations:
- a scalar type is used when another incompatible type is expected: using an array instead of a integer.
- a compatible type is provided when strict_types is active: for example, using a numeric string or a stringable object with a
stringtype. - a parent class is used where a child type is expected: object types accept child classes, not parent ones.
- the type is an interface, and the provided object is not implementing it explicitly
- the type has a typo
- the type should is not the one that is the specifications.
Example
<?php
function foo(int $i) {}
foo([]);
// with strict_types = 1
foo(1.0);
class A {}
class B extends A {}
function goo(B $b) {}
goo(new A);
?>
Literal Examples
- must be of type Traversable, int given
- must be of type int, array given
- must be of type int, float given
- must be of type A, B given
Alternatives
- Remove the type.
- Fix the parameter type.
- Fix the argument type: convert it to the expected type.
Related error messages
must be of type array when argument #3 ($option) is MCAST_LEAVE_GROUP, %s given
Description
When $option is MCAST_LEAVE_GROUP, socket_set_option() expects $value (argument #4) to be an array (or an object, read as a property bag) describing the group to leave — with keys such as group and interface. Passing anything else, such as the plain string above, is rejected before the request ever reaches the underlying setsockopt() call.
Example
<?php
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($socket, IPPROTO_IP, MCAST_LEAVE_GROUP, 'not-an-array');
?>
Literal Examples
- socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is MCAST_LEAVE_GROUP, string given
Alternatives
- Pass an array with the
group(and, where applicable,interface) keys expected for MCAST_LEAVE_GROUP. - Consult the socket_set_option() documentation for the exact shape expected for this option.
Related error messages
In more recent PHP versions, this error message is now :ref:must-be-of-type-array-when-argument-#3-($option)-is-mcast_leave_source_group,-%s-given.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be of type array when argument #3 ($option) is MCAST_LEAVE_SOURCE_GROUP, %s given
Description
When $option is MCAST_LEAVE_SOURCE_GROUP, socket_set_option() expects $value (argument #4) to be an array (or an object, read as a property bag) describing the source-specific multicast group to leave — with keys such as group, source and interface. Passing anything else, such as the plain string above, is rejected before the request ever reaches the underlying setsockopt() call.
Example
<?php
$socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
socket_set_option($socket, IPPROTO_IP, MCAST_LEAVE_SOURCE_GROUP, 'not-an-array');
?>
Literal Examples
- socket_set_option(): Argument #4 ($value) must be of type array when argument #3 ($option) is MCAST_LEAVE_SOURCE_GROUP, string given
Alternatives
- Pass an array with the
group,sourceandinterfacekeys expected for MCAST_LEAVE_SOURCE_GROUP. - Consult the socket_set_option() documentation for the exact shape expected for this option.
Related error messages
In previous PHP versions, this error message used to be :ref:must-be-of-type-array-when-argument-#3-($option)-is-mcast_leave_group,-%s-given.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be of type Countable|array, %s given
Description
The count() native function only count elements that are arrays, or objects that implements the Countable interface. Anything else yields a fatal error.
Example
<?php
$value = null;
echo count($value);
?>
Alternatives
- Check for type before using count:
is_arrayorinstanceof \Countable.
In previous PHP versions, this error message used to be :ref:parameter-must-be-an-array-or-an-object-that-implements-countable.
must be of type string when argument #3 ($option) is FIL_ATTACH or FIL_DETACH, %s given
Description
FIL_ATTACH and FIL_DETACH (used with the SOL_FILTER level, on platforms that support BSD accept/receive filters) name the filter to attach or detach as a string. socket_set_option() requires $value (argument #4) to be a string for these two options; any other type, such as the integer above, is rejected.
Example
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_FILTER);
socket_set_option($socket, SOL_FILTER, FIL_ATTACH, 123);
?>
Literal Examples
- socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is FIL_ATTACH or FIL_DETACH, int given
Alternatives
- Pass the filter name as a string.
- Consult your platform’s setsockopt(2)/SOL_FILTER documentation for valid filter names.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be of type string when argument #3 ($option) is SO_ACCEPTFILTER, %s given
Description
SO_ACCEPTFILTER (available on BSD-derived systems such as FreeBSD) names an accept filter by a short string, e.g. "dataready". socket_set_option() requires $value (argument #4) to be a string for this option; any other type, such as the integer above, is rejected. Note that the string must also be shorter than the platform’s internal filter-name buffer and must not contain a null byte, which are reported as separate ValueError cases.
Example
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_ACCEPTFILTER, 123);
?>
Literal Examples
- socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is SO_ACCEPTFILTER, int given
Alternatives
- Pass the accept filter name as a short string, without embedded null bytes.
- Consult your platform’s accf(9)/setsockopt(2) documentation for valid filter names.
Related error messages
- must-be-of-type-string-when-argument-#3-($option)-is-so_bindtodevice,-%s-given
- must-be-of-type-string-when-argument-#3-($option)-is-fil_attach-or-fil_detach,-%s-given
In more recent PHP versions, this error message is now :ref:must-be-of-type-string-when-argument-#3-($option)-is-so_bindtodevice,-%s-given.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be of type string when argument #3 ($option) is SO_BINDTODEVICE, %s given
Description
SO_BINDTODEVICE (Linux) binds a socket to a specific network interface, identified by its name, e.g. "eth0". socket_set_option() requires $value (argument #4) to be a string for this option; any other type, such as the integer above, is rejected.
Example
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_BINDTODEVICE, 123);
?>
Literal Examples
- socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is SO_BINDTODEVICE, int given
Alternatives
- Pass the network interface name as a string.
- Use php_uname() or /sys/class/net to discover the correct interface name if unsure.
Related error messages
- must-be-of-type-string-when-argument-#3-($option)-is-so_acceptfilter,-%s-given
- must-be-of-type-string-when-argument-#3-($option)-is-tcp_congestion,-%s-given
In previous PHP versions, this error message used to be :ref:must-be-of-type-string-when-argument-#3-($option)-is-so_acceptfilter,-%s-given.
In more recent PHP versions, this error message is now :ref:must-be-of-type-string-when-argument-#3-($option)-is-tcp_congestion,-%s-given.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be of type string when argument #3 ($option) is TCP_CONGESTION, %s given
Description
TCP_CONGESTION selects the congestion-control algorithm for a TCP socket, by name, e.g. "cubic" or "bbr". socket_set_option() requires $value (argument #4) to be a string for this option; any other type, such as the integer above, is rejected.
Example
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, IPPROTO_TCP, TCP_CONGESTION, 123);
?>
Literal Examples
- socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is TCP_CONGESTION, int given
Alternatives
- Pass the congestion-control algorithm name as a string.
- List available algorithms via
/proc/sys/net/ipv4/tcp_available_congestion_controlon Linux.
Related error messages
- must-be-of-type-string-when-argument-#3-($option)-is-so_bindtodevice,-%s-given
- must-be-of-type-string-when-argument-#3-($option)-is-tcp_function_blk,-%s-given
In previous PHP versions, this error message used to be :ref:must-be-of-type-string-when-argument-#3-($option)-is-so_bindtodevice,-%s-given.
In more recent PHP versions, this error message is now :ref:must-be-of-type-string-when-argument-#3-($option)-is-tcp_function_blk,-%s-given.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be of type string when argument #3 ($option) is TCP_FUNCTION_BLK, %s given
Description
TCP_FUNCTION_BLK (FreeBSD only) selects the pluggable TCP stack to use for a connection, identified by its name. socket_set_option() requires $value (argument #4) to be a string for this option; any other type, such as the integer above, is rejected. The string must also be free of null bytes and shorter than the platform’s TCP_FUNCTION_NAME_LEN_MAX, which are reported as separate ValueError cases.
Example
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, IPPROTO_TCP, TCP_FUNCTION_BLK, 123);
?>
Literal Examples
- socket_set_option(): Argument #4 ($value) must be of type string when argument #3 ($option) is TCP_FUNCTION_BLK, int given
Alternatives
- Pass the TCP stack name as a string, without embedded null bytes.
- List available stacks via
net.inet.tcp.functions_availableon FreeBSD.
Related error messages
In previous PHP versions, this error message used to be :ref:must-be-of-type-string-when-argument-#3-($option)-is-tcp_congestion,-%s-given.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be one of ARRAY_FILTER_USE_VALUE, ARRAY_FILTER_USE_KEY, or ARRAY_FILTER_USE_BOTH
Description
array_filter() uses its third argument, $mode, to decide what the callback receives: the value (ARRAY_FILTER_USE_VALUE, the default), the key (ARRAY_FILTER_USE_KEY), or both (ARRAY_FILTER_USE_BOTH). No other mode makes sense, since the callback’s signature is chosen based on exactly one of these three constants.
Before PHP 8.6, passing any other integer for $mode was silently treated as ARRAY_FILTER_USE_VALUE. As of PHP 8.6, an unrecognized mode now throws a ValueError instead of falling back silently.
Example
<?php
$array = ['a' => 1, 'b' => 2];
array_filter($array, fn($v) => $v > 0, 42);
?>
Literal Examples
- array_filter(): Argument #3 ($mode) must be one of ARRAY_FILTER_USE_VALUE, ARRAY_FILTER_USE_KEY, or ARRAY_FILTER_USE_BOTH
Alternatives
- Pass one of
ARRAY_FILTER_USE_VALUE,ARRAY_FILTER_USE_KEY, orARRAY_FILTER_USE_BOTHas the$modeargument toarray_filter().
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
[Previously, any unrecognized $mode value was silently treated as ARRAY_FILTER_USE_VALUE.](Previously, any unrecognized $mode value was silently treated as ARRAY_FILTER_USE_VALUE.)
must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, ::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, ::IDENTITY_FALLBACK_APPROXIMATELY, or ::IDENTITY_FALLBACK_RANGE
Description
IntlNumberRangeFormatter::createFromSkeleton() builds a formatter for numeric ranges (such as 3-5). Its identityFallback argument tells ICU what to do when the range’s start and end turn out to be identical after formatting, and only four such fallback strategies exist: IDENTITY_FALLBACK_SINGLE_VALUE, IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IDENTITY_FALLBACK_APPROXIMATELY, and IDENTITY_FALLBACK_RANGE.
Passing any other integer raises a ValueError, since ICU’s range formatter has no other identity-fallback behavior to fall back to.
Example
<?php
IntlNumberRangeFormatter::createFromSkeleton(
'',
'en',
IntlNumberRangeFormatter::COLLAPSE_AUTO,
999
);
?>
Literal Examples
- IntlNumberRangeFormatter::createFromSkeleton(): Argument #4 ($identityFallback) must be one of IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY, or IntlNumberRangeFormatter::IDENTITY_FALLBACK_RANGE
Alternatives
- Pass one of
IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE,::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE,::IDENTITY_FALLBACK_APPROXIMATELY, or::IDENTITY_FALLBACK_RANGEas theidentityFallbackargument.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be one of PGSQL_ASSOC, PGSQL_NUM, or PGSQL_BOTH
Description
pg_fetch_all() 2nd argument must be one of 3 possible pgsql constants: PGSQL_ASSOC, PGSQL_NUM and PGSQL_BOTH.
It is also the case of pg_fetch_array() and pg_fetch_row()’s 3rd argument; and pg_select()’s 4th argument.
It is possible to use raw integers, instead of the constants, although this is not recommended.
Example
<?php
try {
var_dump(pg_last_notice($db, 99));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
?>
Alternatives
- Use one of the three constants.
Related error messages
must be one of PGSQL_NOTICE_LAST, PGSQL_NOTICE_ALL, or PGSQL_NOTICE_CLEAR
Description
pg_last_notice() 2nd argument must be one of 3 possible pgsql constants: PGSQL_NOTICE_LAST, PGSQL_NOTICE_ALL, or PGSQL_NOTICE_CLEAR.
It is possible to use raw integers, instead of the constants, although this is not recommended.
Example
<?php
try {
var_dump(pg_last_notice($db, 99));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
?>
Alternatives
- Use one of the three constants.
Related error messages
must be one of the PATHINFO_* constants
Description
pathinfo() takes an optional $flags argument built from the PATHINFO_DIRNAME, PATHINFO_BASENAME, PATHINFO_EXTENSION, PATHINFO_FILENAME, and PATHINFO_ALL constants, describing which parts of the path to return.
Previously, passing a value outside this set was silently accepted and produced an empty (or nonsensical) result. As of PHP 8.6, pathinfo() validates that $flags is actually built from these constants and throws a ValueError otherwise, instead of silently returning incomplete information.
Example
<?php
pathinfo('/tmp/example.txt', 9999);
?>
Literal Examples
- pathinfo(): Argument #2 ($flags) must be one of the PATHINFO_* constants
Alternatives
- Only pass a combination of
PATHINFO_DIRNAME,PATHINFO_BASENAME,PATHINFO_EXTENSION,PATHINFO_FILENAME, orPATHINFO_ALLas the$flagsargument.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
[Previously, an invalid $flags value was silently accepted and returned incomplete or empty results instead of throwing.](Previously, an invalid $flags value was silently accepted and returned incomplete or empty results instead of throwing.)
must be one of the SCANDIR_SORT_ASCENDING, SCANDIR_SORT_DESCENDING, or SCANDIR_SORT_NONE constants
Description
scandir() takes an optional $sorting_order argument controlling how the returned directory listing is sorted: SCANDIR_SORT_ASCENDING (the default), SCANDIR_SORT_DESCENDING, or SCANDIR_SORT_NONE.
Before PHP 8.6, passing any other integer silently fell through to one of these behaviors without warning. As of PHP 8.6, an unrecognized sorting order now throws a ValueError naming the offending argument.
Example
<?php
scandir('/tmp', 42);
?>
Literal Examples
- scandir(): Argument #2 ($sorting_order) must be one of the SCANDIR_SORT_ASCENDING, SCANDIR_SORT_DESCENDING, or SCANDIR_SORT_NONE constants
Alternatives
- Pass one of
SCANDIR_SORT_ASCENDING,SCANDIR_SORT_DESCENDING, orSCANDIR_SORT_NONEas the$sorting_orderargument toscandir().
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
[Previously, an unrecognized $sorting_order value was silently accepted instead of throwing.](Previously, an unrecognized $sorting_order value was silently accepted instead of throwing.)
must be only one of the PATHINFO_* constants
Description
Unlike most bitmask arguments, pathinfo()’s $flags argument (aside from the catch-all PATHINFO_ALL) is meant to select exactly one part of the path at a time: PATHINFO_DIRNAME, PATHINFO_BASENAME, PATHINFO_EXTENSION, or PATHINFO_FILENAME. Combining two of them with | does not make sense, since the function then wouldn’t know which single value to return.
As of PHP 8.6, combining more than one of these single-part constants (without using PATHINFO_ALL) throws a ValueError, instead of silently returning just one of the requested parts.
Example
<?php
pathinfo('/tmp/example.txt', PATHINFO_DIRNAME | PATHINFO_EXTENSION);
?>
Literal Examples
- pathinfo(): Argument #2 ($flags) must be only one of the PATHINFO_* constants
Alternatives
- Pass exactly one of
PATHINFO_DIRNAME,PATHINFO_BASENAME,PATHINFO_EXTENSION, orPATHINFO_FILENAME, or usePATHINFO_ALLto get all of them as an array.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, combining multiple single-part PATHINFO_* constants silently returned only one of the requested parts instead of throwing.](Previously, combining multiple single-part PATHINFO_* constants silently returned only one of the requested parts instead of throwing.)
must be OPENSSL_ENCODING_DER or OPENSSL_ENCODING_PEM
Description
PHP 8.6 introduces Openssl\Session, a class representing a TLS session that can be exported and later re-imported to resume a connection without a full handshake. Both Openssl\Session::export() and the static Openssl\Session::import() take a $format argument describing how the session data is encoded, but only two encodings are supported: OPENSSL_ENCODING_DER and OPENSSL_ENCODING_PEM.
Passing any other integer as the format raises a ValueError, since there is no other encoding these methods know how to produce or parse.
Example
<?php
$session = Openssl\Session::import('previously-exported-session-data', 999);
?>
Literal Examples
- Openssl\Session::import(): Argument #2 ($format) must be OPENSSL_ENCODING_DER or OPENSSL_ENCODING_PEM
Alternatives
- Pass either
OPENSSL_ENCODING_DERorOPENSSL_ENCODING_PEMas the$formatargument toOpenssl\Session::export()orOpenssl\Session::import().
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be smaller than or equal to argument #3 ($max)
Description
PHP 8.6 introduces the clamp() function, which returns $value restricted to the inclusive range [$min, $max]. For that range to mean anything, $min must not be greater than $max.
Passing a $min that is greater than $max throws a ValueError for the second argument, naming $max as the argument it must not exceed, instead of silently returning a nonsensical result.
Example
<?php
clamp(5, 10, 1);
?>
Literal Examples
- clamp(): Argument #2 ($min) must be smaller than or equal to argument #3 ($max)
Alternatives
- Make sure the
$minargument toclamp()is not greater than$max; swap them if they were passed in the wrong order.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be SODIUM_CRYPTO_PWHASH_SALTBYTES bytes long
Description
sodium_crypto_pwhash() derives a key from a password using Argon2i, and it needs a salt as its third argument. The salt must be exactly SODIUM_CRYPTO_PWHASH_SALTBYTES bytes long, which is 16 bytes. Any other length throws a SodiumException.
The salt should be random and unique for each password. Generate it with random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES), and store it next to the derived key, since the same salt is needed to derive the key again.
Example
<?php
// The salt must be exactly SODIUM_CRYPTO_PWHASH_SALTBYTES (16) bytes long
$key = sodium_crypto_pwhash(
16,
'password',
'short',
SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE
);
?>
Literal Examples
- sodium_crypto_pwhash(): Argument #3 ($salt) must be SODIUM_CRYPTO_PWHASH_SALTBYTES bytes long
Alternatives
- Generate the salt with
random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES), so its length always matches. - If you do not need to manage the salt yourself, use
sodium_crypto_pwhash_str(). It creates the salt and stores it inside the returned hash string.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must be SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES bytes long
Description
sodium_crypto_pwhash_scryptsalsa208sha256() derives a key from a password using the scrypt algorithm, and it needs a salt as its third argument. The salt must be exactly SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES bytes long, which is 32 bytes. Any other length throws a SodiumException.
This constant is different from SODIUM_CRYPTO_PWHASH_SALTBYTES, which is used by sodium_crypto_pwhash(). A salt that works with one function does not necessarily work with the other.
The salt should be random and unique for each password. Generate it with random_bytes(SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES), and store it with the derived key.
Example
<?php
// The salt must be exactly SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES (32) bytes long
$key = sodium_crypto_pwhash_scryptsalsa208sha256(
16,
'password',
'short',
SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE,
SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE
);
?>
Literal Examples
- sodium_crypto_pwhash_scryptsalsa208sha256(): Argument #3 ($salt) must be SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES bytes long
Alternatives
- Generate the salt with
random_bytes(SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES), so its length always matches. - Check that the constant matches the function: use
SODIUM_CRYPTO_PWHASH_SALTBYTESwithsodium_crypto_pwhash(), and this constant withsodium_crypto_pwhash_scryptsalsa208sha256().
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must contain a type for object ID %s
Description
SNMP::set() lets $objectId, $type, and $value each be passed as parallel arrays, matched up element by element. Every object ID in $objectId needs a corresponding entry in $type describing what kind of SNMP value is being set.
If $type runs out of elements before $objectId does, the object ID that has no matching type now throws a ValueError naming that OID, instead of silently skipping it with a warning.
Example
<?php
$snmp = new SNMP(SNMP::VERSION_2c, 'localhost', 'private');
$snmp->set(
['.1.3.6.1.2.1.1.6.0'],
[],
['New location']
);
?>
Literal Examples
- SNMP::set(): Argument #2 ($type) must contain a type for object ID ‘.1.3.6.1.2.1.1.6.0’
Alternatives
- Make sure the $type array passed to SNMP::set() has one entry for every object ID in $objectId.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, this emitted an E_WARNING (“‘%s’: no type set”) and silently skipped the affected object ID, instead of throwing.](Previously, this emitted an E_WARNING (“‘%s’: no type set”) and silently skipped the affected object ID, instead of throwing.)
must contain a value for object ID %s
Description
SNMP::set() lets $objectId, $type, and $value each be passed as parallel arrays, matched up element by element. Every object ID in $objectId needs a corresponding entry in $value describing what to set it to.
If $value runs out of elements before $objectId does, the object ID that has no matching value now throws a ValueError naming that OID, instead of silently skipping it with a warning.
Example
<?php
$snmp = new SNMP(SNMP::VERSION_2c, 'localhost', 'private');
$snmp->set(
['.1.3.6.1.2.1.1.6.0'],
['s'],
[]
);
?>
Literal Examples
- SNMP::set(): Argument #3 ($value) must contain a value for object ID ‘.1.3.6.1.2.1.1.6.0’
Alternatives
- Make sure the $value array passed to SNMP::set() has one entry for every object ID in $objectId.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, this emitted an E_WARNING (“‘%s’: no value set”) and silently skipped the affected object ID, instead of throwing.](Previously, this emitted an E_WARNING (“‘%s’: no value set”) and silently skipped the affected object ID, instead of throwing.)
must contain at least one element
Description
min() and max() only work on arrays that contains at least one element. The object here is to avoid the confusion of the null value that may be the result of the operation, and the null that PHP used to return when there was nothing to process in the array.
Example
<?php
echo min([]);
echo max([]);
?>
Alternatives
- Check for empty() before using the min() or max() functions.
must have a length less than or equal to %u
Description
bzdecompress() hands its input off to libbzip2, which tracks buffer sizes in a 32-bit unsigned integer internally. A $data string of 4294967296 bytes (2^32) or more cannot be represented by that counter and would silently overflow.
As of PHP 8.6, bzdecompress() rejects oversized input up front with a ValueError, instead of risking an integer overflow while decompressing it.
Example
<?php
$data = str_repeat('a', 4294967296);
bzdecompress($data);
?>
Literal Examples
- bzdecompress(): Argument #1 ($source) must have a length less than or equal to 4294967295
Alternatives
- Do not pass strings close to or larger than 4 GB to
bzdecompress(); decompress the data in smaller chunks instead if possible.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, oversized input could trigger an unsigned integer overflow inside bzdecompress() instead of being rejected.](Previously, oversized input could trigger an unsigned integer overflow inside bzdecompress() instead of being rejected.)
must not be empty, use str_split() to split a string into characters
Description
explode() splits a string on every occurrence of a $separator. An empty separator has no well-defined meaning for that operation, so it has always been rejected.
As of PHP 8.6, the ValueError message for this case was made more actionable: instead of just saying the separator cannot be empty, it now points directly to str_split(), which is the correct tool for splitting a string into its individual characters.
Example
<?php
explode('', 'hello');
?>
Literal Examples
- explode(): Argument #1 ($separator) must not be empty, use str_split() to split a string into characters
Alternatives
- Use
str_split()instead ofexplode('', ...)to split a string into individual characters.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, this was reported as “explode(): Argument #1 ($separator) cannot be empty”, without the str_split() suggestion.](Previously, this was reported as “explode(): Argument #1 ($separator) cannot be empty”, without the str_split() suggestion.)
must not be empty when passed as an array
Description
SNMP::get(), ::getnext(), ::walk(), and ::set() accept $objectId as either a single string or an array of object IDs. An empty array carries no object IDs at all, so there is nothing for the query to operate on.
As of PHP 8.6, passing an empty array throws a ValueError, instead of the extension emitting a global error and returning false without saying which argument was the problem.
Example
<?php
$snmp = new SNMP(SNMP::VERSION_2c, 'localhost', 'public');
$snmp->get([]);
?>
Literal Examples
- SNMP::get(): Argument #1 ($objectId) must not be empty when passed as an array
- SNMP::set(): Argument #1 ($objectId) must not be empty when passed as an array
Alternatives
- Pass at least one object ID, either as a string or as a non-empty array, to SNMP::get()/getnext()/walk()/set().
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, this threw a generic ValueError (“Array of object IDs must not be empty”) that did not name the affected argument.](Previously, this threw a generic ValueError (“Array of object IDs must not be empty”) that did not name the affected argument.)
must not be empty
Description
The provided parameter is of the valid type, but cannot be left empty.
Example
<?php
print_r(explode('', 'abc')); // Not possible with an empty delimiter
print_r(str_split(1, 'abc'));
?>
Alternatives
- When parsing data, make sure that the separator is not empty.
In previous PHP versions, this error message used to be :ref:cannot-be-empty.
must not be NAN
Description
PHP 8.6’s clamp() function returns $value restricted to the range [$min, $max]. Comparing anything against NAN never produces a meaningful ordering, so $min and $max cannot be NAN.
Passing NAN as either bound throws a ValueError naming the offending argument, instead of returning an unpredictable result.
Example
<?php
clamp(5, NAN, 10);
?>
Literal Examples
- clamp(): Argument #2 ($min) must not be NAN
- clamp(): Argument #3 ($max) must not be NAN
Alternatives
- Do not pass
NANas the$minor$maxargument toclamp(); validate floating-point bounds withis_nan()first if they come from an untrusted source.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
must not contain empty strings
Description
The deflate_init() function accepts options. Among the options, there is a dictionary, with a dictionary of preset strings. Theses strings cannot be left empty.
Before PHP 8.2, this bug would crash PHP.
Example
<?php
try {
deflate_init(ZLIB_ENCODING_DEFLATE, [dictionary => [, ]]);
} catch (ValueError $ex) {
echo $ex->getMessage(), \n;
}
?>
Alternatives
- Remove the 2nd argument.
- Remove the ‘dictionary’ entry in the 2nd argument.
- Put an actual value in the values of the ‘dictionary’ entry in the 2nd argument.
must not exceed %d bytes
Description
PHP 8.6 introduces Openssl\Psk, which holds a pre-shared key (and an optional identity) used to authenticate TLS connections without a certificate. OpenSSL itself imposes fixed limits on both fields: a PSK cannot exceed Openssl\Psk::MAX_PSK_LEN (256) bytes, and an identity cannot exceed Openssl\Psk::MAX_IDENTITY_LEN (128) bytes.
Passing a longer string to Openssl\Psk::__construct() throws a ValueError for the offending argument instead of silently truncating the key or identity.
Example
<?php
$psk = new Openssl\Psk(str_repeat('a', 300));
?>
Literal Examples
- Openssl\Psk::__construct(): Argument #1 ($psk) must not exceed 256 bytes
Alternatives
- Keep the pre-shared key to 256 bytes or fewer, and the identity to 128 bytes or fewer.
- Use
Openssl\Psk::MAX_PSK_LENandOpenssl\Psk::MAX_IDENTITY_LENto validate lengths before constructing the object.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Must not use parent::$%s::%s() in a different property ($%s)
Description
Property hooks are actual methods: they can call other methods to fulfill their mission. They may also call the parent’ methods, and, as such, they may also call the parent’s property hook. This has lead to the syntax parent::$properpty::get().
This syntax is specific to property hooks, and can only be used inside the same property hook for the same property.
Example
<?php
class X {
public string $q {
get => 'in parent';
}
}
class Y extends X {
public string $property {
// Must not use parent::$q::get() in a different property ($property)
get => parent::$q::get();
}
}
$y = new Y;
echo $y->q;
?>
Literal Examples
- Must not use parent::$q::get() in a different property ($p)
Alternatives
- Move the block of the property hook in a regular method and call it from the hook and other methods.
- Inline the code every time it is needed.
Related error messages
- must-not-use-parent::$%s::%s()-in-a-different-property-hook-(%s)
- must-not-use-parent::$%s::%s()-outside-a-property-hook
Must not use parent::$%s::%s() in a different property hook (%s)
Description
Property hooks are actual methods: they can call other methods to fulfill their mission. They may also call the parent’ methods, and, as such, they may also call the parent’s property hook. This has lead to the syntax parent::$properpty::get().
This syntax is specific to property hooks, and can only be used inside the same property hook for the same property.
Example
<?php
class X {
public string $q {
get => 'in parent';
}
}
class Y extends X {
public string $q {
// Must not use parent::$q::get() in a different property hook ($p)
set => parent::$q::get();
}
}
$y = new Y;
echo $y->q;
?>
Literal Examples
- Must not use parent::$q::get() in a different property hook ($p)
Alternatives
- Move the block of the property hook in a regular method and call it from the hook and other methods.
- Inline the code every time it is needed.
Related error messages
- must-not-use-parent::$%s::%s()-in-a-different-property-($%s)
- must-not-use-parent::$%s::%s()-outside-a-property-hook
Must not use parent::$%s::%s() outside a property hook
Description
Property hooks are actual methods: they can call other methods to fulfill their mission. They may also call the parent’ methods, and, as such, they may also call the parent’s property hook. This has lead to the syntax parent::$properpty::get().
This syntax is specific to property hooks, and can only be used inside the same property hook for the same property.
Example
<?php
class X {
public string $q {
get => 'in parent';
}
}
class Y extends X {
public string $q {
get => parent::$q::get();
}
function foo(): string {
// Must not use parent::$q::get() outside a property hook
return parent::$q::get();
}
}
$objectY = new X;
echo $objectY->q;
?>
Literal Examples
- Must not use parent::$q::get() outside a property hook
Alternatives
- Move the block of the property hook in a regular method and call it from the hook and other methods.
- Inline the code every time it is needed.
Related error messages
- must-not-use-parent::$%s::%s()-in-a-different-property-($%s)
- must-not-use-parent::$%s::%s()-in-a-different-property-hook-(%s)
Named parameter $%s overwrites previous argument
Description
Named parameter and positional arguments are setting the same argument, with different name. PHP reports this to avoid overwritting the first with the second.
In the first example, there are two cases for this error: either a repetition of the same parameter in the argument list, or a mix of positional and named parameters, which leads to the second overwriting the first.
In the second example, a mix of named and positionned arguments is used, and there is a duplicate for the
There is a distinct error message when this happens to in attributes calls.
Example
<?php
function foo($a, $b) { print_r($b); }
foo(a: 1, a:1);
foo(1, a:1);
// 1 is given to $a, by its position 0
// 2 is given to $a, by its name 'a'. This is a conflict
$args = [1, a => 2];
foo(...$args); // error
$args = [a => 1, 2];
foo(...$args); // Cannot use positional argument after named argument during unpacking
$args = [b => 1];
foo(...$args, b: 2); // b is overwritten
?>
Literal Examples
- Named parameter $a overwrites previous argument
Alternatives
- Remove duplicate named parameters in the argument list.
- Add all names to parameters in the argument list.
- Remove all names to parameters in the argument list.
Related error messages
- duplicate-named-parameter-$%s
- cannot-use-positional-argument-after-named-argument-during-unpacking
- cannot-use-positional-argument-after-named-argument
- cannot-use-positional-argument-after-argument-unpacking
namespace%s is an invalid class name
Description
This is the unquoted counterpart of the 'namespace\%s' is an invalid class name error: it carries the exact same runtime message, just without the surrounding single quotes PHP actually prints around the offending name.
namespace used at the start of a fully qualified name refers to the current namespace, and is usually omitted. self describes the current class: it is a relative class name with no absolute-path equivalent, so writing it as namespace\self (or the equivalent \self) is meaningless and rejected. The same applies to static and parent.
Example
<?php
function foo(namespace\self $a) {};
function foo( $a): namespace\self {};
class X {
private namespace\self $f;
private namespace\x $f2;
}
?>
Literal Examples
- namespace\self is an invalid class name
Alternatives
- Remove the initial namespace and backslash.
- Use the literal name of the intended class.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Namespace declaration statement has to be
Description
A namespace declaration must be the very first statement of the file, or immediately follow a declare() call (such as declare(strict_types=1);). Any other statement, including a simple echo, a comment that generates output, or whitespace before the opening <?php tag, placed before the namespace statement makes it invalid.
The full message reads: Namespace declaration statement has to be the very first statement or after any declare call in the script.
Example
<?php
echo 'Hello';
namespace App;
?>
Literal Examples
- Namespace declaration statement has to be the very first statement or after any declare call in the script
Alternatives
- Move the
namespacestatement to be the first statement in the file, right after the opening<?phptag. - Only keep a
declare()call before thenamespacestatement, and move everything else after it. - Remove any whitespace or output before the opening
<?phptag.
Related error messages
- no-code-may-exist-outside-of-namespace-{}
- strict_types-declaration-must-be-the-very-first-statement-in-the-script
- cannot-mix-bracketed-namespace-declarations
- encoding-declaration-pragma-must-be
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Namespace declarations cannot be nested
Description
Namespace declaration, with blocks, cannot be nested one into the other. Namespaces must be one next to each other.
Usually, there is only one namespace per file, without a block.
Example
<?php
namespace A {
namespace B {
}
}
?>
Alternatives
- Make the namespaces next to each other; concatenate the names to create deep namespaces:
namespace A\B {..}. - Split the code into several files, each with only one namespace.
Related error messages
needle is not a string or an integer
Description
The second argument may be a string, or an integer, which will be used as a string. Any other type is forbidden, in particular array. Other types may yield other error messages, such as a type error.
Example
<?php
print strpos('abc99', []);
?>
Alternatives
- Use a foreach on an array of strings, and use these values instead.
- Pick up a value in the array.
Related error messages
Negative power of zero
Description
It is not possible to calculate a negative power of 0: a negative power is, in fact, a division raised to a power, and division by zero is undefined.
It was a silent error until PHP 8.4, and it is now a visible one.
This is also the case with PHP native ** and pow().
Example
<?php
echo bcpow(0, -1);
?>
Alternatives
- Check for the first argument not to be 0, or similar.
- Catch the exception.
Related error messages
Nesting level too deep - recursive dependency?
Description
PHP comparison may be recursive: it happens when an array contains a reference to another element of itself. In that case, the array becomes recursive: traversing such array may end up with an infinite loop, as the reference may loop back on itself.
This error message applies to array comparisons, and count(). There might be other situations where this applies.
Example
<?php
$a = [1, 5=> &$a];
$b = [1, 5=> &$b];
try {
var_dump($a === $b);
} catch (Error $e) {
print caught\n;
}
// count() doesn't handle recursive arrays
count($a);
?>
Alternatives
- Do not make direct comparisons of recursive arrays.
- Do not try to count recursive arrays.
never can only be used as a standalone type
Description
never is a special return type, indicating that a function or method never returns control to its caller: it always throws, calls exit(), or otherwise never completes normally.
Because never represents the absence of any return at all, it cannot be combined with other types in a union, nor made nullable: it can only be used on its own, as the sole return type of a function or method.
Example
<?php
function foo(): int|never {}
?>
Alternatives
- Remove the other types, and use
neveralone. - Remove
never, and keep the other type(s) alone.
Related error messages
- void-can-only-be-used-as-a-standalone-type
- type-mixed-can-only-be-used-as-a-standalone-type
- a-never-returning-%s-must-not-return
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
never cannot be used as a parameter type
Description
Never is a PHP return type, that is used to indicate that a method will not return a value. As such, it makes no sense to use with a parameter, as a parameter cannot return any value. Hence, the never type cannot be used with a parameter.
Example
<?php
function foo(never $n) {}
?>
Alternatives
- Remove the never type.
- Change the never type to another type.
never-returning function must not implicitly return
Description
A never returning function or method never reaches the end of the method, or any return operation. It must either throw an exception, trigger an error, die or exit, or stay in an infinite loop.
In the case of an empty function, PHP execution reachs the end of the method, and adds an implicit return null call, which triggers the TypeError.
never type is checked at execution time, though the presence of return in the body of the method triggers it at linting time.
Example
<?php
function foo() : never { }
?>
Alternatives
- Remove all return calls from the body of the method.
- Prevent the method to reaching its end.
- Checks that the method include either a
throw,dieorexit, a call to another never-returning method, or an infinite loop.
New expressions are not supported in this context
Description
It is not possible to use directly an object as value for a class constant.
It is also not allowed to use an object as default value for properties, static or not.
On the other hand, it is possible to use an object stored in a global constant. And, since it is possible to use a global constant as a value for a class constant, it is easy to work around this limitation. The same trick is possible with properties, as long as the target object is not self.
Properties cannot use their host class as default values: it leads to a chicken and egg problem. The global constant must be created with an object of the class, which is then immediately instantiated with a default value based on the global constant.
Example
<?php
class B {}
const CONSTANT_B = new B;
class X {
// This is not possible
const A = new B;
// This is possible, with the same result
const A2 = CONSTANT_B;
}
?>
Alternatives
- Remove the constant A.
- Create a global constant, and assign it to A.
- Make the constant a property.
- Create a global constant, and assign it to the class constant.
No code may exist outside of namespace
Description
When using a block notation for namespaces, there cannot be any other code outside the namespaced blocks. Here, the function foo() is outside the namespace block.
The error message is not strictly true: the declare command may be left out of the namespace, and so does any comments.
Example
<?php
namespace A {
}
function foo() {}
?>
Alternatives
- Move all the code inside a namespace block.
- For global namespace, use the
namespace {...}command without a name. - Switch to the namespace command without block: all the code will be in that namespace, until the next namespace command.
Related error messages
No ending delimiter ‘%c’ found
Description
This error is a regex related error, not a PHP one. The regular expression is the first argument of the call. It is invalid, as regex are supposed to start and end with the same non-alphanumeric character.
Then, PHP stops the process, and returns false. In this case, false may be confused with a failure to find the pattern in the string, and yield unexpected results.
Example
<?php
preg_match('/[a-b]', 'abc');
?>
Literal Examples
- No ending delimiter ‘/’ found
Alternatives
- Fix the regex.
Related error messages
- delimiter-must-not-be-alphanumeric,-backslash,-or-nul-byte
- delimiter-must-not-be-alphanumeric,-backslash,-or-nul
- delimiter-must-not-be-alphanumeric-or-backslash
Related error messages
No such file or directory
Description
PHP reports, as warning, a failure to remove a file that doesn’t exists. This is both an error, as the file could not be removed, but also a success, as the file is removed in the end.
Example
<?php
unlink(non-existing-file.txt);
?>
Literal Examples
- unlink(oops): No such file or directory
Alternatives
- Check that the file exists before trying to remove it.
Related error messages
Non-abstract method %s::%s() must contain body
Description
A method must have a body block. When it has no body block, it has a semicolon instead, and it must have the abstract keyword for the method, and following, to the class.
Example
<?php
class X {
function foo();
}
?>
Literal Examples
- Non-abstract method X::foo() must contain body
Alternatives
- Add a body block to the method.
- Add a abstract option to the method and to the class.
Related error messages
- class-%s-contains-%d-abstract-method%s-and-must-therefore-be-declared-abstract-or-implement-the-remaining-methods
- %s-%s-contains-%d-abstract-method%s-and-must-therefore-be-declared-abstract-or-implement-the-remaining-method%s-(
- %s-function-%s::%s()-cannot-contain-body
Non-abstract property hook must have a body
Description
Property hooks, both set and get, may be made abstract by replacing the body block by a semi-colon. And, just like methods, property hooks must use the abstract property, although the property definition has to support the option, not the property hook itself.
Example
<?php
class X {
// This is an error. A property hook must have a body
public $property {
get;
}
// This is OK. The property is marked as abstract
public abstract $abstractProperty {
get;
}
}
?>
Alternatives
- Add a body to the property hook.
- Add the abstract keyword to the property definition.
Related error messages
- abstract-property-hook-cannot-have-body
- abstract-property-%s::$%s-must-specify-at-least-one-abstract-hook
Non-canonical cast (binary) is deprecated, use the (string) cast instead
Description
The non-canonical cast (binary) has been deprecated. It should be replace by the simpler (string).
Example
<?php
$a = (binary) $string;
?>
Alternatives
- Use
(string).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See nonCanonicalCast
Non-canonical cast (boolean) is deprecated, use the (bool) cast instead
Description
The non-canonical cast (boolean) has been deprecated. It should be replace by the simpler (bool).
Example
<?php
$a = (boolean) $string;
?>
Alternatives
- Use
(bool).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See nonCanonicalCast
Non-canonical cast (double) is deprecated, use the (float) cast instead
Description
The non-canonical cast (double) has been deprecated. It should be replace by the simpler (float).
Example
<?php
$a = (double) $string;
?>
Alternatives
- Use
(float).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See nonCanonicalCast
Non-canonical cast (integer) is deprecated, use the (int) cast instead
Description
The non-canonical cast (integer) has been deprecated. It should be replace by the simpler (int).
Example
<?php
$a = (integer) $string;
?>
Alternatives
- Use
(int).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See nonCanonicalCast
Non-enum class %s cannot implement interface %s
Description
UnitEnum is an PHP native and reserved interface. It is only used with enumerations. It is also handled by PHP itself, which adds it to enumerations: there is no need to add it explictly. This applies to BackedEnum and UnitEnum, as of PHP 8.4.
Example
<?php
class X implements YnitEnum {}
?>
Literal Examples
- Non-enum class x cannot implement interface UnitEnum
- Non-enum class x cannot implement interface BackEnum
Alternatives
- Turn the class into an enumeration.
- Remove the UnitEnum implementation.
Related error messages
Non-readonly class %s cannot extend readonly class %s
Description
A readonly class cannot extends a non-readonly class; a non-readonly class cannot extends a readonly class. Both classes must be readonly or non-readonly to be able to extends one another. This is due to readonly being applied to all available properties, which is ambiguous with class hierarchies.
Example
<?php
readonly class Foo
{
}
class Bar extends Foo
{
}
?>
Literal Examples
- Non-readonly class Foo cannot extend readonly class Bar
Alternatives
- Make both classes readonly.
- Make both classes non-readonly.
- Make both classes non-readonly and apply readonly per properties.
Related error messages
Non-static method %s::%s() cannot be called statically
Description
While a non-static method can call a static method, the contrary is not possible. In particular, the non-static method will not be able to have a valid $this variable, since the static call doesn’t provide one.
This error is also reported when creating a closure from a non-static method. This happen even if the method is not actually called.
Example
<?php
class X {
static function foo() {
//Non-static method x::foo() cannot be called statically
self::goo();
}
function goo() {}
}
(new X)->foo();
// when creating a closure
$closure = X::goo(...);
?>
Literal Examples
- Non-static method x::foo() cannot be called statically
Alternatives
- Make the concrete method static too.
- Find an object to call the non-static method.
Related error messages
In previous PHP versions, this error message used to be :ref:non-static-method-%s::%s()-should-not-be-called-statically.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See nonStaticMethodCalledStatically
Non-static method %s::%s() should not be called statically
Description
A non-static method requires an object to be called, as PHP will populate that object in the $this method.
If the method makes no use of $this, make it static to allow the call. Otherwise, keep it non-static, and use an object for the call.
Example
<?php
class X {
function foo() { echo __METHOD__;}
}
X::foo();
?>
Literal Examples
- Non-static method x::foo() should not be called statically
Alternatives
- Make the method static.
- Find an object to call the method.
Related error messages
In more recent PHP versions, this error message is now :ref:non-static-method-%s::%s()-cannot-be-called-statically.
Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior
Description
Until PHP 8.0, strpos() accepted integers as second argument. Then, it would automagically, transform them into their equivalent. Hence, it returned 2 in PHP 7.4.
In PHP 8.0 and later, the integer is used as a string. Unless the ASCII characters and the string matches, it would return nothing.
Example
<?php
// 99 is ASCII for c
print strpos('abc99', 99);
// displays 3 in PHP 8.0+
// displays 2 in PHP 7.4-
?>
Alternatives
- Use
chr(99)instead of99, to ensure the second argument is a string. - Convert the second argument into a string first.
Related error messages
null cannot be marked as nullable
Description
Since PHP 8.2, null (like false and true) can be used directly as a standalone type. But null already means exactly one thing: the value null. Marking it nullable with a leading ?, as in ?null, would only mean null or null, which is entirely redundant, so PHP rejects it.
Example
<?php
function test(): ?null
{
}
?>
Literal Examples
- null cannot be marked as nullable
Alternatives
- Remove the
?and usenullon its own.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Object %s#%d not contained in WeakMap
Description
This error is thrown when a WeakMap is read with an object that is not one of its keys. The message gives the class and the object id of the missing key, such as stdClass#2.
Reading a missing key is an error, unlike isset(), which returns false for it. Removing a missing key with unset() does nothing and does not raise this error.
Also note that a key is removed from the WeakMap as soon as the object is destroyed, so reading the map with an object that has already been freed raises this error too.
Example
<?php
$map = new WeakMap();
$object = new stdClass();
// $object was never added to the WeakMap
echo $map[$object];
?>
Literal Examples
- Object stdClass#2 not contained in WeakMap
Alternatives
- Check that the key is in the map with
isset()before reading it:if (isset($map[$object])) { ... }. - Use
$map[$object] ?? $defaultto provide a default value when the key is missing. The??operator does not raise the error. - Make sure the object was added to the map with
$map[$object] = $valuebefore it is read.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Object casts are not supported in this context
Description
All cast operators are not supported in a static constant expression. This applies to all casts operations: (int), (string), (bool), (array), (object), until PHP 8.5. In PHP 8.5 and later, only (object) is not supported.
They look like any other operator, such as + or ., but they require data manipulations which are incompatible with constant expressions.
While it may be useless to apply a cast to a literal value, it might be useful to use it with another expression or another constant.
Example
<?php
class X {
public $foo = (object) [];
}
?>
Alternatives
- Create a value directly with the target type.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Object not initialized
Description
This error appears with intl and spl extensions. It happens when an object was not fully initialized with the extension: it was only extended and the parent constructor was omitted. This leaves the custom object valid, but not finalized from the parent point of view.
This error may also happen when the object keeps being used, after an unset() call, or __destructor call.
Example
<?php
class MyDirectoryIterator extends DirectoryIterator {
public function __construct() {}
}
$it = new MyDirectoryIterator;
try {
$it->key();
} catch (Error $e) {
echo $e->getMessage(), \n;
}
?>
Alternatives
- Call
parent::__constructin the custom constructor. - Remove any call to the object after destruction.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Object of class %s could not be converted to %s
Description
An object cannot be converted automatically into a string, without calling a dedicated method, or setting up the magic method called __toString.
With native PHP operators and functions, the call to __toString is automagic. With custom functions, it is dependent on the strict_types configuration: when strict_types is activated, it prevents the automatic conversion to string, and yields the error.
Example
<?php
class X {}
$x = new X;
// This would work if the __toString() method is defined in X
echo $x;
function foo(string $s) {
echo $s;
}
// This works with __toString() and without strict_types=1
foo($x);
?>
Literal Examples
- Object of class X could not be converted to string
Alternatives
- Remove the strict_types configuration.
- Add a cast to (string) to explicitly activate the conversion to string.
- Create a method to do the conversion, and use it, instead of the raw object.
Object of class %s could not be converted to bool
Description
PHP reports that the object cannot be used as a boolean. Converting an object into a boolean is a PHP engine feature, and should be always on. Though, some extensions have not systematically implemented it.
Here, gmp is lacking the support for converting objects into a boolean, though it was fixed in PHP 8.4. When meeting such error, it should be reported to the author of the extension.
Example
<?php
$x = gmp_result('12', 3);
if ($x) {
print $x is truthy;
}
?>
Literal Examples
- Object of class GMP could not be converted to bool
Alternatives
- Make an explicit comparison, with
is_object(). - Make an explicit comparison, with
instanceof.
Related error messages
- object-of-class-%s-could-not-be-converted-to-string
- object-of-class-%s-could-not-be-converted-to-float
- object-of-class-%s-could-not-be-converted-to-int
Object of class %s could not be converted to float
Description
PHP reports that the object cannot be used as an float. Converting an object into a float is only possible when the underlying class has provided the code for it. There is no userland code to do that, such as a magic code: it is only possible via a call to a method that returns a float.
Among the PHP classes, gmp and bcmath (in PHP 8.4) extensions provide classes which also works with math operations. Most of the other classes do not convert easily to numbers, as it makes little sense to convert a database connexion (for example) into a number.
Example
<?php
class Y { }
// Error!
echo new Y + 1;
$multiplication = gmp_mul('12', 3);
print $multiplication * 4; // 144
$number = new BcMath\Number('1.234');
$addition = $number->add(new BcMath\Number('2.34567'));
print $addition + 1; // 4.57967
?>
Literal Examples
- Object of class Y could not be converted to float
- Object of class Mysqli could not be converted to float
Alternatives
- Implement tod that returns an integer, on that object.
- Upgrade to PHP 8.4, to use automatic conversion with
bcmath.
Related error messages
- object-of-class-%s-could-not-be-converted-to-bool
- object-of-class-%s-could-not-be-converted-to-string
- object-of-class-%s-could-not-be-converted-to-int
Object of class %s could not be converted to int
Description
PHP reports that the object cannot be used as an integer. Converting an object into a int is only possible when the underlying class has provided the code for it. There is no userland code to do that, such as a magic code: it is only possible via a call to a method that returns an integer.
Among the PHP classes, gmp and bcmath (in PHP 8.4) extensions provide classes which also works with math operations. Most of the other classes do not convert easily to numbers, as it makes little sense to convert a database connexion (for example) into a number.
Example
<?php
class Y { }
// Error!
echo new Y + 1;
$multiplication = gmp_mul('12', 3);
print $multiplication * 4; // 144
$number = new BcMath\Number('1.234');
$addition = $number->add(new BcMath\Number('2.34567'));
print $addition + 1; // 4.57967
?>
Literal Examples
- Object of class Y could not be converted to int
- Object of class Datetime could not be converted to int
Alternatives
- Implement tod that returns an integer, on that object.
- Upgrade to PHP 8.4, to use automatic conversion with
bcmath.
Related error messages
- object-of-class-%s-could-not-be-converted-to-bool
- object-of-class-%s-could-not-be-converted-to-float
- object-of-class-%s-could-not-be-converted-to-string
Object of class %s could not be converted to string
Description
PHP reports that the object cannot be used as a string. Converting an object into a string is only possible when the magic method __toString() is implemented, or when the interface Stringable is implemented.
In that case, the object is automatically converted into a string, thanks to that method. Otherwise, it is a Fatal error.
This is a distinct error than passing an object in a string argument: in that case, it is a Type error.
A lot of native PHP classes support the conversion, but not all of them. Check for stringable interface before using them.
Example
<?php
class Y { }
//error!
echo (new Y);
// X could also be implementing Stringable, to enforce the __toString() method
class X {
function __construct(array $arg) {
$this->a = $arg;
}
function __toString(){
return implode(', ', $this->arg);
}
}
// valid
echo (new X);
$array1 = [E::A];
$array2 = [E::B];
enum E: string {
case A = 'a';
case B = 'b';
}
// hidden necessary string conversion
array_intersect($array1, $array2); // also with other array_intersect* functions
?>
Literal Examples
- Object of class Y could not be converted to string
- Object of class stdClass could not be converted to string
Alternatives
- Implement the
Stringableinterface on the class, or its parent. - Implement the
__toStringmethod n the class, or its parent. - Call a method that returns a string, on that object.
- Use
print_rorvar_dumpto get the details inside the object.
Related error messages
- object-of-class-%s-could-not-be-converted-to-bool
- object-of-class-%s-could-not-be-converted-to-int
- object-of-class-%s-could-not-be-converted-to-float
Related error messages
Object of type %s has not been correctly initialized by calling parent::__construct() in its constructor
Description
PHP needs an explicit call to the parent constructor to init the parent class. Sometimes, overwritten constructor is an expected features. With PHP native classes, Datetime and Datetimezone must be explicitly called when extended.
Note that this error is only raised when the object is used, and not at instantiation time.
Example
<?php
class X extends DateTime {
public function __construct() { }
}
$object = new X;
var_dump(object->format("d"));
?>
Literal Examples
- Object of type X has not been correctly initialized by calling parent::__construct() in its constructor
Alternatives
- Add a call to the parent __construct() method.
Object of type %s is not callable
Description
There was an attempt to call a function whose name was provided in a variable, but that value could not be related to a callable code.
null: not a callabletrue,false: booleans are not callableint: integers are not callablereal: real are not callablearray: arrays are callable when they have two elements, with keys 0 and 1. First one is a class or an object of that class, the second is a string with a visible method name on that class. Otherwise, they are not valid callables.string: strings are callable when they represent a function, with the leading backslash,\strlen, or a method, with a class name, a double colon::, and a visible method name. Otherwise, they are not valid callables.object: object are callable when their class has a__invokemethod. This might be through a parent, likeClosure. Otherwise, objects are not callable, although their method are.
All of these may be checked with a call to is_callable() on the variable, before using it.
Example
<?php
$method = new stdClass;
$method();
?>
Literal Examples
- Object of type stdClass is not callable
- Object of type X is not callable
Alternatives
- Check the variable with
is_callable(), before using it with the call syntax. - Use one of the available format.
Related error messages
In previous PHP versions, this error message used to be :ref:function-name-must-be-a-string.
object values within argument #1 $data to http_build_query() being interpreted as arrays is deprecated,
Description
http_build_query() walks its $data argument recursively, and treats any object value it finds along the way — not just the top-level argument — as if it were an array, iterating its public properties to build nested query keys such as public[public]=input. PHP 8.6 deprecates this implicit array-like treatment of nested object values, on top of the separate deprecation for passing an object as the top-level $data argument itself.
Example
<?php
class KeyVal {
public $public = 'input';
}
$o = new KeyVal();
$nested = new KeyVal();
$o->public = $nested;
echo http_build_query($o);
?>
Literal Examples
- http_build_query(): object values within argument #1 $data to http_build_query() being interpreted as arrays is deprecated, instead the $data argument should be preprocessed with get_object_vars()
Alternatives
- Convert nested objects to arrays with
get_object_vars()before assigning them, so the structure passed to http_build_query() is plain arrays all the way down. - Restructure the data so query parameters are built from arrays rather than objects.
Related error messages
In previous PHP versions, this error message used to be :ref:passing-an-object-for-argument-#1-$data-to-http_build_query()-is-deprecated,-call-get_object_vars()-first-instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Octal escape sequence overflow %s is greater than \377
Description
Octal escape is a notation for double quoted strings, where a backslash followed by 3 digits is replaced by the character with this ASCII number. These ASCII numbers have a limit of 0o377.
Between 0o377 and 0o777, numbers are valid octals, and not ASCII numbers, so the error message appears.
Beyond 0o777, the sequence is not a valid octal anymore, and PHP does not process it, nor emit an error message.
Example
<?php
$a = "\500";
?>
Alternatives
- Check the value in the octal sequence to be valid.
- Add backslashes, to make the characters literals.
Offset not contained in string.
Description
strpos() searches for a string called $needle in another string called $haystack, starting at the offset passed as third argument, and called $offset.
The offset must be smaller than the full length of the $haystack: otherwise, PHP starts to search beyond the end of the data, and that will always fail.
This error message is shared by several PHP native and extension functions, namely mbstring and iconv: strpos(), strrpos(), stripos(), strripos(), mb_strpos(), mb_strrpos(), mb_stripos(), mb_strripos(), iconv_strpos and iconv_strrpos.
Before PHP 8.0, the failure was reported as a non-blocking warning. Since PHP 8.0, it is a fatal error.
Example
<?php
var_dump(strpos('abc', 'a', 4));
?>
Alternatives
- Check that the offset is not beyond the length of the string.
- Use a try catch around this methodcall.
- Lengthen the source string.
In more recent PHP versions, this error message is now :ref:must-be-contained-in-argument-#1-($haystack).
Only arrays and Traversables can be unpacked
Description
The triple dot ... operator works on arrays and traversables, such as generator, iterators… It cannot work on other data structures.
Also, ... has a lower priority than the null-coalesce operator ??, so it applies to both branch of the operator.
Example
<?php
$a = null;
foo(...$a);
foo(...$a ?? range(1,2));
// displays 1, 2
function foo() {
print_r(func_get_args());
}
?>
Alternatives
- Check that the value is an array or a traverable before using the
...operator. - Use the
??operator to give a value tonullbefore the...operator. - Use the
?:operator to give a value to empty data before the...operator.
Related error messages
Only arrays can be unpacked in constant expression
Description
... may be used on both arrays and Traversable objects, but within a static constant expression, this operator only works on arrays, and cannot be used on objects, Traversable or not.
Example
<?php
const A = 2;
function foo($a = [...A]) {
print_r($a);
}
foo();
?>
Alternatives
- Rewrite the expression without the
...operator. - Convert the object into an array.
Related error messages
Only basic entities substitution is supported for multi-byte encodings other than UTF-8; functionality is equivalent to htmlspecialchars
Description
When passing a valid encoding to htmlentities(), but that is not supported, a warning is displayed, and an empty string is returned. This contrasts with the behavior when the encoding is not recognized, where PHP defaults to UTF-8, and returns something non empty.
Example
<?php
var_dump( htmlentities("Café & 'quotes' and € euro", ENT_QUOTES, 'Big5') );
// '', empty string
?>
Alternatives
- Check that the used encoding is supported.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Only hooked properties may be declared abstract
Description
Hooked properties may be declared abstract, as long as the class is also abstract, and that one of the hook, get or set or both, have no body block.
In previous version, PHP would never allow properties to be abstract.
Example
<?php
abstract class X {
public abstract string $x;
}
?>
Alternatives
- Add an identity hook to the class, such as
get => $this->xorset => $this->x = $value;. - Remove the abstract keyword.
Related error messages
In previous PHP versions, this error message used to be :ref:cannot-use-the-abstract-modifier-on-a-property.
Only internal classes can be registered as compiler attribute
Description
This error could not be reproduced so far. Help us by sending us any generating code.
Example
Alternatives
Only the first byte will be assigned to the string offset
Description
The array notation is available with strings, to both write and read. When writing to a string, the new assigned character must be a single character, and even, a single byte. This means that it is not possible to replace multiple characters, or to inject a longer string inside another one with such syntax.
As a side effect, this also applies to multi-byte characters: since they are represented on two, or more, characters, they cannot be injected in such syntax.
Example
<?php
$string = 'abc';
$string[3] = 'd';
// abcd
$string[4] = 'ef';
// warning
// abcde
$string[5] = '我'; // multi-byte character
// warning
// abcde� // <- invisible character at the end of the string
?>
Alternatives
- Use preg_replace() or str_replace() to inject more than one character.
- Splice the string and insert the new string in-between:
substr($string, 0, $x).$newString.substr($string,$x+1).
Only the last parameter can be variadic
Description
A variadic parameter, marked with ..., collects every remaining argument passed to the function into an array. Since it consumes all the arguments left, no parameter can follow it: it must be the last one in the parameter list.
This is checked at compile time, as soon as a parameter is declared after a variadic one.
Example
<?php
function foo(...$a, $b) {}
?>
Alternatives
- Move the variadic parameter to the end of the parameter list.
- Use named arguments instead, if the extra parameter needs to keep a fixed conceptual position.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Only variable references should be returned by reference
Description
When a function returns a reference, it must return a variable, a property or an array’s item. It cannot return a literal value, a constant or an expression.
Example
<?php
function &foo() {
return 1;
return B;
}
?>
Alternatives
- Put the literal in a variable, and return the variable.
- Remove the reference in the method signature.
Related error messages
- %s():-argument-#%d%s%s%s-cannot-be-passed-by-reference
- %s():-argument-#%d%s%s%s-could-not-be-passed-by-reference
Only variable references should be yielded by reference
Description
With the & option in the signature, a generator is yielding values by reference, and not by value. This way, literal values cannot be yielded: they must be stored in a variable or property first.
Example
<?php
function &gen() {
yield foo;
}
$gen = gen();
var_dump($gen->current());
?>
Alternatives
- Store the literal in a variable and yield the variable.
- Remove the & in the method signature.
Only variables can be passed by reference
Description
Methods arguments may be passed by value or by reference. The first one is the default behavior, and the second one is optional: it is identified with the &, before the name of the argument.
When an argument is passed by reference, the calling context passes a variable, and conserves a handle to the modified variable after the execution of the method. The handle points to a data container, such as a variable, a property, a static property or a array item.
When passing literal values or constants, global or class, a distinct error is emitted, as there cannot be a reference to them. They can only be passed by value.
This error message is emitted when a value is returned, and feed into a reference argument.
Example
<?php
function foo(&$a) {}
foo(1);
?>
Alternatives
- Store the value in a variable, and pass the variable to the method.
- Remove the reference from the called method signature.
In more recent PHP versions, this error message is now :ref:only-variables-should-be-passed-by-reference.
Only variables should be passed by reference
Description
Methods arguments may be passed by value or by reference. The first one is the default behavior, and the second one is optional: it is identified with the &, before the name of the argument.
When an argument is passed by reference, the calling context passes a variable, and conserves a handle to the modified variable after the execution of the method. The handle points to a data container, such as a variable, a property, a static property or a array item.
When passing literal values or constants, global or class, a distinct error is emitted, as there cannot be a reference to them. They can only be passed by value.
This error message is emitted when a value is returned, and feed into a reference argument.
Example
<?php
function foo(int &$int) {
// doSomething
}
// the result of a function is still a literal value
foo(abs(-3));
// a direct literal value generates that error
foo(3);
// This one is a notice
enum E {
case A;
case B;
case C;
}
usort(E::cases());
//The sort won't be visible, as the array is not accessible and must be called again, unsorted.
?>
Alternatives
- Store the value in a variable, and pass the variable to the method.
- Remove the reference from the called method signature.
In previous PHP versions, this error message used to be :ref:only-variables-can-be-passed-by-reference.
open_basedir prohibits opening %s
Description
open_basedir is a PHP directive which limits access of the inclusion functions, such as include and require, to include files which are outside the path specified with open_basedir.
Example
<?php
include '/private/folder/secret.php';
?>
Alternatives
- Update the
open_basedirdirective to allow access to the file. - Update the inclusion path to target a file that falls within the paths in the
open_basedirdirective.
Related error messages
- failed-opening-required-%s-(include_path=%s)
- open_basedir-restriction-in-effect.-file(%s)-is-not-within-the-allowed-path(s):-(%s)
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s)
Description
This is an alt error message raised when a PHP extension tries to access a file, while the open_basedir is enabled. This may happen with XML extensions, sqlite3, file, tidy, mysqli, readline, stream, curl, etc. This list is not exhaustive.
Example
<?php
$db = new SQLite3('/forbidden/path/to/sqlite3.db');
?>
Literal Examples
- open_basedir restriction in effect. File(example.php) is not within the allowed path(s): (.::/tmp/)
Alternatives
- Make sure the file path lies within the
open_basedirdirective’s path. - Change the value of the
open_basedirdirective. - Check the value of the
open_basedirdirective for typos.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Optional parameter %s declared before required parameter %s is implicitly treated as a required parameter
Description
An optional parameter has a default value, while a required parameter doesn’t. In a method signature, PHP recommends to set the required parameters first, then the optional parameter.
When this is not the case, PHP is unable to understand if an argument has to be assigned to a parameter, or if it can be skipped, and assigned to the next required. When this happens, any required parameter makes previously defined parameter also required.
Example
<?php
function foo($a = 1, $b) {}
?>
Literal Examples
- Optional parameter $a declared before required parameter $b is implicitly treated as a required parameter
Alternatives
- Remove the default value of the early optional parameter.
- Add a default value of the late required parameter.
In previous PHP versions, this error message used to be :ref:required-parameter-$%s-follows-optional-parameter-$%s.
In more recent PHP versions, this error message is now :ref:%s():-optional-parameter-$%s-declared-before-required-parameter-$%s.
Parameter $%s of %s hook %s::$%s must not be pass-by-reference
Description
The parameter of a set property hook receives the value being assigned to the property. It cannot be declared as pass-by-reference with a leading &, since a property hook is not meant to modify the caller’s variable; it only reacts to, or transforms, the value on its way into the property.
Example
<?php
class X
{
public string $property {
set(&$value) {
$this->property = $value;
}
}
}
?>
Literal Examples
- Parameter $value of set hook X::$property must not be pass-by-reference
Alternatives
- Remove the
&from the hook’s parameter.
Related error messages
- parameter-$%s-of-%s-hook-%s::$%s-must-not-be-variadic
- parameter-$%s-of-%s-hook-%s::$%s-must-not-have-a-default-value
- %s-hook-of-property-%s::$%s-must-accept-exactly-one-parameters
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Parameter $%s of %s hook %s::$%s must not be variadic
Description
A set property hook must accept exactly one, ordinary parameter: the incoming value. Declaring it as variadic with ... does not make sense, since the hook is always called with exactly one value, never with a variable number of arguments.
Example
<?php
class X
{
public string $property {
set(string ...$value) {
$this->property = implode(',', $value);
}
}
}
?>
Literal Examples
- Parameter $value of set hook X::$property must not be variadic
Alternatives
- Remove the
...from the hook’s parameter, and declare it as a regular parameter.
Related error messages
- parameter-$%s-of-%s-hook-%s::$%s-must-not-be-pass-by-reference
- parameter-$%s-of-%s-hook-%s::$%s-must-not-have-a-default-value
- %s-hook-of-property-%s::$%s-must-accept-exactly-one-parameters
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Parameter $%s of %s hook %s::$%s must not have a default value
Description
The parameter of a set property hook cannot declare a default value. The hook is always invoked with the value being assigned to the property, so a default value would never actually be used, and PHP rejects it as meaningless.
Example
<?php
class X
{
public string $property {
set(string $value = 'default') {
$this->property = $value;
}
}
}
?>
Literal Examples
- Parameter $value of set hook X::$property must not have a default value
Alternatives
- Remove the default value from the hook’s parameter.
- If a fallback value is needed, assign a default to the property itself, or handle it inside the hook’s body.
Related error messages
- parameter-$%s-of-%s-hook-%s::$%s-must-not-be-pass-by-reference
- parameter-$%s-of-%s-hook-%s::$%s-must-not-be-variadic
- %s-hook-of-property-%s::$%s-must-accept-exactly-one-parameters
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Parameter %d must be passed by reference
Description
When a parameter is set to be passed by reference, there is a & character before its name. In that case, the argument must be a data container, such as a variable, a property, a static property, an array index, but it cannot be a literal value, a constant, or the result of an expression.
Example
<?php
function foo(&$a) {}
// invalid cases
foo(1);
foo(1 + 2);
const A = 1;
foo(A);
class X {
const B = 2;
}
foo(X::B);
?>
Literal Examples
- foo(): Argument #1 ($a) must be passed by reference, value given
Alternatives
- Store the value in a variable and passe the variable.
- Remove the reference in the method signature.
Related error messages
In more recent PHP versions, this error message is now :ref:%s%s%s():-argument-#%d%s%s%s-must-be-passed-by-reference,-value-given.
Parameter must be an array or an object that implements Countable
Description
The count() native function only count elements that are arrays, or objects that implements the Countable interface. Anything else yields a fatal error.
Example
<?php
$value = null;
echo count($value);
?>
Alternatives
- Check for type before using count:
is_arrayorinstanceof \Countable.
In more recent PHP versions, this error message is now :ref:must-be-of-type-countable|array,-%s-given.
Parameter must have a name
Description
This is an internal error, when the engine detect that a parameter was set on a function without a name. This should not compile anyway.
Example
Alternatives
- Change of PHP version.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Parameter uses ‘parent’ as type hint although class does not have a parent!
Description
This error is a Reflection API error. It appears when the code tries to get information about the type of a parameter, that was defined as ‘parent’ while it is not a valid code.
Example
<?php
class X {
function foo(parent $a) {}
}
?>
Alternatives
- Check the name of the type before trying to instantiate it.
In more recent PHP versions, this error message is now :ref:cannot-use-"parent"-when-current-class-scope-has-no-parent.
Partial application of %s() expects %s %d arguments, %d given
Description
PHP 8.6 introduces partial function application: a ? in an argument position stands in for a value to be supplied later, and turns the call into a Closure bound to whichever arguments were already given. The placeholder ... on its own captures all of a function’s still-missing required parameters instead, but a single ? does not, so the call must still provide at least one argument slot (a value or a ?) for every required parameter.
Here, add() requires 3 arguments, but the partial application supplies only 2 slots (the value 1 and one ?), so PHP rejects it as underspecified rather than silently creating a closure that would itself fail as soon as it were called.
Example
<?php
function add($a, $b, $c) {
return $a + $b + $c;
}
$partial = add(1, ?);
?>
Literal Examples
- Partial application of add() expects exactly 3 arguments, 2 given
Alternatives
- Provide one argument slot (a value or a ? placeholder) for every required parameter, or replace the trailing ? with … to defer all remaining required parameters at once: add(1, …).
Related error messages
- partial-application-of-%s()-expects-at-most-%d-arguments,-%d-given
- cannot-combine-partial-application-and-unpacking
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Partial application of %s() expects at most %d arguments, %d given
Description
PHP 8.6 introduces partial function application: a ? in an argument position stands in for a value to be supplied later, and turns the call into a Closure bound to whichever arguments were already given. A partial-application call still can’t supply more argument slots (values or ? placeholders combined) than the target function actually declares, unless that function is itself variadic.
Here, add() declares only 2 parameters, but the partial application supplies 4 slots (1, 2, 3, and a trailing ?), so PHP rejects it instead of creating a closure that could never be called successfully.
Example
<?php
function add($a, $b) {
return $a + $b;
}
$partial = add(1, 2, 3, ?);
?>
Literal Examples
- Partial application of add() expects at most 2 arguments, 4 given
Alternatives
- Don’t supply more argument slots (values or ? placeholders) to a partial application than the function declares, unless the function itself accepts a variadic parameter.
Related error messages
- partial-application-of-%s()-expects-%s-%d-arguments,-%d-given
- cannot-combine-partial-application-and-unpacking
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
passing a negative integer to argument #3 ($width) is deprecated
Description
mb_strimwidth() trims a string to a given display width. Its $width argument used to accept negative values, in which case the width was measured from the end of the string instead of from $start.
A review of public code found essentially no real-world usage of a negative $width, and the feature made the function’s behavior harder to reason about for little benefit. As of PHP 8.3.0, passing a negative integer for this argument is deprecated.
Example
<?php
echo mb_strimwidth('Hello world', 0, -5, '...');
?>
Alternatives
- Compute the trimmed width explicitly (e.g. using
mb_strwidth()) and pass a positive value tomb_strimwidth().
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See mb_strimwidth
Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs
Description
The xxh3 and xxh128 hashing algorithms accept an optional 'secret' entry in the options array passed to hash()/hash_init(), used instead of a plain integer seed to initialize the hash. It is documented as a string, but PHP did not previously enforce that: any other type was silently converted with an implicit (string) cast, so a programmer who passed, say, an int would get a working-looking hash computed from an unintended value, with no indication anything was wrong.
As of PHP 8.4, passing a non-string ‘secret’ emits this deprecation notice before the implicit conversion happens, so the mistake is no longer silent. A future version is expected to throw a ValueError instead.
Example
<?php
try {
// 'secret' is documented as a string; passing an int silently
// converts it with (string) instead of being used as given.
hash('xxh3', 'some data', false, ['secret' => 12345]);
} catch (\Throwable $e) {
// xxh3 also requires the secret to be at least 136 bytes long once
// converted to a string -- unrelated to the type deprecation itself.
}
?>
Literal Examples
- hash(): Passing a secret of a type other than string is deprecated because it implicitly converts to a string, potentially hiding bugs
Alternatives
- Pass a string directly for ‘secret’, e.g. a value produced by random_bytes().
- If the value naturally isn’t a string, convert it explicitly and document why, e.g. [‘secret’ => (string) $value].
- Use the ‘seed’ option (an int) instead of ‘secret’ when a full custom secret is not actually needed.
Related error messages
- passing-a-seed-of-a-type-other-than-int-is-deprecated-because-it-is-ignored
- passing-a-seed-of-a-type-other-than-int-is-deprecated-because-it-is-the-same-as-setting-the-seed-to-0
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing a seed of a type other than int is deprecated because it is ignored
Description
The xxh3 and xxh128 algorithms accept an optional 'seed' entry (an int) in the options array passed to hash()/hash_init(). Unlike the older murmur3*/xxh32/xxh64 algorithms – where a non-int seed is coerced and effectively becomes 0 – these two algorithms take a different code path: when 'seed' is not an int, it is simply ignored altogether, and neither the seed nor a secret is applied. Code that believes it configured a seed silently gets the plain, unseeded hash instead.
As of PHP 8.4, passing a non-int ‘seed’ to xxh3/xxh128 emits this deprecation notice so the silent no-op is no longer invisible. A future version is expected to throw a ValueError instead.
Example
<?php
// 'seed' is documented as an int; xxh3 simply ignores it when it
// isn't one, silently falling back to the unseeded, default hash.
var_dump(hash('xxh3', 'some data', false, ['seed' => '1234']));
?>
Literal Examples
- hash(): Passing a seed of a type other than int is deprecated because it is ignored
Alternatives
- Pass an actual int for ‘seed’, e.g. [‘seed’ => 1234] rather than a numeric string.
- Cast the value explicitly if it is computed dynamically: [‘seed’ => (int) $value].
- Use ‘secret’ (a string) instead of ‘seed’ when more entropy than a single int provides is needed.
Related error messages
- passing-a-seed-of-a-type-other-than-int-is-deprecated-because-it-is-the-same-as-setting-the-seed-to-0
- passing-a-secret-of-a-type-other-than-string-is-deprecated-because-it-implicitly-converts-to-a-string,-potentially-hiding-bugs
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing a seed of a type other than int is deprecated because it is the same as setting the seed to 0
Description
The murmur3a, murmur3c, murmur3f, xxh32 and xxh64 algorithms accept an optional 'seed' entry (an int) in the options array passed to hash()/hash_init(), defaulting to 0 when not given. When a non-int value is passed, these algorithms’ code checks the type, finds it isn’t an int, and simply falls through without ever assigning it – leaving the seed at its already-initialized default of 0. The visible effect is identical to never having passed 'seed' at all, which is easy to miss since no error was raised.
As of PHP 8.4, passing a non-int ‘seed’ to one of these algorithms emits this deprecation notice. Note that xxh3/xxh128 take a related but distinct code path for the same mistake, documented separately since their non-int seed is ignored rather than treated as 0 (the two happen to behave the same when the intended seed actually was 0, but not otherwise).
Example
<?php
// 'seed' is documented as an int; murmur3a treats anything else as
// though 'seed' had simply been left at its default, 0.
var_dump(hash('murmur3a', 'some data', false, ['seed' => '1234']));
var_dump(hash('murmur3a', 'some data', false, ['seed' => 0]));
// the two lines above produce the exact same hash
?>
Literal Examples
- hash(): Passing a seed of a type other than int is deprecated because it is the same as setting the seed to 0
Alternatives
- Pass an actual int for ‘seed’, e.g. [‘seed’ => 1234] rather than a numeric string.
- Cast the value explicitly if it is computed dynamically: [‘seed’ => (int) $value].
- If a seed of 0 was genuinely intended, pass [‘seed’ => 0] explicitly instead of relying on a mistyped value falling back to it.
Related error messages
- passing-a-seed-of-a-type-other-than-int-is-deprecated-because-it-is-ignored
- passing-a-secret-of-a-type-other-than-string-is-deprecated-because-it-implicitly-converts-to-a-string,-potentially-hiding-bugs
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing an object for argument #%“ PRIu32 “ $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead
Description
mb_convert_variables() converts the character encoding of every value passed to it — strings, arrays, or objects — in place, recursing into arrays and objects alike. Each variadic argument after the first two occupies a different, dynamic position ($vars), so the deprecation names whichever argument number the object was actually found at, not a fixed one. PHP 8.6 deprecates passing an object anywhere in that variadic list, whether directly or nested inside an array.
Example
<?php
class Nested {
public $inner;
}
$nested = new Nested();
$nested->inner = 'some text';
mb_convert_variables('UTF-8', 'auto', $nested);
?>
Literal Examples
- mb_convert_variables(): Passing an object for argument #3 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead
- mb_convert_variables(): Passing an object for argument #7 $vars to mb_convert_variables() is deprecated, call get_object_vars() first instead
Alternatives
- Convert the object to an array first with
get_object_vars()and pass that instead. - Convert only the scalar string properties you need, individually.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing an object for argument #1 $array to array_walk() is deprecated, call get_object_vars() first instead
Description
array_walk() has always accepted an object in place of $array as an undocumented convenience, iterating over its accessible properties the same way it iterates array elements — including private and protected properties when called from inside the class. PHP 8.6 deprecates this implicit array/object interchangeability, since it makes visibility rules leak into what looks like ordinary array iteration.
Example
<?php
class Test {
public $foo = 'foo';
public $bar = 'bar';
}
array_walk(new Test(), function ($value, $key) {
var_dump($key, $value);
});
?>
Alternatives
- Convert the object to an array first with
get_object_vars($obj)(from outside the class) and pass that to array_walk(). - Iterate the object directly with foreach if you don’t need array_walk()’s by-reference callback semantics.
Related error messages
In more recent PHP versions, this error message is now :ref:passing-an-object-for-argument-#1-$array-to-array_walk_recursive()-is-deprecated,-call-get_object_vars()-first-instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing an object for argument #1 $array to array_walk_recursive() is deprecated, call get_object_vars() first instead
Description
Like array_walk(), array_walk_recursive() has always accepted an object in place of $array, iterating over its accessible properties (recursing into any that are themselves arrays or objects) instead of requiring an array. PHP 8.6 deprecates this implicit object handling, along with the equivalent case in array_walk().
Example
<?php
class Test {
public $foo = 'foo';
public $bar = ['x', 'y'];
}
array_walk_recursive(new Test(), function ($value, $key) {
var_dump($key, $value);
});
?>
Alternatives
- Convert the object to an array first with
get_object_vars($obj)and pass that to array_walk_recursive(). - Write a small recursive helper for objects if visibility of nested properties matters.
Related error messages
In previous PHP versions, this error message used to be :ref:passing-an-object-for-argument-#1-$array-to-array_walk()-is-deprecated,-call-get_object_vars()-first-instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing an object for argument #1 $data to http_build_query() is deprecated, call get_object_vars() first instead
Description
http_build_query()’s $data parameter is documented as taking an array, but has always also accepted an object, building the query string from its accessible (public, from outside the class) properties. PHP 8.6 deprecates passing an object directly as $data. Passing an object nested inside the array is separately deprecated too.
Example
<?php
class KeyVal {
public $public = 'input';
protected $protected = 'hello';
private $private = 'world';
}
echo http_build_query(new KeyVal());
?>
Alternatives
- Convert the object to an array first with
get_object_vars($obj)and pass that to http_build_query(). - If the object implements a mapping interface, expose its data as an array explicitly, e.g. via a dedicated method.
Related error messages
In more recent PHP versions, this error message is now :ref:object-values-within-argument-#1-$data-to-http_build_query()-being-interpreted-as-arrays-is-deprecated,.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead
Description
deflate_init()’s $options argument is documented as taking an associative array (level, memory, window, strategy, dictionary), but has always also accepted an object, reading the same keys off its public properties. PHP 8.6 deprecates passing an object here, matching the equivalent deprecation for inflate_init().
Example
<?php
class Options {
public int $level = 3;
}
$context = deflate_init(ZLIB_ENCODING_RAW, new Options());
?>
Alternatives
- Convert the object to an array first with
get_object_vars($obj)and pass that as$options. - Pass an associative array literal instead of building an options object.
Related error messages
In more recent PHP versions, this error message is now :ref:passing-an-object-for-argument-#2-$option-to-inflate_init()-is-deprecated,-call-get_object_vars()-first-instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead
Description
inflate_init()’s $options argument is documented as taking an associative array (level, memory, window, dictionary), but has always also accepted an object, reading the same keys off its public properties. PHP 8.6 deprecates passing an object here, matching the equivalent deprecation for deflate_init().
Example
<?php
class Options {
public int $window = 15;
}
$context = inflate_init(ZLIB_ENCODING_RAW, new Options());
?>
Alternatives
- Convert the object to an array first with
get_object_vars($obj)and pass that as$options. - Pass an associative array literal instead of building an options object.
Related error messages
In previous PHP versions, this error message used to be :ref:passing-an-object-for-argument-#2-$option-to-deflate_init()-is-deprecated,-call-get_object_vars()-first-instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing an object for filter parameters for %s is deprecated, call get_object_vars() first instead
Description
stream_filter_append() (and stream_filter_prepend()) pass their $params argument through to the named stream filter. The bundled zlib.deflate and zlib.inflate filters accept it as an associative array of options, but have always also accepted an object, reading the same keys off its public properties. PHP 8.6 deprecates passing an object for these two filters — the %s in the message is replaced with the filter name, zlib.deflate or zlib.inflate. The bzip2 filters have the same deprecation under distinct, filter-specific messages.
Example
<?php
class Options {
public int $level = 9;
}
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'zlib.deflate', STREAM_FILTER_WRITE, new Options());
fwrite($fp, 'Hello world');
?>
Literal Examples
- stream_filter_append(): Passing an object for filter parameters for zlib.deflate is deprecated, call get_object_vars() first instead
- stream_filter_append(): Passing an object for filter parameters for zlib.inflate is deprecated, call get_object_vars() first instead
Alternatives
- Convert the object to an array first with
get_object_vars($obj)and pass that as the filter parameters. - Pass an associative array literal instead of building an options object.
Related error messages
- passing-an-object-for-filter-parameters-for-bzip2.compress-is-deprecated,-call-get_object_vars()-first-instead
- passing-an-object-for-filter-parameters-for-bzip2.decompress-is-deprecated,-call-get_object_vars()-first-instead
In more recent PHP versions, this error message is now :ref:passing-an-object-for-filter-parameters-for-bzip2.compress-is-deprecated,-call-get_object_vars()-first-instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing an object for filter parameters for bzip2.compress is deprecated, call get_object_vars() first instead
Description
The bzip2.compress stream filter accepts its parameters as an associative array (blocksize100k, workfactor), but has always also accepted an object, reading the same keys off its public properties. PHP 8.6 deprecates passing an object here, matching the equivalent deprecation for bzip2.decompress and for the zlib filters.
Example
<?php
class ParamsCompress {
public int $blocks = 5;
public int $work = 10;
}
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'bzip2.compress', STREAM_FILTER_WRITE, new ParamsCompress());
fwrite($fp, 'Hello world');
?>
Alternatives
- Convert the object to an array first with
get_object_vars($obj)and pass that as the filter parameters. - Pass an associative array literal instead of building an options object.
Related error messages
- passing-an-object-for-filter-parameters-for-bzip2.decompress-is-deprecated,-call-get_object_vars()-first-instead
- passing-an-object-for-filter-parameters-for-%s-is-deprecated,-call-get_object_vars()-first-instead
In previous PHP versions, this error message used to be :ref:passing-an-object-for-filter-parameters-for-%s-is-deprecated,-call-get_object_vars()-first-instead.
In more recent PHP versions, this error message is now :ref:passing-an-object-for-filter-parameters-for-bzip2.decompress-is-deprecated,-call-get_object_vars()-first-instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing an object for filter parameters for bzip2.decompress is deprecated, call get_object_vars() first instead
Description
The bzip2.decompress stream filter accepts its parameters as an associative array (small, concatenated), but has always also accepted an object, or a plain boolean, reading the array-equivalent keys off an object’s public properties. PHP 8.6 deprecates passing an object here, matching the equivalent deprecation for bzip2.compress and for the zlib filters.
Example
<?php
class ParamsDecompress {
public bool $concatenated = true;
public bool $small = true;
}
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'bzip2.decompress', STREAM_FILTER_WRITE, new ParamsDecompress());
?>
Alternatives
- Convert the object to an array first with
get_object_vars($obj)and pass that as the filter parameters. - Pass an associative array literal instead of building an options object.
Related error messages
- passing-an-object-for-filter-parameters-for-bzip2.compress-is-deprecated,-call-get_object_vars()-first-instead
- passing-an-object-for-filter-parameters-for-%s-is-deprecated,-call-get_object_vars()-first-instead
In previous PHP versions, this error message used to be :ref:passing-an-object-for-filter-parameters-for-bzip2.compress-is-deprecated,-call-get_object_vars()-first-instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing bool is deprecated, use 1 or -1 instead
Description
IntlCalendar::roll() (and the procedural intlcal_roll()) add an amount to a calendar field, wrapping around instead of carrying into the next field – e.g. rolling the hour field past 23 wraps back to 0 rather than advancing the day. The $value argument is meant to be a signed int amount, but PHP has always also special-cased a bool: true is interpreted as 1 and false as -1 – not the 0 that PHP’s normal bool-to-int coercion would produce, which is itself a common source of confusion, and does not appear to serve any purpose the plain integers 1/-1 don’t already cover.
As of PHP 8.1, passing a bool for this argument emits this deprecation notice; it still works exactly as before for now, but relying on this special-cased, non-standard coercion is expected to stop being supported in a future version.
Example
<?php
$cal = IntlCalendar::createInstance('UTC');
// true/false used to mean 'roll up'/'roll down', mirroring the
// underlying ICU API, which actually expects a signed amount.
$cal->roll(IntlCalendar::FIELD_HOUR_OF_DAY, true);
?>
Literal Examples
- IntlCalendar::roll(): Passing bool is deprecated, use 1 or -1 instead
Alternatives
- Pass 1 instead of true to roll the field up by one.
- Pass -1 instead of false to roll the field down by one.
- Pass any other signed int to roll by more than one step in either direction.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing connection object as an argument is deprecated
Description
mysqli_get_client_info() reports the version of the underlying MySQL client library that PHP was compiled/linked against. This information is a property of the client library itself, not of any particular connection, so the function never actually needed a connection argument, even though its procedural signature historically accepted one for consistency with other mysqli_* functions.
Passing a connection object to this function has no effect on the result, and is deprecated as of PHP 8.1.0 to make that clear.
Example
<?php
$mysqli = mysqli_connect('localhost', 'user', 'password');
// The connection argument is ignored by this function.
echo mysqli_get_client_info($mysqli);
?>
Alternatives
- Call
mysqli_get_client_info()without arguments, e.g.mysqli_get_client_info(). - When using the object-oriented API, use
mysqli_get_client_info()(not a method call), since the client info is not connection-specific.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See mysqli_get_client_info
Passing E_USER_ERROR to trigger_error() is deprecated since 8.4, throw an exception or call exit with a string message instead
Description
The error level E_USER_ERROR is deprecated since PHP 8.4. It should be replaced with a thrown exceptions. The other levels, E_USER_NOTICE and E_USER_WARNING are still available.
Example
<?php
trigger_error('message', E_USER_ERROR);
?>
Alternatives
- Throw an execption.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See E_USER_ERROR
Passing false or null is deprecated since 8.4
Description
Passsing false or null to dba_key_split() is deprecated since PHP 8.4.
Example
<?php
var_dump(dba_key_split(null));
var_dump(dba_key_split(false));
?>
Alternatives
- Use an empty string.
Passing non-callable strings is deprecated since 8.4
Description
xml_set_processing_instruction_handler() requires a valid method to be passed. Closure, first class callable, and other callable structures are possible. When using a string, make sure it references an existing function name.
Example
<?php
// empty string is not a valid callable
xml_set_processing_instruction_handler($parser, '');
// This cannot be a valid function name
xml_set_processing_instruction_handler($parser, '123foo');
?>
Alternatives
- Use a valid function name: non empty string, and a valid name format.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing null is deprecated, instead the last opened directory stream should be provided
Description
When calling dir() twice, it was possible to use null the second time to open the same directory. Since PHP 8.1, it is not possible anymore, and the actual name of the directory must be provided.
Example
<?php
dir('/tmp'); // opens /tmp
dir(null); // opens /tmp
?>
Alternatives
- Always use the name of the directory when calling
dir().
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Passing the $mode parameter is deprecated since 8.4, as it has been ignored since 8.1
Description
mysqli_store_result() (and mysqli::store_result()) used to accept an optional $mode flag, MYSQLI_STORE_RESULT_COPY_DATA, telling mysqlnd to copy fetched data out of its internal buffer instead of referencing it directly. As of PHP 8.1, mysqlnd’s internal buffering changed and this flag no longer has any effect: the parameter is silently ignored no matter what is passed.
Since code could keep passing $mode for years without any indication that it did nothing, PHP 8.4 adds a deprecation notice specifically for that: passing the parameter at all, regardless of its value, is now reported as deprecated.
Example
<?php
$mysqli = new mysqli('localhost', 'user', 'password', 'database');
$mysqli->query('SELECT id FROM users', MYSQLI_USE_RESULT);
$result = $mysqli->store_result(MYSQLI_STORE_RESULT_COPY_DATA);
?>
Literal Examples
- Passing the $mode parameter is deprecated since 8.4, as it has been ignored since 8.1
Alternatives
- Stop passing the $mode argument (and the MYSQLI_STORE_RESULT_COPY_DATA constant) to store_result(); it has had no effect since PHP 8.1.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [The $mode parameter (MYSQLI_STORE_RESULT_COPY_DATA) already stopped having any effect in PHP 8.1, without any notice. PHP 8.4 only adds the deprecation notice; the (lack of) behavior itself is unchanged.](The $mode parameter (MYSQLI_STORE_RESULT_COPY_DATA) already stopped having any effect in PHP 8.1, without any notice. PHP 8.4 only adds the deprecation notice; the (lack of) behavior itself is unchanged.)
Passing the encoding as third parameter is deprecated. Use an explicit zero offset
Description
PHP used to recognize automatically the third parameter when it was actually the encoding, and noth the offset of start. The latter is an integer, while the former is a string.
In PHP 8.0, it is now a normal type error.
Example
<?php
// Valid in PHP 7.x
echo mb_strrpos('abc', 'a', 'utf8');
// Valid in PHP 8.+
echo mb_strrpos('abc', 'a', 0, 'utf8');
echo mb_strrpos('abc', 'a', encoding: 'utf8');
?>
Alternatives
- Use named parameters.
- Add a 0 as third parameter (the default value for offset).
In more recent PHP versions, this error message is now :ref:argument-#%d-($%s)-must-be-of-type-%s,-%s-given.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See mb_strrpos
Path cannot be empty
Description
fopen()’s first argument is of type string, though the empty string is not allowed, as it does not lead to any file.
Example
<?php
fopen('', 'r');
?>
Literal Examples
- fopen(): Path cannot be empty
Alternatives
- Check the name of the file with empty() before using it with fopen().
- Check the name of the file against ‘’ (empty string) before using it with fopen().
In previous PHP versions, this error message used to be :ref:filename-cannot-be-empty.
In more recent PHP versions, this error message is now :ref:path-must-not-be-empty.
Path must not be empty
Description
fopen()’s first argument is of type string, though the empty string is not allowed, as it does not lead to any file.
Example
<?php
fopen('', 'r');
?>
Literal Examples
- fopen(): Path cannot be empty
Alternatives
- Check the name of the file with empty() before using it with fopen().
- Check the name of the file against ‘’ (empty string) before using it with fopen().
In previous PHP versions, this error message used to be :ref:path-cannot-be-empty.
Power of base 0 and negative exponent is deprecated
Description
Requesting a negative exponent on 0 yields this error message. While PHP 8.3- used to generate INF as result, PHP 8.4 is moving toward generating a DivisionByZeroError: this will be set in PHP 9.0.
Example
<?php
$x = 0;
$y = $x ** -2;
?>
Alternatives
- Check for 0 before raising a negative power. Positive powers are OK.
- Check for negative power before raising a power of 0.
- Use the PHP 8.4 function fpow() that has the future behavior, with a try/catch structure.
Related error messages
Private constant %s::%s cannot be final as it is not visible to other classes
Description
A private constant is restricted to being used by its definition class only: as such, it is not visible to other classes, including children. A final class constant cannot be overwritten by a child class.
private and final a both mutually exclusive.
Example
<?php
class X {
private final const A = 1;
}
?>
Literal Examples
- Private constant C::A cannot be final as it is not visible to other classes
Alternatives
- Relax the private keyword with protected, or public.
- Remove the final keyword.
Private methods cannot be final as they are never overridden by other classes
Description
Final methods are only available in the class where they are defined. If such a method is defined in one of the child class, it is considered a distinct method. As such, the final keyword doesn’t apply, and even is misleading.
Example
<?php
class X {
private final function foo() {}
}
?>
Alternatives
- Remove the final keyword in the method definition.
- Change the visibility to protected to public.
Producing output from user output handler %s is deprecated
Description
A user output handler registered with ob_start() is expected to receive the current buffer contents and return the (possibly transformed) string to send further down the output stack. Historically, nothing prevented such a handler from also producing its own output directly (for instance with echo or print), in addition to returning a value.
Output produced this way bypasses the normal buffering contract and is silently discarded, which usually indicates a bug in the handler rather than an intentional behavior. As of PHP 8.5.0, doing so raises a deprecation notice naming the offending handler.
Example
<?php
ob_start(function (string $buffer): string {
// Directly emitting output from the handler, instead of
// only returning the transformed buffer.
echo 'debug: ', strlen($buffer), " bytes\n";
return $buffer;
});
echo 'Hello world';
ob_end_flush();
?>
Alternatives
- Only communicate the processed content through the handler’s return value; do not
echo/printfrom within it.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See ob_start
Property %s does not exist
Description
This error happens when the Reflection API fails at getting the description of a non-existent property. The name of the property should be checked before using the getProperty method.
Example
<?php
$class = new ReflectionClass('ReflectionClass');
$property = $class->getProperty('unkown');
var_dump($property);
?>
Literal Examples
- Property unknown does not exist
Alternatives
- Check that the property exists before using
getProperty.
Related error messages
In more recent PHP versions, this error message is now :ref:property-%s::$%s-does-not-exist.
Property %s::$%s cannot have type %s
Description
Some native PHP types are not allowed with a property. This is the case of void, never and callable. Any mention of them, alone or in a compsed type generates this error.
Example
<?php
class X {
public callable|int $property = 1;
}
?>
Literal Examples
- Property x::$p cannot have type callable
Alternatives
- Remove any illegal type from the definition of the property.
- Remove all types from the definition of the property.
Related error messages
- class-constant-%s::%s-cannot-have-type-%s
- default-value-for-property-of-type-%s-may-not-be-null.-use-the-nullable-type-%s-to-allow-null-default-value
Property %s::$%s does not exist
Description
This error happens when the Reflection API fails at getting the description of a non-existent property. The name of the property should be checked before using the getProperty method.
Example
<?php
$class = new ReflectionClass('ReflectionClass');
$property = $class->getProperty('unkown');
var_dump($property);
?>
Literal Examples
- Property ReflectionClass::$unknown does not exist
Alternatives
- Check that the property exists before using
getProperty.
Related error messages
In previous PHP versions, this error message used to be :ref:property-%s-does-not-exist.
Property cannot be both final and private
Description
When a property is final, it cannot be overridden in a child class; when a class is private, it is only available in the current class.
Hence, a property cannot be final and private at the same time.
In this situation, the property may not final, as there are no property hooks.
Example
<?php
class X {
final private $p;
}
?>
Alternatives
- Remove the hooks, and use the magic methods __get/__set.
- Remove the final keyword.
- Remove the private keyword and use protected or public.
In previous PHP versions, this error message used to be :ref:cannot-use-the-final-modifier-on-a-property.
Property hook cannot be both abstract and final
Description
This error is emitted when a property is defined in an interface, with the final option. There, a property hook is automatically abstract, as it is part of an interface, so the abstract option is understated.
In a class or a trait, the reported error is that abstract is not allowed on a property hook.
Example
<?php
interface I {
public int $p {
final get;
}
}
?>
Alternatives
- Remove the
finaloption from the property hook.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Property hook cannot be both abstract and private
Description
Property hook may be private, as in only available to current class, or abstract, as in always redefined in a child class, but not both at the same time.
It is the same as for methods.
Example
<?php
class X {
private abstract $property { get; }
}
?>
Alternatives
- Make the method protected or public.
- Remove the abstract keyword.
Property hook cannot be both final and private
Description
When a property is final, it cannot be overridden in a child class; when a class is private, it is only available in the current class.
Hence, a property cannot be final and private at the same time.
In this situation, the property may be final, due to the property hooks. A property without hooks cannot be final.
Example
<?php
class X {
private $p {
final get => 2;
set => $this->p = $value;
}
}
?>
Alternatives
- Remove the hooks, and use the magic methods __get/__set.
- Remove the final keyword.
- Remove the private keyword and use protected or public.
Property hook list must not be empty
Description
It is possible to add a block, after a property definition. This is where the get and set methods are defined. There can be one or two of these methods, but the block just cannot be left empty.
Example
<?php
class X {
public int $p = 3 { }
}
?>
Alternatives
- Create at least one accessor method in the block.
- Remove the block.
Property in interface cannot be explicitly abstract.
Description
While PHP 8.4 supports properties in an interface, as long as they are defining hooks, it is not possible to use explicitly the option abstract.
Example
<?php
interface I {
abstract $p { get; }
}
?>
Alternatives
- Remove the option
abstract. May be usepublicinstead. - Move the property definition to an abstract class.
Property in interface cannot be final
Description
While PHP 8.4 supports properties in an interface, as long as they are defining hooks, it is not possible to use the final option: in fact, the property hook does not have a body, so there is no code to finalize.
Example
<?php
interface I {
final $p { get; }
}
?>
Alternatives
- Remove the
finaloption. - Move the property definition to an abstract class.
Property in interface cannot be protected or private
Description
While PHP 8.4 supports properties in an interface, as long as they are defining hooks, it is not possible to use another visibility than public.
Example
<?php
interface I {
private $p { get; }
}
?>
Alternatives
- Make the property visible.
- Move the property definition to an abstract class.
Property with asymmetric visibility %s::$%s must have type
Description
Asymmetric visibility, such as protected(set) only applies to a typed property.
Example
<?php
class X {
static protected(set) int $property;
}
?>
Literal Examples
- Property with asymmetric visibility x::$property must have type
Alternatives
- Remove the asymmetric property.
- Add a type to the property.
Property x::$p cannot have type void
Description
Void is a type, that can only be used with return type, on methods or functions. Here, void represents the absence of value: this is not possible for a property or an argument. The null value is then the closest possible type that can be assigned to a property, yet representing no value.
Example
<?php
class X {
private void $property;
}
?>
Alternatives
- Use another type for the property.
- Remove the property.
- Use the null type.
Related error messages
Related error messages
Providing a string that is not one byte long is deprecated. Use ord($str[0]) instead
Description
The ord() function returns the ordinal value of the first byte of a string. When the provided string is longer than one byte, only the first byte is used and the remaining bytes are silently discarded. This implicit behavior is a source of confusion, especially when working with multi-byte encodings such as UTF-8, where a single character may span several bytes. To make the intent explicit, use the $str[0] syntax to extract the first byte before passing it to ord().
Example
<?php
$str = '我';
echo ord($str);
?>
Alternatives
- Use the
$str[0]rather than the whole string. - Use
substr($str, 0, 1)on the string, as long as the string is not multi-byte.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See ordNonSingleByteString
Providing a value not in-between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. The value used will be constrained using %% 256
Description
chr() builds a one-character string from an integer code point, but a string byte can only hold a value between 0 and 255. Historically, chr() accepted any int and silently wrapped out-of-range values by computing value %% 256, so chr(256) quietly produced the same byte as chr(0). This is almost always the sign of an arithmetic mistake upstream (an off-by-one, a missing modulo, a value that was never validated).
As of PHP 8.5, calling chr() with a value outside the [0, 255] interval emits this deprecation notice. The returned byte is unchanged – PHP still applies %% 256 to constrain the value – so existing output is not affected, but code should stop relying on the implicit wrap.
Example
<?php
// A byte can only hold a value in [0, 255]; anything outside
// that range was silently wrapped with % 256.
echo chr(256); // same as chr(0)
echo chr(-1); // same as chr(255)
?>
Literal Examples
- chr(): Providing a value not in-between 0 and 255 is deprecated, this is because a byte value must be in the [0, 255] interval. The value used will be constrained using %% 256
Alternatives
- Apply the modulo explicitly before calling chr(), e.g. chr($value %% 256), so the intent is documented and the notice is silenced.
- Validate the value is already within [0, 255] before calling chr(), and handle out-of-range input as an error instead of wrapping it.
- If you are building a UTF-8 string from a code point rather than a raw byte, use mb_chr() instead of chr().
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Providing an empty string is deprecated
Description
Calling ord() with an empty string is like calling it without an argument: it has nothing to work on.
Example
<?php
ord('');
?>
Alternatives
- Remove the call ord() on empty string.
- Check that the length of the string passed to ord() is 1.
- Ensure that the string is in latin1 encoding: multi-byte strings will also lead to an error.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See emptyStringWithOrd
Providing an object to argument #1 ($sessionhandler) which does not have the create_sid() method defined is deprecated
Description
create_sid() and validateId() currently live on the optional SessionIdInterface / SessionUpdateTimestampHandlerInterface, so a handler passed to session_set_save_handler() can implement SessionHandlerInterface alone and simply lack them; PHP silently falls back to its built-in session ID generation. Both methods are being folded into SessionHandlerInterface itself, so PHP 8.6 deprecates supplying a handler object that doesn’t define create_sid() — it will become mandatory in PHP 9.0.
Example
<?php
class SessionHandlerTester implements SessionHandlerInterface {
public function close(): bool { return true; }
public function destroy($id): bool { return true; }
public function gc($max_lifetime): int|false { return 1; }
public function open($path, $name): bool { return true; }
public function read($id): string { return ''; }
public function write($id, $data): bool { return true; }
// create_sid() intentionally not implemented
}
session_set_save_handler(new SessionHandlerTester());
session_start();
?>
Alternatives
- Implement a public create_sid(): string method on the session handler, generating an unpredictable, unique session ID.
- Implement SessionIdInterface explicitly so the requirement is visible at the class declaration.
Related error messages
In more recent PHP versions, this error message is now :ref:providing-an-object-to-argument-#1-($sessionhandler)-which-does-not-have-the-validateid()-method-defined-is-deprecated.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Providing an object to argument #1 ($sessionhandler) which does not have the validateId() method defined is deprecated
Description
validateId() currently lives on the optional SessionUpdateTimestampHandlerInterface, so a handler passed to session_set_save_handler() can implement only SessionHandlerInterface and lack it; with session.use_strict_mode enabled, PHP falls back to accepting any externally supplied session ID without validating it, weakening the protection strict mode is meant to provide. validateId() is being folded into SessionHandlerInterface itself, so PHP 8.6 deprecates supplying a handler object that doesn’t define it — it will become mandatory in PHP 9.0.
Example
<?php
class SessionHandlerTester implements SessionHandlerInterface {
public function close(): bool { return true; }
public function destroy($id): bool { return true; }
public function gc($max_lifetime): int|false { return 1; }
public function open($path, $name): bool { return true; }
public function read($id): string { return ''; }
public function write($id, $data): bool { return true; }
// validateId() intentionally not implemented
}
session_set_save_handler(new SessionHandlerTester());
session_start();
?>
Alternatives
- Implement a public validateId(string $id): bool method on the session handler that checks whether the given ID already exists in storage.
- Implement SessionUpdateTimestampHandlerInterface (which also adds updateTimestamp()) explicitly so the requirement is visible at the class declaration.
Related error messages
In previous PHP versions, this error message used to be :ref:providing-an-object-to-argument-#1-($sessionhandler)-which-does-not-have-the-create_sid()-method-defined-is-deprecated.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Providing individual callbacks instead of an object implementing SessionHandlerInterface is deprecated
Description
session_set_save_handler() used to accept six to to nine distinct callables to configure the handler. In fact, that PHP native function was available even before PHP had objects support.
Nowadays, there still needs that many callables, but they are expected to be grouped in a class, and checked by the SessionHandlerInterface interface.
Example
<?php
session_set_save_handler(
session_open(...),
session_close(...),
session_read(...),
session_write(...),
session_destroy(...),
session_gc(...),
session_create_sid(...),
session_validate_sid(...),
session_update_timestamp(...)
);
?>
Alternatives
- Refactor the callables into a class, add the
SessionHandlerInterfaceimplementation and use that class.
Readonly class %s cannot extend non-readonly class %s
Description
A readonly class cannot extends a non-readonly class; a non-readonly class cannot extends a readonly class. Both classes must be readonly or non-readonly to be able to extends one another. This is due to readonly being applied to all available properties, which is ambiguous with class hierarchies.
Example
<?php
class Foo
{
}
readonly class Bar extends Foo
{
}
?>
Literal Examples
- Readonly class Foo cannot extend non-readonly class Bar
Alternatives
- Make both classes readonly.
- Make both classes non-readonly.
- Make both classes non-readonly and apply readonly per properties.
Related error messages
Readonly class %s cannot use trait with a non-readonly property %s::$%s
Description
When a class is readonly, then even the properties added to the class from a trait have to be readonly. Since a trait cannot be readonly, like a class, then each of the properties in the trait, have to be readonly.
Also, note that PHP checks all the traits and the traits of the traits, for readonly properties.
Example
<?php
trait T {
private $property;
}
readonly class X {
use T;
}
?>
Literal Examples
- Readonly class x cannot use trait with a non-readonly property t::$a
Alternatives
- Remove the readonly on the class and apply to all each property in the class.
- Make each of the property in the trait, and its dependencies, readonly.
Readonly property %s::$%s cannot have default value
Description
A readonly property is expected to be set once, and only once, at execution time. Then, it is not changed anymore.
A property, whose value is known at compilation time should probably be a constant.
Example
<?php
class T {
public readonly int $i = 1;
}
?>
Literal Examples
- Readonly property x::$i cannot have default value
Alternatives
- Drop the readonly option.
- Make the property a class constant.
Related error messages
Readonly property %s::$%s must have type
Description
A readonly property must be typed. It cannot be left without a type. In case of need of a wide range of types, use an union type, or the mixed keyword.
Example
<?php
class X {
private readonly $property;
}
?>
Literal Examples
- Readonly property X::$property must have type
Alternatives
- Use the
mixedtype to explicitly type the property, but not commit to any constraint. - Use an union type to explicitly type the property, and commit to a restricted list of types.
- Use the actual type for the property.
- Remove the
readonlyoption.
Recursion detected
Description
The compact function accepts an array of arguments. The function is actually recursive, and searches for everything recursively. This leads to potential infinite recursion, if the provided array contains a link to itself.
Example
<?php
$a = 1;
$arr1 = array('a', &$arr1);
try {
var_dump(compact($arr1));
} catch (Error $e) {
echo $e->getMessage() . \n;
}
?>
Alternatives
- Flatten the array into one level only.
- Remove the self references.
- Do not use array known to host self references, such as
$GLOBALS.
Redefinition of parameter $%s
Description
Parameters must all have distinct names in a method signature. Before PHP 7.0, no error was emitted, and the last parameter’s value was used. In PHP 7.0 and more recent, it is a compilation error.
Example
<?php
function foo($b, $b, $b) {}
?>
Literal Examples
- Redefinition of parameter $b
Alternatives
- Use all different names for the parameters.
ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists
Description
ReflectionClass::getConstant() returns false both when the requested constant does not exist and when the constant’s actual value is false, so the return value alone cannot tell the two cases apart. Calling it for a constant that does not exist is now deprecated in favour of an explicit existence check.
Example
<?php
class X {
const FOO = 1;
}
$class = new ReflectionClass(X::class);
$value = $class->getConstant('BAR');
var_dump($value);
?>
Literal Examples
- ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists
Alternatives
- Call
ReflectionClass::hasConstant()first, and only callgetConstant()once existence is confirmed.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See ReflectionClass::getConstant
ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists
Description
ReflectionProperty::getDefaultValue() returns null both when the property genuinely defaults to null and when the property has no default value at all (such as an uninitialized typed property), so the return value alone cannot tell the two cases apart. Calling it for a property that has no default value is now deprecated in favour of an explicit existence check.
Example
<?php
class X {
public int $prop;
}
$r = new ReflectionProperty(X::class, 'prop');
var_dump($r->getDefaultValue());
?>
Literal Examples
- ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists
Alternatives
- Call
ReflectionProperty::hasDefaultValue()first, and only callgetDefaultValue()once a default value is confirmed to exist.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See ReflectionProperty::getDefaultValue
Requested precision of %d digits was truncated to PHP maximum of %d digits
Description
A decimal number is being represented as a string, with a precision which is above the precision available to PHP itself. Since no more data is available, the requested precision was not met.
Example
<?php
printf(%.988f,1.23456789e10);
?>
Literal Examples
- Requested precision of 20 digits was truncated to PHP maximum of 14 digits
Alternatives
- Reduce the requested precision, down to 54 maximum.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Required parameter $%s follows optional parameter $%s
Description
An optional parameter has a default value, while a required parameter doesn’t. In a method signature, PHP recommends to set the required parameters first, then the optional parameter.
When this is not the case, PHP is unable to understand if an argument has to be assigned to a parameter, or if it can be skipped, and assigned to the next required. When this happens, any required parameter makes previously defined parameter also required.
Example
<?php
function foo($a = 1, $b) {}
?>
Literal Examples
- Required parameter $b follows optional parameter $b
Alternatives
- Remove the default value of the early optional parameter.
- Add a default value of the late required parameter.
In more recent PHP versions, this error message is now :ref:optional-parameter-$%s-declared-before-required-parameter-$%s-is-implicitly-treated-as-a-required-parameter.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See OptionalParameterLast
Required Trait %s wasn’t added to %s
Description
This error happens during name conflict resolution for traits. It means that one of the mentioned trait is not use in the code, and cannot be replaced or replacing another method. In the example below, the trait T2 is mentioned, but is not in the use command.
Example
<?php
trait T1 {
function foo() {echo "T1\n";}
}
trait T2 {
function foo() {echo "T2\n";}
}
class C {
use T1 {
T2::foo insteadof T1;
}
}
?>
Literal Examples
- Required Trait T2 wasn’t added to C
Alternatives
- Add the missing trait to the class.
- Remove the extra name resolution from the class.
Return type of %s::%s() should either be compatible with %s::%s(): mixed
Description
Native PHP interfaces, which define a type, expect the derived methods to use the same time. In particular, a mixed return type was added to some interfaces and must be available with child classes.
Since PHP 8.1, the mixed return type is now enforced, and a deprecated notice is displayed.
One alternative is to add the expected return type; a temporary solution is to the #[ReturnTypeWillChange] attribute. The attribute makes the warning disappear, but must be updated in the long run to keep in line with PHP recommendations.
This rule covers the following interfaces :
- ArrayAccess
- Countable
- Exception
- FilterIterator
- Iterator
- JsonSerializable
- php_user_filter
- SessionHandlerInterface.
Example
<?php
class MyJsonSerialize implements JsonSerialize {
function jsonserialize() : int {}
}
?>
Literal Examples
- Return type of MyJsonSerialize::jsonserialize() should either be compatible with JsonSerialize::jsonserialize(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice
Alternatives
- Use the correct return type for the methods from the interfaces.
- Use the the
#[ReturnTypeWillChange]to hide the error message. - Remove the interface from this class.
- Remove the offending method.
Return value of %s%s%s() must %s%s%s, %s%s returned
Description
The type of the returned value must match the type of the method signature.
With strict_types, PHP refuses anything that is not compatible with the returned type: returning ‘123’ (123 as a string), or 123.00 (123 as float) is forbidden.
Without strict_types, PHP tries to convert the value to int, and only produces an error when it cannot.
Example
<?php
function foo() : int {
return 'abc';
}
?>
Literal Examples
- Return value of foo() must be int, string returned
Alternatives
- Use a cast to force the type to the desired returntype.
- Check the type before returning it.
- Remove the return type.
- Remove strict_types.
Related error messages
Returning a value from a constructor is deprecated
Description
new X always evaluates to the newly created instance, no matter what __construct() returns: any value returned from a constructor is discarded.
Since explicitly returning a value from __construct() is therefore always misleading dead code, PHP 8.6 deprecates it. A bare return; with no expression, used purely to exit the constructor early, remains unaffected.
Example
<?php
class X {
public function __construct() {
return 42;
}
}
$x = new X;
var_dump($x);
?>
Literal Examples
- Returning a value from a constructor is deprecated
Alternatives
- Use a bare
return;(with no expression) to exit the constructor early. - If you need to build and hand back an object based on some logic, use a static factory method instead of relying on
newand a constructor return value.
Related error messages
- returning-a-value-from-a-destructor-is-deprecated
- making-a-constructor-a-generator-is-deprecated
- constructor-%s::%s()-cannot-declare-a-return-type
- method-%s::__construct()-cannot-declare-a-return-type
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See constructorReturnDeprecated
Returning a value from a destructor is deprecated
Description
__destruct() is invoked automatically by PHP’s garbage collector when an object is about to be destroyed; nothing ever reads or uses its return value.
Since explicitly returning a value from __destruct() is therefore always dead code, PHP 8.6 deprecates it. A bare return; with no expression, used purely to exit the destructor early, remains unaffected.
Example
<?php
class X {
public function __destruct() {
return 42;
}
}
$x = new X;
unset($x);
?>
Literal Examples
- Returning a value from a destructor is deprecated
Alternatives
- Use a bare
return;(with no expression) to exit the destructor early. - Remove the
return $value;statement; if you need to signal something to calling code, do it before the object is unset, not from the destructor.
Related error messages
- returning-a-value-from-a-constructor-is-deprecated
- making-a-destructor-a-generator-is-deprecated
- destructors-cannot-declare-a-return-type
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See constructorReturnDeprecated
Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero
Description
usort() requires a callback function, that is used to put set the order in the array. This function must return three different values:
- 1 if
$a > $b - 0 if
$a == $b - -1 if
$a < $b
The return type should be the integer subset [1, 0, -1], and since there is no such type in PHP, the int type shall be used.
This is exactly compatible with the spaceship operator <=>.
Also, note that any positive integer is considered as 1, and any negative integer is considered as -1.
This applies to usort(), uasort(), uksort().
Not that without declare(strict_types=), the integer result of the callback is converted into a boolean, where 1 and -1 are both true. This may lead to strange results.
Example
<?php
function foo($a, $b): bool { return $a > $b; }
$array = [4, 2, 3, 0];
usort($array, foo(...));
?>
Alternatives
- Use the
intreturn type. - Remove the return type.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See sortClosureReturnType
Returning bool from comparison function is deprecated
Description
The comparison function should return 0, 1 or -1, and not just booleans. 1 means that $a > $b, -1 that $a < $b and 0 means that $a === $b. This is a richer information than boolean, and it also fits very well with the spaceship operator <=>.
Example
<?php
function mySort(int $a, int $b) : bool {
return $a > $b;
}
$array = [1,2,3,4,5,6,7,8,9,10];
usort($array, mySort(...));
?>
Alternatives
- Set the returntype of the comparison function to int.
- Use the spaceship operator as possible.
- Cast the result to integer.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See sortClosureReturnType
Returning by reference from a void function is deprecated
Description
The return type void means that no value is returned, not even NULL. This means that the & option has no value here. Since PHP 8.1, this is reported as deprecated.
In the end, it has no value to collect the returned value of a void function, reference or not.
Example
<?php
function &foo() : void { }
?>
Alternatives
- Do not collect the returned valueo of a void function.
- Remove the reference in the method definition.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See return_reference_on_void
Returning from a finally block is deprecated
Description
A return statement inside a finally block always wins: it replaces whatever the try or catch block was about to return, and it silently swallows any exception that was propagating out of the try. Unlike the other abrupt exits from a finally block, which PHP already forbids outright (break, continue and goto out of a finally are compile errors, and a throw automatically chains the discarded exception as $previous), return gave no indication that anything had been dropped.
PHP 8.6 deprecates this pattern. It remains legal for now, but the discarded return value or exception should be treated as a latent bug.
Example
<?php
function getConfig(): array {
try {
return loadConfig(); // may throw
} finally {
return []; // the exception, or the try's return value, is silently discarded
}
}
?>
Literal Examples
- Returning from a finally block is deprecated
Alternatives
- Move the return statement out of the finally block, into the try or after it.
- If the intent is to override the result deliberately, do so explicitly outside the finally block so the discarded value or exception is visible.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Previously, returning from a finally block silently discarded any pending exception or return value from the try/catch, with no warning. As of PHP 8.6, doing so emits a deprecation notice.](Previously, returning from a finally block silently discarded any pending exception or return value from the try/catch, with no warning. As of PHP 8.6, doing so emits a deprecation notice.)
Returning null from %s::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead
Description
The __debugInfo() magic method controls what var_dump() displays for instances of the class. It must return an array; historically, returning null was also tolerated and treated the same as an empty array (hiding all properties).
This message is emitted at class-declaration time whenever __debugInfo() is declared with a return type that allows null (?array, array|null, and similar), regardless of whether the method is ever actually called or ever really returns null. Since null and [] are handled identically, keeping the return type nullable serves no purpose, so PHP 8.6 deprecates it in favor of a strict array return type.
This is a compile-time counterpart to “Returning null from %s::__debugInfo() is deprecated, return an empty array instead”, which instead fires at call time for a method that has no return type declared at all but returns null anyway.
Example
<?php
class X {
public function __debugInfo(): ?array {
return null;
}
}
var_dump(new X);
?>
Literal Examples
- Returning null from X::__debugInfo() is deprecated, make the return type non-nullable and return an empty array instead
Alternatives
- Declare
__debugInfo(): arrayinstead of__debugInfo(): ?array(orarray|null). - Return an empty array
[]instead ofnullfrom__debugInfo().
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Returning null from %s::__debugInfo() is deprecated, return an empty array instead
Description
The __debugInfo() magic method allows a class to customize what var_dump() displays for its instances. When this method returns null, PHP has historically treated it as an empty array, but the behavior was inconsistent.
Since PHP 8.4, returning null from __debugInfo() is deprecated. This deprecation ensures consistent behavior and explicit return types.
Returning an empty array [] achieves the same effect (hides all properties from var_dump()) while being type-safe and unambiguous.
Example
<?php
class X {
public function __debugInfo(): ?array {
return null;
}
}
var_dump(new X);
?>
Literal Examples
- Returning null from X::__debugInfo() is deprecated, return an empty array instead
Alternatives
- Return an empty array
[]instead ofnullfrom__debugInfo(). - Remove the
__debugInfo()method entirely if you want the defaultvar_dump()behavior. - Return the array of properties you want to display:
return ['key' => $this->value];.
Related error messages
- method-%s::%s()-cannot-be-static
- returning-null-from-%s::__debuginfo()-is-deprecated,-make-the-return-type-non-nullable-and-return-an-empty-array-instead
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See debugInfoCannotReturnNull
Security level must be one of “noAuthNoPriv”, “authNoPriv”, or “authPriv”
Description
The third argument of snmp3_get() must be one of the following values, “noAuthNoPriv”, “authNoPriv”, or “authPriv”. Case is important. There are not constants to for these values.
Example
<?php
try {
var_dump(snmp3_get($hostname, $community, '', '', '', '', '', '.1.3.6.1.2.1.1.1.0'));
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
?>
Alternatives
- Use one of the three possible values.
Security protocol must be one of “AES128”, or “AES E_ERROR
Description
The fourth argument of snmp3_get() must be one of the following values, “AES128”, or “AES”.
The DES protocol must be inactive to see this error message. Otherwise, a distinct message is displayed.
Case is important. There are not constants to for these values.
Example
<?php
try {
var_dump(snmp3_get($hostname, $community, '', 'protocol', '', '', '', '');
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
?>
Alternatives
- Use one of the two possible values.
Related error messages
Security protocol must be one of “DES”, “AES128”, or “AES E_ERROR
Description
The fourth argument of snmp3_get() must be one of the following values, DES, AES128, or AES.
The DES protocol must be active to see this error message. Otherwise, a distinct message is displayed.
Case is important. There are not constants to for these values.
Example
<?php
try {
var_dump(snmp3_get($hostname, $community, '', 'protocol', '', '', '', '');
} catch (\ValueError $e) {
echo $e->getMessage() . \PHP_EOL;
}
?>
Alternatives
- Use one of the three possible values.
Related error messages
Serialization of %s is not allowed, override __serialize() and __unserialize() to implement it
Description
Some internal classes hold state, such as a connection handle or a resource, that cannot be meaningfully turned into a string and restored later. To prevent silent data loss or unusable objects after unserialize(), PHP flags these classes as not serializable by default. Since PHP 7.4, a class can opt back in by implementing the __serialize() and __unserialize() magic methods, giving full control over what state is actually persisted and how it is restored. Trying to serialize() an instance of such a class, or of a subclass that does not add these methods, throws this exception.
Example
<?php
$pdo = new PDO('sqlite::memory:');
$data = serialize($pdo);
?>
Literal Examples
- Serialization of PDO is not allowed, override __serialize() and __unserialize() to implement it
Alternatives
- Create a subclass that implements
__serialize()and__unserialize()to control exactly which state is persisted. - Avoid serializing the object directly; store only the data needed to recreate it, then reconstruct it manually.
Related error messages
In more recent PHP versions, this error message is now :ref:unserialization-of-%s-is-not-allowed,-override-__serialize()-and-__unserialize()-to-implement-it.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Session callback must have a return value of type bool, %s returned
Description
The callbacks registered through session_set_save_handler() (open, close, read, write, destroy, gc, etc.) are expected to return a value of type bool to report success or failure, matching the signatures declared by SessionHandlerInterface.
Some older session handlers followed the pre-PHP 7 convention of C-style save handlers, returning an integer (0 for success, a negative value such as -1 for failure) instead of true/false. PHP still accepts 0 and -1 for backward compatibility, but as of PHP 8.0.0 it emits a deprecation notice naming the actual type/value returned; any other non-bool return value triggers a TypeError instead.
Example
<?php
session_set_save_handler(
open: fn (string $path, string $name): bool => true,
close: fn (): bool => true,
read: fn (string $id): string => '',
// Legacy convention: 0 for success, -1 for failure,
// instead of returning a real bool.
write: fn (string $id, string $data): int => 0,
destroy: fn (string $id): bool => true,
gc: fn (int $max_lifetime): int => 0,
);
session_start();
?>
Alternatives
- Make every session handler callback explicitly return
trueorfalse. - Implement
SessionHandlerInterfaceon a dedicated class instead of passing loose callables, so the return types are enforced.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See session_set_save_handler
session.sid_bits_per_character INI setting is deprecated
Description
session.sid_bits_per_character used to control how many bits of entropy each character of a generated session ID encodes (from 4, hexadecimal, up to 6, a larger custom alphabet), in combination with session.sid_length.
Letting this be configurable made it possible to end up with weak, easily-guessable session IDs if the values were lowered, without much practical benefit from raising them either. PHP 8.4 fixes the format to a 32-character hexadecimal session ID (4 bits per character) and deprecates the directive; it is only emitted when the value is set to something other than the fixed default of 4.
Example
<?php
ini_set('session.sid_bits_per_character', '5');
?>
Alternatives
- Remove
session.sid_bits_per_characterfromphp.iniand from the code; PHP now always uses a 32-character hexadecimal session ID.
Related error messages
In more recent PHP versions, this error message is now :ref:session.sid_length-ini-setting-is-deprecated.
session.sid_length INI setting is deprecated
Description
session.sid_length used to control the number of characters in a generated session ID, in combination with session.sid_bits_per_character.
Letting this be configurable made it possible to end up with weak, easily-guessable session IDs if the value was lowered too much. PHP 8.4 fixes the format to a 32-character session ID and deprecates the directive; it is only emitted when the value is set to something other than the fixed default of 32.
Example
<?php
ini_set('session.sid_length', '26');
?>
Alternatives
- Remove
session.sid_lengthfromphp.iniand from the code; PHP now always uses a 32-character session ID.
Related error messages
In previous PHP versions, this error message used to be :ref:session.sid_bits_per_character-ini-setting-is-deprecated.
Set access level of %s::$%s must be %s (as in class %s)%s
Description
This error is specific to asymmetric visibility. A property may expose a wider visibility for reading than for writing, for example public protected(set) string $foo, which can be read from anywhere but only written from within the class or its subclasses.
When a child class redeclares such a property, the write (set) visibility it declares must be the same as, or weaker (more permissive) than, the one inherited from the parent. It cannot be narrowed. In the example, the parent grants write access to protected(set), but the child tries to restrict it further to private(set), which is forbidden.
The same error is raised, with an omitted access level instead of a named one, when the parent property has no explicit set-visibility restriction at all (a plain read/write property, or a hooked virtual property whose get hook exists but set hook does not restrict visibility): in that case, the child is not allowed to introduce any set-visibility restriction, since that would also be a narrowing of what the parent allows.
A property declared readonly implicitly behaves as write-once with an asymmetric set visibility, so this error can also surface when a plain or hooked property overrides, or implements, a readonly property with looser write access.
Example
<?php
class A {
public protected(set) string $foo;
}
class B extends A {
public private(set) string $foo;
}
?>
Literal Examples
- Set access level of B::$foo must be protected(set) (as in class A) or weaker
- Set access level of B::$foo must be omitted (as in class A)
Alternatives
- Use the same set-visibility keyword as the parent class (or omit it, if the parent has none).
- Widen the set-visibility of the child property so that it is the same as, or weaker than, the parent’s.
- Remove the asymmetric visibility from the child property altogether.
Related error messages
- access-level-to-%s::%s-must-be-%s-(as-in-%s-%s)%s
- set-type-of-%s::$%s-must-be-supertype-of-%s-(as-in-%s-%s)
- cannot-override-final-property-hook-%s::%s()
- access-level-to-%s::$%s-must-be-%s-(as-in-class-%s)%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Set type of %s::$%s must be supertype of %s (as in %s %s)
Description
A property hooked with a set hook can accept a wider range of values than its declared (get) type, since the set hook is free to convert or narrow whatever it receives before storing it. In the example, I::$prop accepts both int and string on write, even though it only ever reads back as string.
When a class overrides such a property, whether by extending a parent class or implementing an interface, the type accepted on write by the new declaration must remain a supertype of (or equal to) the type accepted by the original declaration. It must not be narrowed.
In the example, C::$prop is a plain property, so it can only be assigned values of its own declared type, string. This is narrower than the int|string accepted by I::$prop’s set hook, so code that relied on I’s contract to pass an int to $prop would break. Consequently, PHP rejects the composition.
Example
<?php
interface I {
public string $prop {
set(int|string $value);
}
}
class C implements I {
public string $prop;
}
?>
Literal Examples
- Set type of C::$prop must be supertype of string|int (as in interface I)
Alternatives
- Give the child property (or its
sethook parameter) a type that is the same as, or a supertype of, the type accepted by the parent’ssethook. - Add an explicit
sethook to the child property, accepting the same or a wider type than the parent. - Narrow the type accepted by the parent’s
sethook instead, if the wider type is not actually needed.
Related error messages
- type-of-parameter-$%s-of-hook-%s::$%s::set-must-be-compatible-with-property-type
- type-of-%s::$%s-must-be-%s%s-(as-in-class-%s)
- set-access-level-of-%s::$%s-must-be-%s-(as-in-class-%s)%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
setlocale() expects exactly 2 arguments when argument #2 ($locales) is an array, %d given
Description
setlocale() accepts a locale to try either as one or more separate string arguments (each tried in turn until one succeeds), or as a single array of candidate locale strings passed as $locales. Since PHP 8.6, mixing the two forms in the same call, an array followed by further trailing string arguments, is rejected outright: when $locales is an array, it must be the only argument supplied after $category.
Example
<?php
setlocale(LC_ALL, ['en_US.UTF-8', 'C'], 'fr_FR.UTF-8');
?>
Literal Examples
- setlocale() expects exactly 2 arguments when argument #2 ($locales) is an array, 3 given
Alternatives
- Pass the candidate locales either as separate string arguments (setlocale($category, $a, $b, …)) or as a single array ($category, [$a, $b, …]), but not both in the same call.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.6, this combination was silently accepted: PHP tried each candidate in the array first, then went on to also try any trailing string arguments as further candidate locales, instead of rejecting the mixed call.](Prior to PHP 8.6, this combination was silently accepted: PHP tried each candidate in the array first, then went on to also try any trailing string arguments as further candidate locales, instead of rejecting the mixed call.)
Spread operator is not supported in assignments
Description
The spread operator cannot be used with the list() operator. It may be used to spread an array into arguments, but it is not possible to do the same when assigning elements inside an array.
Example
<?php
[...$x] = [1, 2, 3];
list(...$x) = array(1, 2, 3);
[$x[0], , $x['a']] = [1, 2, 3];
?>
Alternatives
- Write the full list of targets in the list operator: it might be array elements, and the array nor the elements needs to pre-exists.
SQLite3Result cannot be directly instantiated
Description
Sqlite3Result is returned after executing a SQL query on a Sqlite3 database, with such method as query or execute.
Example
<?php
new Sqlite3Result();
?>
Alternatives
- Call a valid query to obtain an object of that class.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
static“ is not allowed in compile-time constants
Description
“New in initializers” (PHP 8.1) allows new expressions in constant-expression contexts, such as default parameter values, as long as the class being instantiated is fixed and unambiguous: a literal class name, self, or parent. static refers to the class actually used at call time (late static binding), which can differ for every subclass, so it cannot be resolved once and for all at the point the initializer is compiled, and is rejected.
Example
<?php
class Point {
public function __construct(
public readonly self $origin = new static()
) {}
}
?>
Alternatives
- Use self if the intent is to always instantiate the declaring class.
- Move the instantiation into the constructor or method body instead, where late static binding works normally: $origin ??= new static();
Related error messages
- static::-“-is-not-allowed-in-compile-time-constants
- static::class-cannot-be-used-for-compile-time-class-name-resolution
- cannot-use-dynamic-class-name-in-constant-expression
- cannot-use-anonymous-class-in-constant-expression
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Static function %s%s%s() cannot be abstract
Description
This error could not be reproduced so far. Help us by sending us any generating code.
Example
Literal Examples
- Static function foo() cannot be abstract
Alternatives
Static property %s::$%s cannot be readonly
Description
Static properties cannot use the readonly option. readonly only support normal properties, and not static properties.
Example
<?php
class X {
public static readonly int $property;
}
?>
Literal Examples
- Static property X::$property cannot be readonly
Alternatives
- Remove the readonly option.
- Turn the static property into a normal property.
Static property may not have asymmetric visibility
Description
Asymmetric visibility is only applicable to object properties, not static properties.
Example
<?php
class X {
static private(set) $p = 1;
}
?>
Alternatives
- Make the property non-static.
- Remove the asymmetric visibility.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
static::" is not allowed in compile-time constants
Description
Class constants are meant to hold a single, fixed value shared identically by the declaring class and every subclass that inherits it. Referencing static:: inside a constant expression would make the value depend on late static binding, i.e. on whichever subclass actually reads it, which contradicts a constant’s fixed nature, so PHP rejects it at compile time.
Example
<?php
class Base {
const A = 1;
const B = static::A * 2;
}
?>
Alternatives
- Use self:: instead if the intent is to always refer to the declaring class’s own member.
- Compute the value in a static method instead of a constant.
Related error messages
- static-“-is-not-allowed-in-compile-time-constants
- static::class-cannot-be-used-for-compile-time-class-name-resolution
- cannot-use-dynamic-class-name-in-constant-expression
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
static::class cannot be used for compile-time class name resolution
Description
static::class resolves to the class name of whichever subclass is actually in scope at runtime, through late static binding. A class constant, on the other hand, is resolved once and shared identically by the declaring class and every class that inherits it, so it cannot hold a value that is meant to vary per subclass. self::class is accepted in the same spot because it never varies.
Example
<?php
class Base {
const NAME = static::class;
}
?>
Alternatives
- Use self::class if a fixed class name is acceptable.
- Expose it through a method instead: public static function name(): string { return static::class; }.
Related error messages
- static::-“-is-not-allowed-in-compile-time-constants
- static-“-is-not-allowed-in-compile-time-constants
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
stream context option error_mode must be of type StreamErrorMode
Description
PHP 8.6 adds a stream context option, error_mode, that controls how errors raised by a stream operation are reported. It must be one of the cases of the StreamErrorMode enum: StreamErrorMode::Error (the default, standard PHP warnings/notices), StreamErrorMode::Exception (throw a StreamException for terminating errors), or StreamErrorMode::Silent (suppress error output entirely).
Passing anything other than a StreamErrorMode case, such as a plain string, throws a TypeError when the stream operation reads the option, instead of the option being silently ignored.
Example
<?php
$context = stream_context_create([
'stream' => ['error_mode' => 'exception'],
]);
file_get_contents('https://example.invalid/', false, $context);
?>
Literal Examples
- stream context option ‘error_mode’ must be of type StreamErrorMode
Alternatives
- Pass one of the StreamErrorMode enum cases, e.g. StreamErrorMode::Exception, instead of a string or other value.
Related error messages
- stream-context-option-error_store-must-be-of-type-streamerrorstore
- stream-error-handler-must-be-a-valid-callback,-%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
stream context option error_store must be of type StreamErrorStore
Description
PHP 8.6 adds a stream context option, error_store, that controls which errors raised during a stream operation are kept for later retrieval. It must be one of the cases of the StreamErrorStore enum: Auto (the default, decides based on error_mode), None, NonTerminating, Terminating, or All.
Passing anything other than a StreamErrorStore case throws a TypeError when the stream operation reads the option; PHP then falls back to deciding the store mode automatically from error_mode, but still reports the misuse.
Example
<?php
$context = stream_context_create([
'stream' => ['error_store' => 'all'],
]);
file_get_contents('https://example.invalid/', false, $context);
?>
Literal Examples
- stream context option ‘error_store’ must be of type StreamErrorStore
Alternatives
- Pass one of the StreamErrorStore enum cases, e.g. StreamErrorStore::All, instead of a string or other value.
Related error messages
- stream-context-option-error_mode-must-be-of-type-streamerrormode
- stream-error-handler-must-be-a-valid-callback,-%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
stream error handler must be a valid callback, %s
Description
PHP 8.6 adds a stream context option, error_handler, that receives the StreamError[] produced by a stream operation through a callback with the signature function(array $errors): void.
If the supplied value is not actually callable, PHP throws a TypeError whose message is completed with the specific reason returned by the callable check, for example “array must have exactly two elements” or “function … does not exist”.
Example
<?php
$context = stream_context_create([
'stream' => ['error_handler' => 'this is not a callback'],
]);
file_get_contents('https://example.invalid/', false, $context);
?>
Literal Examples
- stream error handler must be a valid callback, no array or string given
- stream error handler must be a valid callback, function ‘doesNotExist’ not found or invalid function name
Alternatives
- Pass a real callable (closure, function name, or [object, method] array) as the error_handler stream context option.
Related error messages
- stream-context-option-error_mode-must-be-of-type-streamerrormode
- stream-context-option-error_store-must-be-of-type-streamerrorstore
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Stream filter %s is never seekable
Description
PHP 8.6 fixes a long-standing inconsistency (bug #49874) between fseek()/ftell() and stream filters: seeking a stream now checks whether every filter currently attached to the affected chain (read or write) can actually tolerate the requested seek, instead of blindly repositioning the stream and leaving filtered/compressed data out of sync with the raw underlying position.
Some filters, such as zlib.deflate and zlib.inflate, accept a write_seek_mode filter parameter controlling how seeks on their write side are handled: 'preserve' (the default, always seekable), 'reset' (seekable only back to the start), or 'strict' (never seekable once data has started flowing through the filter). With 'strict' in effect, any seek attempt now emits this warning and fails, instead of silently succeeding and corrupting the filtered output.
Example
<?php
$stream = fopen('php://temp', 'r+');
fwrite($stream, str_repeat('a', 100));
rewind($stream);
stream_filter_append($stream, 'zlib.deflate', STREAM_FILTER_WRITE, ['write_seek_mode' => 'strict']);
fseek($stream, 0);
?>
Literal Examples
- Stream filter zlib.deflate is never seekable
Alternatives
- Don’t seek a stream whose filter chain was configured with write_seek_mode => ‘strict’, or use ‘preserve’/‘reset’ instead if the stream genuinely needs to be seekable.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.6, fseek() did not consult filter seekability at all: seeking a stream with filters attached always appeared to succeed, even when it left the filter’s internal state inconsistent with the new stream position.](Prior to PHP 8.6, fseek() did not consult filter seekability at all: seeking a stream with filters attached always appeared to succeed, even when it left the filter’s internal state inconsistent with the new stream position.)
Stream filter %s is seekable only to start position
Description
PHP 8.6 fixes a long-standing inconsistency (bug #49874) between fseek()/ftell() and stream filters: seeking a stream now checks whether every filter attached to the affected chain can actually tolerate the requested seek, instead of blindly repositioning the stream.
Reading through a decompression filter such as zlib.inflate (which zlib.deflate also uses on its read side) can always be restarted from position 0, since that simply means decompressing the underlying data again from the beginning. But it cannot jump to an arbitrary byte offset elsewhere in the stream, since that offset has no meaning inside the compressed byte stream. Seeking anywhere other than back to the very start now emits this warning and fails, instead of repositioning the stream to a location that no longer matches what has actually been decompressed.
Example
<?php
$stream = fopen('php://temp', 'r+');
fwrite($stream, str_repeat('a', 100));
rewind($stream);
stream_filter_append($stream, 'zlib.deflate', STREAM_FILTER_READ);
fread($stream, 10);
fseek($stream, 5, SEEK_CUR);
?>
Literal Examples
- Stream filter zlib.deflate is seekable only to start position
Alternatives
- Only rewind a stream read through such a filter back to position 0 (e.g. with rewind()); don’t seek to an arbitrary offset while the filter is attached.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.6, fseek() did not consult filter seekability at all: seeking a stream with a decompression filter attached always appeared to succeed, even when the requested offset had no valid meaning for the filter.](Prior to PHP 8.6, fseek() did not consult filter seekability at all: seeking a stream with a decompression filter attached always appeared to succeed, even when the requested offset had no valid meaning for the filter.)
Stream filter seeking for %s failed
Description
PHP 8.6 fixes a long-standing inconsistency (bug #49874) between fseek()/ftell() and stream filters: seeking now defers to each attached filter’s own seek logic instead of blindly repositioning the stream. A custom filter registered via stream_filter_register() can implement a seek(int $offset, int $whence, int $chain): bool method to participate in that decision; if it returns false, the requested seek is now treated as failed and this warning is emitted, instead of the stream silently repositioning while the filter’s own internal state (e.g. a decompression buffer) drifted out of sync.
The %s placeholder in this message is always the literal string “user-filter” for any custom, PHP-defined filter class, regardless of the name it was registered under with stream_filter_register(); only PHP’s own built-in filters (like zlib.inflate) report their own name.
Example
<?php
class DenySeekFilter extends php_user_filter
{
public function filter($in, $out, &$consumed, $closing)
{
while ($bucket = stream_bucket_make_writeable($in)) {
$consumed += $bucket->datalen;
stream_bucket_append($out, $bucket);
}
return PSFS_PASS_ON;
}
public function seek(int $offset, int $whence, int $chain): bool
{
return false;
}
}
stream_filter_register('deny.seek', DenySeekFilter::class);
$stream = fopen('php://temp', 'r+');
fwrite($stream, 'hello world');
rewind($stream);
stream_filter_append($stream, 'deny.seek');
fseek($stream, 3);
?>
Literal Examples
- Stream filter seeking for user-filter failed
Alternatives
- Make a custom filter’s seek() method return true for any offset it can actually honor, or omit the method entirely to let all seeks succeed as before.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See [Prior to PHP 8.6, a custom filter’s onSeek() return value had no effect on fseek(): the stream was always repositioned regardless of what the filter reported.](Prior to PHP 8.6, a custom filter’s onSeek() return value had no effect on fseek(): the stream was always repositioned regardless of what the filter reported.)
strict_types declaration must be the very first statement in the script
Description
This error appears when the declare statement is not the first statement in the file.
It appears even when non-executing statement are placed before it, such as forgotten characters before the opening tag, any kind of operations in PHP commands, including definitions, namespaces, etc.
Other declare() calls may appears before the strict_types one, though. Also, PHP uses this error with the other declare statement, such as ticks or encoding. They are very rare though.
Example
Here<?php
$a = 1;
declare(strict_types = 1);
?>
Alternatives
- Check if any characters are left before the opening PHP tag.
- Move the declare after the PHP opening tag.
Related error messages
- strict_types-declaration-must-be
- declare(%s)-value-must-be-a-literal
- encoding-declaration-pragma-must-be
- namespace-declaration-statement-has-to-be
- strict_types-declaration-must-have-0-or-1-as-its-value
- strict_types-declaration-must-not
strict_types declaration must be
Description
This is the same placement rule documented in full under strict_types declaration must be the very first statement in the script: the declare(strict_types = ...) pragma changes how the whole file is compiled, so PHP must see it before compiling anything else. Here, the namespace statement, itself harmless, is still a statement, and it pushes the declare() out of first position.
Only a preceding declare() call (for ticks or encoding) is tolerated before it; any other statement is not.
Example
<?php
namespace App;
declare(strict_types = 1);
?>
Literal Examples
- strict_types declaration must be the very first statement in the script
Alternatives
- Move the
declare(strict_types = 1)statement to be the very first statement in the file.
Related error messages
- strict_types-declaration-must-be-the-very-first-statement-in-the-script
- strict_types-declaration-must-not
- strict_types-declaration-must-have-0-or-1-as-its-value
In more recent PHP versions, this error message is now :ref:strict_types-declaration-must-be-the-very-first-statement-in-the-script.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
strict_types declaration must have 0 or 1 as its value
Description
The strict_types pragma is a switch: 0 keeps the usual weak typing (with type coercion for scalar type declarations), and 1 turns on strict typing for the current file. No other value makes sense, so PHP only accepts the literal integers 0 and 1; anything else, including true, false, or any other number, is rejected.
Example
<?php
declare(strict_types = 2);
?>
Literal Examples
- strict_types declaration must have 0 or 1 as its value
Alternatives
- Use
1to enable strict typing, or0to keep weak typing.
Related error messages
- declare(%s)-value-must-be-a-literal
- strict_types-declaration-must-be-the-very-first-statement-in-the-script
- strict_types-declaration-must-not
- strict_types-declaration-must-be
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
strict_types declaration must not
Description
declare() supports a block form for most directives, such as declare(ticks = 1) { ... }, which scopes the setting to the code inside the block. strict_types is different: it is a compile-time, whole-file setting, not something that can be toggled for a portion of the script. Because of that, the block form is rejected outright.
The full message reads: strict_types declaration must not use block mode.
Example
<?php
declare(strict_types = 1) {
var_dump(strlen('abc'));
}
?>
Literal Examples
- strict_types declaration must not use block mode
Alternatives
- Remove the curly braces, and use
declare(strict_types = 1);as a simple statement.
Related error messages
- strict_types-declaration-must-be-the-very-first-statement-in-the-script
- strict_types-declaration-must-have-0-or-1-as-its-value
- strict_types-declaration-must-be
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
strlen(): Passing null to parameter #1 ($string) of type string is deprecated
Description
strlen() calculates the length of a string. It only works on strings, and, in particular, cannot compute the length of the null value.
Example
<?php
$s = null;
print strlen($s);
?>
Alternatives
- Process
nullin a separate branch of code. - Convert
nullto the empty string before using strlen().
Switch statements may only contain one default clause
Description
The switch expression uses cases and a default entry. Cases are matched against the parameter variable, and when all of them fail, the default case (sic) is used. This also means that there can be only one defaut entry, as it will be used after all the cases.
When several default cases are spotted, PHP stops compilation.
Note that there is no error message for multiple identical cases: in such situations, the first one is used.
Example
<?php
switch($a) {
default:
default:
}
?>
Alternatives
- Remove all defaults but one.
Related error messages
syntax error, unexpected ')', expecting '='
Description
list() must appear on the left side of an assignation. It will be filled with the values in the array of the right side.
Example
<?php
var_dump(list(1,2,3));
?>
Alternatives
- Add a
=sign to the right of thelist()call, and then, add an array on the right. - Turn the
list()into a[]short syntax. This might change the meaning, as, in this case,list()becomes an array.
syntax error, unexpected ‘)’, expecting ‘|’ or variable (T_VARIABLE)
Description
Until PHP 8.0, exceptions always had to be named, with a variable.
Here, the error message is signaling that it expected another exception to catch, separated from the first one by a |, or a variable name.
Example
<?php
try {
} catch (E) {}
?>
Alternatives
- Add a variable name to the catch clause.
- Add another exception to catch, and then a name to the catch clause.
- Upgrade to PHP 8.0 or more recent.
syntax error, unexpected ‘)’, expecting variable (T_VARIABLE)
Description
This error is related to the support the trailing comma in function calls: in PHP 7.4, it is allowed to add a final comma at the end of the arguments list, and yet, not provide an extra argument.
Example
<?php
function foo($a,
$b,
$c) { echo __METHOD__; }
echo foo(1,
2,
3,
);
?>
Alternatives
- Upgrade to PHP 7.4.
- Remove the trailing comma.
syntax error, unexpected ‘,’
Description
Commas are used as a separator in lists of items, such as parameters, arguments, elements of an array. When such list is supposed to have only one element, the syntax error appears.
This happens with switch, match(), if(), or parenthesis, which all allow one expression, not two, although they might be confused with a function call.
It also happens with curly braces, which uses semi-colon ; as a separator.
The unexpected , appears when there is nothing between separators: for example, an empty argument, or a missing variable in a global call. The only situation where it is acceptable is inside a list() expression.
Example
<?php
// only one expression for switch, parenthesis, etc.
switch(2,3);
(1,2);
// blocks use ; as separator.
{3,4}
// comma must separate something
global $a,, $b;
?>
Alternatives
- Check if the expression accepts more than one expression.
- Review commas directly inside a curly braces block.
syntax error, unexpected ‘-’, expecting ‘=’
Description
When defining a constant, the constant name must be valid. It must be satisfying the following regex: /[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/. When an unexpected character appears, it yields this errors, mentioning the erroneous character first.
This error appears for global constant, written with const or for class constants, inside a class.
The unexpected character may have a lot of variations, in particular any non-letter or non-figure characters. Check the regex for more options.
Example
<?php
const A-B = 1;
?>
Alternatives
- Remove the
-in the constant name. - Remove the
unexpectedcharacter in the constant name. - Remove the constant definition.
syntax error, unexpected ‘::’, expecting ‘(’
Description
This is a situation where a new keyword degrades a previously valid syntax. match is a new keyword in PHP 8.0, for the eponymous command. It cannot be used as a class name, a function name, or a global constant, as before.
By extension, the match keyword cannot be used in static object notations, such as calling a constant, or a static method or property.
This error may arise with other keywords, for similar reasons.
Example
<?php
echo Match::A;
?>
Alternatives
- Rename the
matchclass to a non-keyword name.
Related error messages
syntax error, unexpected ‘::’ (T_PAAMAYIM_NEKUDOTAYIM), expecting ‘;’ or ‘,’
Description
Using the static class syntax directly on an interpolated string was not possible until PHP 8.0. Until then, it reported a syntax error.
Example
<?php
class Bar {
static function foo() {}
static $property = 3;
const C = 4;
}
$a = "ar";
echo "B$a"::foo();
echo "B$a"::$property;
echo "B$a"::C;
?>
Alternatives
- Upgrade to PHP 8.0 or more recent.
- Store the class name in a variable, and use that variable instead of the direct string.
Related error messages
- [syntax-error,-unexpected-’‘,-expecting-’;‘-or-’,’
syntax error, unexpected ‘;’, expecting ‘[’
Description
The & reference operator turns a value into a reference. It works with data containers, such as variables, properties or array elements. It doesn’t work on literal constants.
The error message suggestion to use extra operators such as [ leads to a distinct error: Cannot use temporary expression in write context.
Example
<?php
$a = &E_ALL;
const B = [1,2,3];
//Cannot use temporary expression in write context
$c = &B[2];
?>
Alternatives
- Store the constant in a variable, and make the reference on the variable.
- Use constants by value, not by reference.
Related error messages
In more recent PHP versions, this error message is now :ref:syntax-error,-unexpected-token-";",-expecting-"->"-or-"?->"-or-"{"-or-"[".
syntax error, unexpected ‘;’, expecting ‘{’
Description
The error message comes from the possibility to use new lines inside fully qualified names, that was possible until PHP 8.0.
Example
<?php
\A
\B
\C
;
?>
Alternatives
- Remove the new lines and whitespaces inside a fully qualified name.
syntax error, unexpected ‘[’, expecting ‘;’ or ‘,’
Description
Using the array syntax directly on an interpolated string was not possible until PHP 8.0. Until then, it reported a syntax error.
Example
<?php
$a = 'foo';
echo bar$a[4]; // display f
?>
Alternatives
- Upgrade to PHP 8.0 or more.
- Put the string in a variable first.
Related error messages
syntax error, unexpected ‘elseif’
Description
The elseif must follow a if structure. It cannot be used alone, not be used after a else clause.
Example
<?php
// elseif cannot be standalone
elseif ($a === 1) {
echo 2;
}
// else has closed the if structure, not more elseif allowed
if ($condition) {}
else {}
elseif ($a === 1) {
echo 2;
}
// the endif; has already closed the if structure.
if ($condition):
endif;
elseif ($a === 1) :
echo 2;
endif;
?>
Alternatives
- Ensure that there is a previous
ifstructure, with onethenblock, and optionally, otherelseifblock. - Ensure that there is no previous
elseclause. - Ensure that there is no previous
endifkeyword.
syntax error, unexpected ‘match’
Description
This error is related to match being a PHP keyword. Since PHP 8.0, it cannot be used anymore as a class or interface name. When moving from PHP 7 to 8, any traditional usage of match where a class name is expected shall produce such an error.
In the illustrations, no more details are provided about the reason why match is not allowed. Other situation may provide better hints.
This error applies to all PHP keywords. match is only the most common, as it is a new PHP 8.0 keyword.
Example
<?php
// Cannot use Match here.
interface X extends Match { }
// Cannot use Match here.
class Y implements Match {
// Cannot use Match here.
use Match;
}
?>
Alternatives
- Rename
Matchto something that is not a PHP keyword. - Stay on PHP 7.x.
syntax error, unexpected ‘throw’ (T_THROW)
Description
throw is not an expression until PHP 8.0. Until then, it cannot be used as part of another expression, such as the left part of or, an argument, or inside parenthesis.
After PHP 8.0, one could use it as part of an expression.
Example
<?php
$x ?? throw new \Exception('Missing value for x');
?>
Alternatives
- Upgrade to PHP 8.0 or more recent.
- Convert the
orto anifthenstructure.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See throwIsAnExpression
syntax error, unexpected ‘{’
Description
This error arise when the old curly braces syntax is used to access an element in an array. This syntax was deprecated in PHP 7.x and removed entirely in 8.0. It also was left as a syntax error since PHP 8.3.
Example
<?php
$array[1]{0};
?>
Alternatives
- Use the square brackets to access array elements.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected ‘|’, expecting variable (T_VARIABLE)
Description
Union types were introduced in PHP 8.0: union type allows the specification of several distinct types, separated by a | pipe character. Until PHP 8.0, types were immediately followed by the variable or property name.
Example
<?php
class X {
private int|float $property;
}
function foo(int|float $property) {}
?>
Alternatives
- Upgrade to PHP 8.0.
- Find a common supertype to the two (or more) involved types.
- Remove all types.
syntax error, unexpected end of file
Description
The unexpected end of file happens when PHP has not finished parsing a file, and still expected a few more tokens to complete it.
Usually, this means that not enough code was provided, or also, that some code instruction were not completed as expected.
In the example here, the expression is completed with a semi-colon, or a closing PHP tag. Both would conclude the expression, and the script, but they are not available.
Example
<?php
$x = 1
Alternatives
- Make sure all expression are completed.
syntax error, unexpected fully qualified name “%s”, expecting “function” or “const”
Description
There should not be any fully qualified name inside the body of a class, enumeration, trait or interface. Names are used for methods or constants, or with the use expression, to import a trait.
Example
<?php
class X {
\A;
}
?>
Alternatives
- Add the
usekeyword before the name to import a trait. - Add the
functionkeyword before the name to make it a method, although there should not be any\in the method name. - Add the
constkeyword before the name to make it a constant, although there should not be any\in the constant name. - Add the
#[keyword before the name to make it an attribute.
syntax error, unexpected fully qualified name “%s”, expecting “function”
Description
This error appears when a fully qualified name is used in the body of a class, (or any CITE).
Example
<?php
class X {
\A\B;
}
?>
Alternatives
- Remove the standalone name.
- Add the
usekeyword before the standalone name, to import a related trait.
Related error messages
syntax error, unexpected fully qualified name “%s”, expecting “{”
Description
Until PHP 8.0, it was possible to include spaces or new lines in a namespace. They would be ignored later, but parsed and handled that way.
In PHP 8.0, this is not possible anymore.
Example
<?php
namespace Vendor
\XXX;
echo 1;
?>
Literal Examples
- syntax error, unexpected fully qualified name “\XXX”, expecting “{”
Alternatives
- Make namespaces one string, without new lines or any spaces.
syntax error, unexpected fully qualified name “%s”
Description
This error appears when new lines are introduced inside a namespace. This was possible syntax until PHP 8.0, but not anymore.
Example
<?php
// constant
\A
\B
\C
;
?>
Alternatives
- Remove the new lines and whitespaces from the namespace.
syntax error, unexpected identifier “%s”, expecting “(”
Description
After the function keyword and the function’s name, PHP expects the opening parenthesis of the argument list. Here, a second identifier was found instead, which usually means an extra word was typed, or a comma or a return-type colon was forgotten between two declarations.
Example
<?php
function foo bar() {}
?>
Literal Examples
- syntax error, unexpected identifier “bar”, expecting “(”
Alternatives
- Remove the extra identifier, keeping only the function name.
- If a return type was intended, add a colon before it:
function foo(): bar {}. - If two functions were meant to be declared, close the first one and start a new
functionstatement.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected identifier “%s”, expecting “)”
Description
This error appears an argument is already a complete expression, yet a new identifier appears after it. Within a method call, this could have been the end of the call itself, or an expression error.
Example
<?php
foo(a: 1 b: 2);
foo(a: 1 c);
?>
Literal Examples
- syntax error, unexpected identifier “b”, expecting “)”
Alternatives
- Add the missing comma between the arguments.
- Add the missing operator to build a full expression. There may be many ways to make the expression valid.
- Close the function call with a closing parenthesis, and start a new expression after it.
syntax error, unexpected identifier “%s”, expecting “,” or “;”
Description
This error is not related to the upcoming identifier, but to the previous delimiters. In both cases of the illustration, a string was started, with single or double quotes: yet, inside these strings, there was another set of the same delimiter. The parser could not differentiate between the two usages, and exited the string.
Example
<?php
// missing a '
echo '<a href='https://www.exakat.io'>Exakat.io</a>';
// missing a "
echo "<a href="https://www.exakat.io">Exakat.io</a>";
// missing as between identifier
use OpenApi\Attributesas OA;
?>
Alternatives
- Escape quotes inside a string, when they are used as delimiter.
- Use the other quotes inside the string: if single quotes are used as delimiters, use double quotes in it.
- Switch to the heredoc syntax, to simplify the syntax for both quotes.
- Add the missing
as, between the two identifiers, in auseinstruction.
syntax error, unexpected identifier “%s”, expecting “;” or “{”
Description
An abstract method’s signature must be terminated with a semicolon, since it has no body, and a concrete method’s signature must be followed by a { opening the body. Here, an extra identifier was found right after the closing parenthesis of the argument list, where PHP expected one of those two terminators.
This typically happens when a return type declaration is missing its leading colon, or when a stray word was left over after editing the signature.
Example
<?php
abstract class X {
abstract function foo() bar;
}
?>
Literal Examples
- syntax error, unexpected identifier “bar”, expecting “;” or “{”
Alternatives
- If a return type was intended, add a colon before it:
abstract function foo(): bar;. - Remove the extra identifier.
- If the method should have a body, replace the identifier with
{and the method’s code.
Related error messages
- syntax-error,-unexpected-identifier-“%s”,-expecting-“(”
- syntax-error,-unexpected-variable-“$this”,-expecting-“;”-or-“{”
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected identifier “%s”, expecting “]”
Description
PHP has found two identifiers, one next to the other. This might happen inside an attribute declaration or a function call, where a separator has been forgotten.
Example
<?php
#[A name:a)] // forgotten opening parenthesis
class X {}
?>
Alternatives
- Close the attribute with a closing square bracket. The following code needs to be updated too.
- Open the argument part of the attribute, with an opening parenthesis.
syntax error, unexpected identifier “%s”, expecting “function” or “const”
Description
PHP identified a name in the body of a class, although it was not preceded by a keyword.
The error may suggest function, but any definition keyword will do: private, protected, public, var, const, function, use.
Example
<?php
class X {
publicfunction foo() {}
}
?>
Literal Examples
- syntax error, unexpected identifier “publicfunction”, expecting “function” or “const”
Alternatives
- Add a definition keyword before the name.
- Fix the syntax and make a keyword appear at the beginning of the definition.
In more recent PHP versions, this error message is now :ref:syntax-error,-unexpected-identifier-"%s",-expecting-"function".
syntax error, unexpected identifier “%s”, expecting “function”
Description
PHP identified a name in the body of a class, although it was not preceded by a keyword.
The error may suggest function, but any definition keyword will do: private, protected, public, var, const, function, use.
Example
<?php
class X {
publicfunction foo() {}
}
?>
Literal Examples
- syntax error, unexpected identifier “publicfunction”, expecting “function”
Alternatives
- Add a definition keyword before the name.
- Fix the syntax and make a keyword appear at the beginning of the definition.
In previous PHP versions, this error message used to be :ref:syntax-error,-unexpected-identifier-"%s",-expecting-"function"-or-"const".
syntax error, unexpected identifier “%s”, expecting “{”
Description
In this case, PHP found two identifiers in a row: X and Y. This never happens in PHP code. Either a keyword should have separated them, or one of them is a duplicate.
Example
<?php
class X Y {}
enum E Z {}
interface I W {}
?>
Alternatives
- Add a missing keyword between the two identifiers: here,
implementsorextendscould work. - Remove one of the duplicate name.
syntax error, unexpected identifier “%s”, expecting variable or “$”
Description
new works with objects, static properties and normal properties. It does not work with class constants, even if the constant is an object.
Example
<?php
class A {
const B = C;
}
const C = new A;
var_dump(new A::B);
?>
Literal Examples
- syntax error, unexpected identifier “B”, expecting variable or “$”
Alternatives
- Store the constant in a variable, and
newthe variable. - Get the class name with
get_classor::classand then, create the new object.
syntax error, unexpected identifier “%s”, expecting variable
Description
A foreach() structure requires a variable after the as keyword: in fact, it may be a variable, a property, a static property, an array index or the list() expression.
The same error also appears when the intersectional type syntax is used: While A& is valid PHP 8.0, it should be followed by a variable (a parameter), and it finds another type.
Example
<?php
foreach($a as b) {}
function foo(A&B $arg) {}
?>
Literal Examples
- syntax error, unexpected identifier “B”, expecting variable
- syntax error, unexpected identifier “b”, expecting variable
- syntax error, unexpected identifier “Countable”, expecting variable
Alternatives
- Add the missing
$sign, to make the identifier an array. - Upgrade to PHP 8.2, with intersectional types.
- Remove the intersectional types.
syntax error, unexpected identifier “%s”
Description
This error appears when two identifiers are following each other. This is usually rooted in a missing keyword or character.
Named structures usually start with a keyword, such as class, interface, function, etc.
In a function call, a missing opening parenthesis brings the named parameter and the function name together.
The error also appears when new lines are used inside a namespace. This was valid until PHP 8.0, but is not anymore.
Example
<?php
// missing keyword: class, or interface
A extends B {}
// missing opening parenthesis
foo name:1);
// new lines in namespace
echo \A
B\
C;
?>
Literal Examples
- syntax error, unexpected identifier “A”
Alternatives
- Add the missing keyword before the identifier.
- Add a missing opening parenthesis to the function call.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See MultilineQualifiedName
syntax error, unexpected identifier “readonly”, expecting “function” or “const”
Description
This syntax error signals that readonly is still considered as an identifier, and not as a keyword. This happens when the underlying PHP version is too old for the source code.
Example
<?php
class X {
readonly int $property;
}
?>
Alternatives
- Remove the
readonlyoption. - Upgrade to PHP 8.1 or more recent.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected integer “%s”, expecting “)”
Description
This error is a variation of the named parameter typo: the missing semi colon between the name and the value leads to an identifier next to an unrelated operator. The suggestion to use a closing parenthesis is valid, though not the only one.
Example
<?php
foo(arg new B());
class B {}
function foo(B $arg) {}
?>
Alternatives
- Add the missing
:before the integer. - Add the missing
)before the integer, and may be a comma, depending on the context.
syntax error, unexpected namespaced name “%s”, expecting “function”
Description
A namespaced name is an identifier with at least one backslash. The body of a class, enumeration, trait or interface does not use any namespaces, as it declares methods, constants and proeprties. There may be namespaced names in a use declaration, but such expression starts with a keyword.
Example
<?php
class X {
A\B;
C\D($e);
}
?>
Literal Examples
- syntax error, unexpected namespaced name “A\B”, expecting “function\
Alternatives
- Add the
usekeyword before the name to import a trait. - Add the
functionkeyword before the name to make it a method, although there should not be any\in the method name. - Add the
constkeyword before the name to make it a constant, although there should not be any\in the constant name. - Add the
#[keyword before the name to make it an attribute.
Related error messages
syntax error, unexpected single quoted string “%s”, expecting “)”
Description
After an identifier, such as name, there can only be a delimiter, such as (, [, or : but not a string.
Example
<?php
foo(name 'A');
?>
Literal Examples
- syntax-error,-unexpected-single-quoted-string-“A”,-expecting-“)”
Alternatives
- Add a colon between
nameand'A', to make a named parameter. - Add parenthesis after
nameand around'A', to make a function call. - Add square brackets after
nameand around'A', to make a array call.
syntax error, unexpected string content
Description
This error appears when a single quote string is not properly closed. In the example, there is an opening single quote, but not a closing one. PHP tries to use the rest of the code as a literal string, and ends up without tokens to wrap up the code legally.
Example
<?php
{ $a = '1+2; }
Alternatives
- Close the string with a single quote.
- Close the string with a double quote.
Related error messages
- unclosed-‘{’
- unmatched-‘}’
- unmatched-‘)’
- [unmatched-‘]’](unmatched-].html)
syntax error, unexpected token “#[”, expecting “)”
Description
Attributes can only be placed in front of the declarations that support them, such as classes, functions, methods and parameters. A catch block’s caught-exception clause does not accept an attribute: PHP was expecting the closing parenthesis of the catch (...) clause, and found the beginning of an attribute, #[, instead.
Example
<?php
try {
} catch (Exception #[SomeAttribute] $e) {
}
?>
Alternatives
- Remove the attribute from the
catchclause. - Move the attribute to a declaration that supports it, such as the enclosing method.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected token “#[”, expecting “,” or “;”
Description
The #[ token marks the beginning of an attribute. The previous statement is either not finished with a semi-colon, or could be extended with another set of code and then finished with a semi-colon.
Example
<?php
// missing ; or ,
use A as B
#[MyAttribute]
class X {}
?>
Alternatives
- Finish the previous
usestatement, with a semi-colon. - Complete the previous
usestatement, and finish it with a semi-colon.
syntax error, unexpected token “#[”, expecting “]”
Description
It is not possible to nest attributes, so the first attribute must be finished, with a closing square bracket, before opening the second one.
Example
<?php
#[A
#[B]
class X {}
?>
Alternatives
- Close the first attribute with a closing square bracket.
- Remove the extra opening
#[attribute, and use a comma.
syntax error, unexpected token “%”
Description
PHP accepts one percentage %, for modulo. The % operator requires 2 operands, one before, and one after. This is not the same as + and -, which can be used as unary operator.
Example
<?php
$a = 2 + % 3;
?>
Alternatives
- Remove the superfluous percentage.
Related error messages
syntax error, unexpected token “%s”, expecting identifier
Description
This error arises when a PHP token is used where a name is expected. There is a conflict between the PHP token, which has its own meaning, and the expected name, which is a ‘T_STRING’ token.
This happens with any named structure, such as CITE, functions and global constants. It is legit with class constants and methods.
The identifier can be any string, that satisfy the regex ^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$, and is not a PHP keyword.
This error is case insensitive, like PHP keywords.
Example
<?php
class Match {}
trait Switch {}
class echo {}
interface ECHO {}
enum echo {}
trait echo {}
function echo() {}
const echo = 1;
?>
Alternatives
- Add a distinguishing prefix or suffix to the name to stay out of conflict with PHP keywords.
- Check if the PHP version introduces new keywords.
- Make the function a method.
- Make the constant a global constant.
- Prefix or suffix the name, to make it a normal word, not a keyword.
syntax error, unexpected token “&”, expecting end of file
Description
& is the reference operator. It returns a reference to a value, and cannot be used standalone, or on the left part of an assignation.
Example
<?php
&$x;
&E_ALL;
$c = &'33';
?>
Alternatives
- Remove the whole expression.
- Put this expression in another variable, with an assignation.
- Put this expression in another variable, and make the reference on that variable.
Related error messages
syntax error, unexpected token “&”
Description
The & operator is used in two distinct situations: as the bitwise operator, between two different values; as the reference operator, before a variable.
As the reference operator, it may be used in a method signature, to identify a passed-by-reference argument. It may not be used anymore at call time, for sending an argument nor receiving a value.
The reference operator returns a new reference, and it should be stored in another variable (or any data container). Otherwise, it is.
Example
<?php
function foo(&$a) {}
// Cannot make a reference at call time
foo(&$c);
// Cannot return a reference at call time
$d = &foo($c);
?>
Alternatives
- Remove the
&in function call’s argument, and put it in the function signature. - Remove the
&in function call returned value, and put it in the function signature.
Related error messages
syntax error, unexpected token “(”, expecting “::”
Description
This error appears when calling static as a function. static cannot be used as a function name. It may be used as class name, in a new expression, or as an method. It is often used in a static call, for methods, constant or properties.
It is not recommended to use static as a method name.
Example
<?php
static();
?>
Alternatives
- Add the object before the method name.
- Add the class name and
::before the method name. - Add the
newoperator before thestatickeyword. Make sure that code is within a class or assimilated.
syntax error, unexpected token “(”, expecting identifier or variable or “{” or “$”
Description
The object operators -> and ?-> both expect a name as second operand, aka on the right. Here, the name of the method was forgotten and the operator tried to use ( as a name, which is not allowed.
Example
<?php
// missing a method name
$object-> ();
// missing a method name
$object?-> (1);
?>
Alternatives
- Add a name after the
->and?->, such as$object->method. - Add a name inside a variable after the
->and?->, such as$object->$methodName. - Add a name inside an expression after the
->and?->, such as$object->{$variable . 'suffix'}(). - Add a name inside an variable variable after the
->and?->, such as$object->$$variable().
Related error messages
syntax error, unexpected token “(”, expecting variable
Description
PHP started recognizing a property definition, with its visibility, a type and now expects a variable name. In fact, the function keyword was omitted.
Example
<?php
class X {
public __construct () {}
}
?>
Alternatives
- Add the
functionkeyword, before the name of the method. - Remove the parenthesis and the following tokens, and make a proper property definition.
syntax error, unexpected token “(”
Description
Parenthesis cannot be placed anywhere, although they have a wide range of applications. In particular, they are used to call methods, by delimiting arguments; and set part of expressions apart.
A class cannot hold a closure, only method, which are functions with a name.
The syntax to call a method on an instantiation new x()->foo() and new x()() has been introduced in PHP 8.4.
Example
<?php
// methods cannot be closure. They need a name
class X {
function () {}
}
// This is a PHP 8.4 syntax, cannot be used before.
new $x()();
// equivalent to (new $x())->__invoke();
?>
Alternatives
- Add the name to the method.
Related error messages
- syntax-error,-unexpected-token-“}”
- syntax-error,-unexpected-token-“)”
- [syntax-error,-unexpected-token-“]”](syntax-error,-unexpected-token-].html)
syntax error, unexpected token “(int)”
Description
This is a bug in the parser engine of PHP: (int), (array) or the other cast operators, are recognized early in the code parsing, and are also confused inside a function call.
Example
<?php
var_dump(int);
?>
Alternatives
- Do not use any global constant, with the name of a cast operator:
int,float,unset, etc.
syntax error, unexpected token “)”, expecting “=”
Description
In this case, the = is missing, and the 1 has been merged into the strict_types to become an identifier. PHP expects a = after this identifier.
Example
<?php
declare(strict_types1);
?>
Alternatives
- Add
=afterstrict_types.
syntax error, unexpected token “)”, expecting “function” or “fn” or “static” or “#[”
Description
In this command, an attribute has been configured. The attributes can only precede a structure, such as a class, method or function.
In this case, the attribute has been placed inside an function call, so only a closure can be declared.
This error appears after PHP 8.0: this is when the #[ token was introduced. Until that version, # introduces a comment, until the end of the line.
Example
<?php
foo(#[a]);
function foo(Closure $f) {}
?>
Alternatives
- Finish declaring a closure, with
fnorfunctionin the argument. - Remove the attribute.
- Turn the attribute into a comment.
Related error messages
- [syntax-error,-unexpected-token-“;”,-expecting-“function”-or-“fn”-or-“static”-or-“#“
syntax error, unexpected token “)”, expecting variable
Description
An attribute placed inside a parameter list must be immediately followed by the parameter it decorates. Here, the attribute is the last thing before the closing parenthesis, so PHP expects a variable to declare the parameter, but finds the closing parenthesis instead.
Example
<?php
function foo(string $a, #[SomeAttribute]) {}
?>
Alternatives
- Add the missing parameter, with its
$variable, right after the attribute. - Remove the trailing attribute if no extra parameter was intended.
Related error messages
- [syntax-error,-unexpected-token-“#“,-expecting-”)“
- syntax-error,-unexpected-token-“{”,-expecting-variable
- syntax-error,-unexpected-variable-“$%s”,-expecting-“)”
- syntax-error,-unexpected-variable-“$task”,-expecting-“)”
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected token “)”
Description
This error appeas when the parenthesis is needed, but not at that place.
In the illustration, the parenthesis should be not be used directly after a multiplication sign: that operator needs a second operand.
Example
<?php
$a = (3 * 3 * );
?>
Alternatives
- Add the missing operand to the previous operator.
Related error messages
- syntax-error,-unexpected-token-“}”
- syntax-error,-unexpected-token-“(”
- [syntax-error,-unexpected-token-“]”](syntax-error,-unexpected-token-].html)
syntax error, unexpected token “*”
Description
PHP accepts one star *, for multiplication and two stars **, for power, since PHP 7.0. More stars are not supported as operator.
Example
<?php
// star cannot be used directly after a +
$a = 2 + * 3;
// No such operator as 3 stars
$a = 2 *** 3;
?>
Alternatives
- Remove the previous operator, before the star.
- Finish the previous operation, before the star.
- Remove the superfluous star.
Related error messages
syntax error, unexpected token “,”, expecting “)”
Description
The new call was not properly closed with a closing parenthesis, and PHP found a closing square bracket, instead.
Example
<?php
#[A(new X( a: 'b', ]
class X {}
?>
Alternatives
- Add a closing parenthesis after the comma.
- Remove the comma, and add a closing parenthesis.
syntax error, unexpected token “,”, expecting “]”
Description
A comma was found in an array syntax: the syntax is $variable[$index], and there can be only one index between the brackets.
Example
<?php
echo $a[1,2];
?>
Alternatives
- Remove the comma and the code after it, until the closing bracket.
- Close the square bracket, open a new one and remove the comma:
$a[1][2].
Related error messages
- syntax-error,-unexpected-token-“,”
- syntax-error,-unexpected-token-“,”,-expecting-variable-or-“$”
- syntax-error,-unexpected-token-“,”,-expecting-variable
syntax error, unexpected token “,”, expecting variable or “$”
Description
This error is reported when a list of global variable is expected after the global keyword.
There is a similar case with the visibility options public, protected and private, and the static keyword, although global is the only keyword with accepts variable variables.
Generally speaking, there can be no two successive commas in an expression, except with the list() keyword.
Example
<?php
class X {
public function foo() {
global $a, , $c;
}
}
?>
Alternatives
- Remove the extra comma.
- Fill the empty slot with a variable.
Related error messages
- syntax-error,-unexpected-token-“,”,-expecting-variable
- [syntax-error,-unexpected-token-“,”,-expecting-“]”](syntax-error,-unexpected-token-,,-expecting-].html)
- syntax-error,-unexpected-token-“,”
syntax error, unexpected token “,”, expecting variable
Description
This error is reported when a list of variable is expected after a keyword.
This is the case with the visibility options public, protected and private, which expect a list of property names.
This is also the case with global and static, which are declaring global and static variables.
Generally speaking, there can be no two successive commas in an expression, except with the list() keyword.
Example
<?php
class X {
public $a, , $c;
public function foo() {
static $a, , $c;
}
}
?>
Alternatives
- Remove the extra comma.
- Fill the empty slot with a variable.
Related error messages
- syntax-error,-unexpected-token-“,”,-expecting-variable-or-“$”
- [syntax-error,-unexpected-token-“,”,-expecting-“]”](syntax-error,-unexpected-token-,,-expecting-].html)
- syntax-error,-unexpected-token-“,”
syntax error, unexpected token “,”
Description
A comma is used to separate arguments in a function call. A functioncall may also use named parameters, to identify the arguments. In this case, the name of the parameter is provided, but not its value.
Example
<?php
#[Attribute(name: , value: 1)]
class X {}
?>
Alternatives
- Remove the parameter name from the function call.
- Provide a value for the parameter name in the functioncall.
Related error messages
- [syntax-error,-unexpected-token-“,”,-expecting-“]”](syntax-error,-unexpected-token-,,-expecting-].html)
- syntax-error,-unexpected-token-“,”,-expecting-variable-or-“$”
- syntax-error,-unexpected-token-“,”,-expecting-variable
syntax error, unexpected token “\”, expecting “{”
Description
This syntax error is related to the usage of PHP keyword in a namespace. Until PHP 8.0, the namespace could not use any such keyword, and produced a compilation error.
Example
<?php
namespace A\eval\B;
?>
Alternatives
- Upgrade to PHP 8.0 or more recent.
- Rename the namespace to avoid using PHP keywords.
syntax error, unexpected token “->”, expecting “,” or “;”
Description
The object operator -> is used in an expression, where it is not expected.
Here, it is a global variable statement. Such statement were possible in PHP 5 and older, but are not valid anymore since PHP 7.0. Then, PHP would use the content of the property as the name of the global variable.
The same error is emitted with static variables, with the :: and the ?-> operators.
Example
<?php
global $object->property;
static $object->property;
?>
Alternatives
- Remove the property or method call from the global instruction.
Related error messages
- syntax-error,-unexpected-token-“::”,-expecting-“,”-or-“;”
- syntax-error,-unexpected-token-“?->”,-expecting-“,”-or-“;”
syntax error, unexpected token “->”
Description
This error reports that the object syntax was not expected there.
One classic reason is the new syntax in PHP 8.4, where parenthesis are not necessary, right after a new, to call properties or methods. This syntax actually requires the parenthesis.
Another situation arise when a space is inserted between the ? and the -> operator. The space let PHP believe that a ternary operator is started, yet the -> must be applied to an object.
Example
<?php
// should be new X()->method();
new X->method();
// wrongly build null object operator
echo $obj ?
-> foo;
?>
Alternatives
- Add the parenthesis on the
newcall. - Write the
?->without spaces.
Related error messages
syntax error, unexpected token “:”, expecting “)”
Description
Single colons : are allowed in a method call, as they separate the value and the name of the named parameter. Here, the name of the parameter is missing.
Example
<?php
foo(a:1, : 2);
?>
Alternatives
- Add the name of the parameter before the colon.
- Remove the colon.
syntax error, unexpected token “:”, expecting “]”
Description
Colons are used with the ternary operators, labels and named parameters. They may also be involved in a typo with a double colon, that lost one half of its elements.
Example
<?php
#[A\Bc: 'D')]
?>
Alternatives
- Add the missing parenthesis between the
Battribute name and thecnamed parameter.
syntax error, unexpected token “:”
Description
A syntax error is a generic error, where PHP could not compile the code. Here are some classic typo or seemingly valid code that leads to this error.
- Since PHP 8.0, named parameters may be used, though parameters don’t use the initial
$sign.
Example
<?php
// calling a named parameter, with the $ in the parameter name
foo($c: 1);
?>
Alternatives
- Fix the name of the parameter.
syntax error, unexpected token “::”, expecting “,” or “;”
Description
The object operator :: is used in an expression, where it is not expected.
Here, it is a global variable statement. Such statement were possible in PHP 5 and older, but are not valid anymore since PHP 7.0. Then, PHP would use the content of the property as the name of the global variable.
The same error is emitted with static variables, with the :: and the -> operators.
Example
<?php
global $object::$property;
static $object::$property;
?>
Alternatives
- Remove the property or method call from the global instruction.
Related error messages
- syntax-error,-unexpected-token-“?->”,-expecting-“,”-or-“;”
- syntax-error,-unexpected-token-“->”,-expecting-“,”-or-“;”
syntax error, unexpected token “::”, expecting “:”
Description
In this example, Match is a PHP keyword, and cannot be part of a static call, with the operator ::. On the other hand, Match could be a parameter name, where the foo function, has a $Match parameter. Hence, the suggestion to use : a single colon.
This error may also appear with other keywords, such as Switch. It is also case-insensitive.
Example
<?php
foo(Match::a());
?>
Alternatives
- Use a single colon, if
$Matchis actually a parameter name. - Rename the
Matchclass to avoid conflicts with PHP keywords.
syntax error, unexpected token “::”, expecting “]”
Description
Inside the square brackets of an array index, PHP expects an expression identifying the key, followed by the closing ]. The scope resolution operator :: cannot start an expression on its own: it must be preceded by a class name, a variable or one of self, parent or static. Here, PHP found :: immediately, so it reports that it was still expecting ] to close the array access.
The same message also appears whenever a previous [ was left unclosed, and a later, unrelated :: is the first token that cannot continue the pending index expression.
Example
<?php
$arr = [1, 2, 3];
$y = $arr[::];
?>
Alternatives
- Provide the missing class name (or
self,parent,static) before::, such as$arr[X::CONST]. - Check that every previous
[in the file has a matching].
Related error messages
- [syntax-error,-unexpected-token-“public”,-expecting-“]”](syntax-error,-unexpected-token-public,-expecting-].html)
- [syntax-error,-unexpected-token-“class”,-expecting-“]”](syntax-error,-unexpected-token-class,-expecting-].html)
- [syntax-error,-unexpected-token-“if”,-expecting-“]”](syntax-error,-unexpected-token-if,-expecting-].html)
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected token “::”
Description
In this situation, the keyword or is reserved by PHP and cannot be used as a class name, a function name, or a global constant.
By extension, the or keyword cannot be used in static object notations, such as calling a constant, or a static method or property.
This error may arise with other keywords, such as switch, and, foreach, etc, for similar reasons. It also may happen when a new keyword is reserved by PHP, between two versions.
The error also appears when the left operand of the :: is missing, or not applicable. Here, there is an illustration with echo.
Example
<?php
// double-colon on an operator
1 or::A;
echo ::class;
// double-colon on a number
1::class;
?>
Alternatives
- Rename the class with a PHP non-keyword.
Related error messages
syntax error, unexpected token “;”, expecting “(”
Description
This syntax error is related to a new PHP feature. In PHP 8.3, a new syntax for dynamic access to class constants was introduced. It was not supported until then.
Example
<?php
class A {
public const A = 1;
}
$b = 'A';
echo A::{$b};
?>
Alternatives
- Upgrade PHP to PHP 8.3 or more recent.
- Use a call to constant() to reach the value of the class constant.
syntax error, unexpected token “;”, expecting “)”
Description
A semi-colon was found after an opening parenthesis. To keep the code balanced, PHP expects the parenthesis to be closed before finishing the instruction.
Example
<?php
array(1,2; );
foo(3,4;);
function foo($a = 3;) {}
?>
Alternatives
- Remove the semi-colon.
- Close the parenthesis before the semi-colon.
Related error messages
syntax error, unexpected token “;”, expecting “,” or “)”
Description
The declare instruction was not finished properly. declare accepts one or more parameter. With one parameter, the instruction must be closed with a closing parenthesis after the value expression; with multiple parameters, the parameters are separated by commas ,, and the last parameter is followed by a closing parenthesis.
This error message is dedicated to declare, as similar other syntaxes yield distinct error messages.
Example
<?php
declare(strict_types=1;
?>
Alternatives
- Add a closing parenthesis between the
1and the semi-colon;. - Add a comma after the
1, provide another parameter, and close thedeclarewith a closing parenthesis.
Related error messages
syntax error, unexpected token “;”, expecting “->” or “?->” or “[”
Description
The & reference operator turns a value into a reference. It works with data containers, such as variables, properties or array elements. It doesn’t work on literal constants.
The error message suggestion to use extra operators such as [ or -> leads to a distinct error: Cannot use temporary expression in write context.
This error is also raised with a reference on a new operator. The problem is on the reference operator, but the parser tries to understand more details later in the code before coming back to it.
Example
<?php
$a = &E_ALL;
const B = [1,2,3];
//Cannot use temporary expression in write context
$c = &B[2];
// The error is actually on the &
$x = & new X();
?>
Alternatives
- Store the constant in a variable, and make the reference on the variable.
- Use constants by value, not by reference.
- Remove the reference operator
&before the new call.
Related error messages
In previous PHP versions, this error message used to be :ref:syntax-error,-unexpected-token-";",-expecting-"->"-or-"?->"-or-"{"-or-"[".
syntax error, unexpected token “;”, expecting “->” or “?->” or “{” or “[”
Description
The & reference operator turns a value into a reference. It works with data containers, such as variables, properties or array elements. It doesn’t work on literal constants.
The error message suggestion to use extra operators such as [ or -> leads to a distinct error: Cannot use temporary expression in write context. The suggestion to use { is the then-deprecated curly brace syntax for array access. It is still valid in PHP 8.3, but removed in PHP 8.4.
Example
<?php
$a = &E_ALL;
const B = [1,2,3];
//Cannot use temporary expression in write context
$c = &B[2];
?>
Alternatives
- Store the constant in a variable, and make the reference on the variable.
- Use constants by value, not by reference.
Related error messages
In previous PHP versions, this error message used to be :ref:syntax-error,-unexpected-';',-expecting-'['.
In more recent PHP versions, this error message is now :ref:syntax-error,-unexpected-token-";",-expecting-"->"-or-"?->"-or-"[".
syntax error, unexpected token “;”, expecting “]”
Description
A semi-colon was found after an opening square bracket. To keep the code balanced, PHP expects the bracket to be closed before finishing the instruction.
Example
<?php
[1,2; ];
$a[4;];
?>
Alternatives
- Remove the semi-colon.
- Close the square bracket before the semi-colon.
syntax error, unexpected token “;”, expecting “function” or “fn” or “static” or “#[”
Description
In this command, an attribute has been configured. The attributes can only precede a structure, such as a class, method or function.
In this case, the attribute has been placed inside an expression, so only a closure can be declared: hence, the request for a function, fn. That closure could be static or have another attribute.
In the end, the closure is not compatible with the + or similar operator, so the suggestion is not valid here. It could be valid with a comma.
This error appears after PHP 8.0: this is when the #[ token was introduced. Until that version, # introduces a comment, until the end of the line.
Example
<?php
1 + #[attribute];
Alternatives
- Remove the attribute.
- Turn the
#comment into a//comment.
Related error messages
- [syntax-error,-unexpected-token-“)”,-expecting-“function”-or-“fn”-or-“static”-or-“#“
syntax error, unexpected token “;”, expecting “{”
Description
Namespace accepts two syntaxes: the first one with an ending semi-colon, or a block, which starts with an opening curly bracket.
In the current case, there is another feature at play: the name of the namespace may be empty, to refer to the global namespace. In that case, either the namespace keyword is omitted, or a block is defined after the namespace.
Example
<?php
namespace ;
?>
Alternatives
- Remove the
namespace ;entirely. - Add a block after the
namespace, and remove the semi-colon.
syntax error, unexpected token “;”, expecting identifier
Description
The use instruction is not finished properly: as expects a name after it.
Example
<?php
use A\B as ;
?>
Alternatives
- Finish the
use+aswith an alias name. - Remove the
asto make a simpleuseinstruction.
syntax error, unexpected token “;”
Description
The semi-colon marks the end of a command. They are needed in blocks, or sequences of commands.
In the first case, the semi-colon signals the end of the exit command, and PHP is still parsing the if condition.
In the second case, the semi-colon is understated by the closing PHP tag. The previous attribute #[A] requires a structure (class, interface, function…), which is not found.
Example
<?php
// 'if' needs a second closing ), but PHP keeps parsing it until the semi colon.
if ($d !== foo() {
exit(1);
}
#[A()]
// This is an attribute, and it needs a structure to apply to.
?>
Alternatives
- Check previous opening and closing parenthesis, they might be unbalanced.
syntax error, unexpected token “<<”
Description
This error might be related to the left bitshift operator, although it is often related to a git diff leftover. Here, a merge conflict was left in the code, and the first and erroneous characters are <<.
There are other possibilities of error with that operator, although they are less common.
Example
<?php
<<<<<<< HEAD
$a = 2 * $b;
=======
$a = 3 * $b + 1;
>>>>>>> e0ce25cd1fe156c2f50def834532e489b923dcef
?>
Alternatives
- Remove the diff from the code, as it doesn’t compile.
- Fix the merge conflict.
syntax error, unexpected token “=”, expecting identifier or variable or “{” or “$”
Description
The object operators -> and ?-> both expect a name as second operand, aka on the right. Here, the name was forgotten and the operator tried to use = as a name, which is not allowed.
Example
<?php
// missing a property
$object-> = 3;
// missing a property
$object?-> = 3;
?>
Alternatives
- Add a name after the
->and?->, such as$object->property. - Add a name inside a variable after the
->and?->, such as$object->$name. - Add a name inside an expression after the
->and?->, such as$object->{$variable . 'suffix'}. - Add a name inside an variable variable after the
->and?->, such as$object->$$variable.
Related error messages
syntax error, unexpected token “=”, expecting identifier
Description
In this error, the declared optin name value has been removed. It could be strict_types, ticks or encoding.
Example
<?php
declare(= 1);
declare(= 'iso-8859-1');
?>
Alternatives
- Add
strict_typesbefore the=operator. - Add
ticksbefore the=operator. - Add
encodingbefore the=operator. - Remove the
declarecall.
syntax error, unexpected token “=”, expecting variable
Description
The name of the parameter was removed. The parameter name has the syntax of a variable, hence the expected variable mentioned in the error.
Example
<?php
function foo( = 0) {}
?>
Alternatives
- Add the argument name.
- Remove the parameter entirely.
syntax error, unexpected token “=”
Description
The = assignation operator is found after a constant name. Constants are defined with const keyword, and later, they are not changed.
Example
<?php
a = 1;
?>
Alternatives
- Turn the constant name into a variable name by adding a
$sign before it. - Make this code a constant definition by adding
constbefore it, if it was not already defined.
syntax error, unexpected token “>”
Description
This syntax error is characteristic of the pipe operator |> being used in version older than PHP 8.5.
Example
<?php
'abc' |> strtoupper(...);
?>
Alternatives
- Upgrade to PHP 8.5.
- Nest the calls, instead of using the pipe operator.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected token “?”, expecting identifier
Description
This error happens when trying to add a type to a global constant. Only class constants can be typed, since PHP 8.3; a top-level const declaration never supports a type, so the parser expects the constant’s identifier right after the const keyword and rejects the ? (or any other type token) that appears instead.
Example
<?php
const ?int GLOBAL_TYPED = true;
?>
Alternatives
- Make the constant a class constant, which can be typed since PHP 8.3.
- Remove the type from the constant definition.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected token “?”
Description
? is used in several syntaxes in PHP.
- as
nullin a type specification (argument, returntype, property, class constant), when it is the first type specified:?A $a - as the terny operator
$condition ? $then : $else. Then, the condition must be a complete expression.
Example
<?php
// an unfinished ternary operation
$a = 1 + ? 3 : 2 ;
// ? should be written null in a type specification
function foo(a|? $a) {}
?>
Alternatives
- Finish the expression before the
?in a ternary operation. - Use the
nulltype when specifying a type.
Related error messages
syntax error, unexpected token “?->”, expecting “,” or “;”
Description
The object operator ?-> is used in an expression, where it is not expected.
Here, it is a global variable statement. Such statement were possible in PHP 5 and older, but are not valid anymore since PHP 7.0. Then, PHP would use the content of the property as the name of the global variable.
The same error is emitted with static variables, with the :: and the -> operators.
Example
<?php
global $object->property;
static $object->property;
?>
Alternatives
- Remove the property or method call from the global instruction.
Related error messages
- syntax-error,-unexpected-token-“::”,-expecting-“,”-or-“;”
- syntax-error,-unexpected-token-“->”,-expecting-“,”-or-“;”
syntax error, unexpected token “?->”
Description
This error reports that the object syntax was not expected there.
One classic reason is the new syntax in PHP 8.4, where parenthesis are not necessary, right after a new, to call properties or methods. This syntax actually requires the parenthesis.
Example
<?php
// should be new X()?->method();
new X?->method();
?>
Alternatives
- Add the parenthesis on the
newcall.
Related error messages
syntax error, unexpected token “??”
Description
?? is used as the coalesce operator.
The expression on the left side of that operator must be completed of it to be valid.
Example
<?php
// an unfinished coalesce operation
$a = 1 + ?? 3;
?>
Alternatives
- Finish the expression before the
?in a ternary operation.
Related error messages
syntax error, unexpected token “]”
Description
This error appeas when the closing bracket is needed, but not at that place.
In the illustration, the closing square bracket should be not be used directly after a multiplication sign: that operator needs a second operand.
Example
<?php
$a = [3 * 3 * ];
?>
Alternatives
- Add the missing operand to the previous operator.
Related error messages
- syntax-error,-unexpected-token-“}”
- syntax-error,-unexpected-token-“)”
- syntax-error,-unexpected-token-“(”
syntax error, unexpected token “NAMESPACE”, expecting “(”
Description
It is not possible to use __NAMESPACE__ or any other magic constant as a function or method name. This error is case insensitive.
Example
<?php
function __NAMESPACE__() {}
?>
Literal Examples
- syntax-error
Alternatives
- Use another name than
__NAMESPACE__.
syntax error, unexpected token “as”
Description
The as token was found, where it was not expected. as is often used as a modulator of another instruction: foreach, use, function.
Example
<?php
A\B as C;
?>
Alternatives
- Add a missing
useto start the instruction.
syntax error, unexpected token “break”
Description
break is a token that stop the current loop or switch, and proceed from the end of that loop. break is standalone expression, and cannot be part of another expression: this is why it is forbidden in the array, or the match command.
Example
<?php
// break does not fit everwhere
$a = [1 => break ];
// break is for switch, not match
$b = match($c) {
1 => break,
};
?>
Alternatives
- Remove the break, and find another way to jump out of the loop.
Related error messages
syntax error, unexpected token “class”, expecting-“]”
Description
The previous attribute was not closed with a square bracket, and its syntax is spilling over the supporting class.
Example
<?php
#[Attribute()
class X {}
?>
Alternatives
- Remove the attribute.
- Close the attribute with a square bracket.
Related error messages
- [syntax-error,-unexpected-token-“::”,-expecting-“]”](syntax-error,-unexpected-token-::,-expecting-].html)
- [syntax-error,-unexpected-token-“public”,-expecting-“]”](syntax-error,-unexpected-token-public,-expecting-].html)
syntax error, unexpected token “const”
Description
There are several reasons why a const token is found misplaced.
Attributes on global constants are supported since PHP 8.5. Before that version, they are not recognized, and yield this syntax error.
The error also appears when the const keyword is used in the body of the code, outside the main code: this means in any control flow block, such as ifthen, switch, etc. and in any structure like function, method, etc. It is still OK to use const in the body of a class, interface, trait or enum. In such cases, one must use define() to define a constant.
Example
<?php
#[ConstAttribute]
const A = 1;
if ($condition) {
// global constant must be in the global space, and cannot be conditional
const X = 2;
}
class X {
function foo() {
// global constant must be in the global space, and cannot be conditional
const Y = 2;
}
}
?>
Alternatives
- Remove the attribute.
- Refactor the global constant to a class constant.
- Use define() instead of const.
- Use the ternary operator
? :inside the constant definition. - Use inclusion.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected token “continue”
Description
continue is a token that stop the current loop or switch, and proceed from the end of that loop. continue is standalone expression, and cannot be part of another expression: this is why it is forbidden in the array, or the match command.
Example
<?php
// break does not fit everwhere
$a = [1 => continue ];
// break is for switch, not match
$b = match($c) {
1 => continue,
};
?>
Alternatives
- Remove the continue, and find another way to jump out of the loop.
Related error messages
syntax error, unexpected token “exit”
Description
This error reports a badly placed exit or die command. Both of them are represented with the same exit token, hence the naming of the error.
Example
<?php
$a = 1
die();
?>
Alternatives
- Make sure the previous instruction is complete, with its semi-colon.
syntax error, unexpected token “extends”, expecting “{”
Description
When declaring a class, the extends keyword must appear before the implements one. There is only one (or no) class extension, so the extends list is often shorter than the implements list.
Example
<?php
class X implements I1, I2 extends W {}
?>
Alternatives
- Move the
extendskeyword, and its class, right after the name of the class, and before theimplementskeyword. - Remove the
extendskeyword.
Related error messages
syntax error, unexpected token “extends”, expecting identifier
Description
The extends keyword may only be used after a class name, an interface name, or the parenthesis of an anonymous class.
Example
<?php
// this is missing the name of the class
class extends B {}
// this is missing the name of the interface
interface extends B {}
?>
Alternatives
- Add a name to the class.
- Add a name to the interface.
- Add set of parenthesis to the class to make it anonymous.
syntax error, unexpected token “extends”
Description
extends is a PHP token, which appears inside a class or interface structure. It cannot be find anywhere else.
Example
<?php
X extends Y { }
enum Y extends Z { }
?>
Alternatives
- Check that a
classor aninterfacehave been started.
Related error messages
syntax error, unexpected token “final”, expecting “(”
Description
final is not a valid name for a function. It is a valid name for a method, though.
Example
<?php
function final() {};
?>
Alternatives
- Use another name for that function.
- Remove the name, and create a closure instead.
syntax error, unexpected token “if”, expecting “)”
Description
If-then commands are standalone commands. They can’t be part of another expression. Here, PHP found the if, while it was expecting another expression.
Then, PHP mentions that it was expecting ): this usually hints at an unclosed method call syntax. In the example here, the previous line holds an unclosed function call to foo.
Example
<?php
$a = foo(1
if ($a == 2) {
print OK;
}
?>
Alternatives
- Look for the previous opening
(parenthesis in functioncalls and check that it is balanced. - Look for all previous openings
(parenthesis in functioncalls and check that they are all balanced.
syntax error, unexpected token “if”, expecting “]”
Description
If-then commands are standalone commands. They can’t be part of another expression. Here, PHP found the if, while it was expecting another expression.
Then, PHP mentions that it was expecting ]: this usually hints at an unclosed array syntax. In the example here, the previous line holds an unclosed array.
Example
<?php
$a = [1,2,
if ($a == 2) {
print OK;
}
?>
Alternatives
- Look for the previous opening
[square bracket and check that it is all balanced. - Look for all previous openings
[square brackets and check that they are all balanced.
Related error messages
- [syntax-error,-unexpected-token-“::”,-expecting-“]”](syntax-error,-unexpected-token-::,-expecting-].html)
- [syntax-error,-unexpected-token-“public”,-expecting-“]”](syntax-error,-unexpected-token-public,-expecting-].html)
syntax error, unexpected token “if”
Description
If-then expressions are standalone expressions, and cannot be used inside another expression. Hence, they must be preceded by a semi-colon, or any other expression closing character.
Example
<?php
$a = foo() && if ($a == 2) { echo $a; } else { echo "No A"; }
match(
if ($a == 2) { echo $a; } else { echo "No A"; }
?>
Alternatives
- Replace the
&&by a semi-colon. - Move the
$a = foo() &&inside the if condition, before the$a == 2. - Check for opening parenthesis, and make sure they are closed.
- Check for previous statements that uses parenthesis, such as match, switch, if… and make sure they are closed.
syntax error, unexpected token “implements”
Description
implements is a PHP token, which appears inside a class or enum structure. It cannot be find anywhere else.
Example
<?php
X extends Y { }
enum Y extends Z { }
?>
Alternatives
- Check that a
classor anenumhave been started.
Related error messages
syntax error, unexpected token “match”, expecting “(”
Description
Since match was introduced as a PHP keyword, it cannot be used anymore to name a class, interface, enum, trait, function or global constant. It may be used to name a class constant, method or property.
Example
<?php
function match($a) {}
?>
Alternatives
- Change the name
match. - Make the function a method in a class.
syntax error, unexpected token “match”
Description
In PHP 8.0, the match statement was added to PHP feature: it is a similar feature to switch. match is now a PHP reserved keyword, and, as such, cannot be used everywhere. For example, it cannot be used as a class, function or interface name; it cannot be used in a function call, although it may be used in method call.
Example
<?php
$x = match ($a) {};
?>
Alternatives
- Change the name to something else than
match.
syntax error, unexpected token “namespace”, expecting “{”
Description
The namespace token is one of the first to be used in a script. There is little other command that can be used outside a namespace.
Example
<?php
namespace A
namespace B;
?>
Alternatives
- Check the previous namespace command, and its final semi colon.
- Check the previous namespace command, and its associated block.
syntax error, unexpected token “namespace”
Description
The namespace token is one of the first to be used in a script. There is little other command that can be used outside a namespace.
Example
<?php
declare(strict_types=1)
namespace A;
?>
Alternatives
- Check the previous declare command, and its final semi colon.
syntax error, unexpected token “new”, expecting “)”
Description
This error is a variation of the named parameter typo: the missing semi colon between the name and the value leads to an identifier next to an unrelated operator. The suggestion to use a closing parenthesis is valid, though not the only one.
Example
<?php
foo(arg new B());
class B {}
function foo(B $arg) {}
?>
Alternatives
- Add the missing
:before the new operator. - Add the missing
)before the new operator, and add a semi-colon or a comman, depending on the context.
syntax error, unexpected token “private”, expecting “(”
Description
The opening parenthesis that follows a method name is missing. It would be followed by a promoted property declaration, which starts with private.
The same error may apply with the other PHP visibilities, or property options, such as static or readonly.
Example
<?php
class X
{
public function __construct
private Y $y,
) {
}
}
?>
Alternatives
- Add the missing opening parenthesis.
syntax error, unexpected token “private”, expecting “)”
Description
private is not expected at this position in the code, as the previous property $a is not finished. It would be finished with a closing parenthesis ), as suggested by the error message, or a comma, to introduce the next property.
This error message might have other variations, such as protected, public, static, readonly, abstract, final.
Example
<?php
class ProcessController extends AbstractController
{
public function __construct(
public A $a
private B $b,
) {
}
}
?>
Alternatives
- Add a comma to introduce the next property or argument.
- Add a closing parenthesis to close the signature and the previous property.
syntax error, unexpected token “private”, expecting “=”
Description
The name of class constant could not use PHP keywords, such as the visibilities private, protected and public; optiosn such as abstract or final, until PHP 8.3. Until then, they would generate a parse error. Such names are generally not used, as they easily sow confusion in the code, at definition but also at usage.
Example
<?php
class X {
private const string private = 'protected';
}
?>
Alternatives
- Use another name for the constant.
- Upgrade to PHP 8.3 or more recent.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected token “private”, expecting “{”
Description
private and the other visibility options are only seen inside a class or CITE. They mark the start of their definition (property, constant, method), and can only be seen in the body of the CITE.
With an expected opening curly brace, this means the class signature was not finished with the opening curly brace.
Example
<?php
class X
private function foo() {}
}
?>
Alternatives
- Add the opening curly bracket between the class signature and its body.
- Add the opening curly bracket between the interface signature and its body.
- Add the opening curly bracket between the trait signature and its body.
- Add the opening curly bracket between the enum signature and its body.
Related error messages
- syntax-error,-unexpected-token-“protected”,-expecting-“{”
- syntax-error,-unexpected-token-“public”,-expecting-“{”
syntax error, unexpected token “protected”, expecting “{”
Description
protected and the other visibility options are only seen inside a class or CITE. They mark the start of their definition (property, constant, method), and can only be seen in the body of the CITE.
With an expected opening curly brace, this means the class signature was not finished with the opening curly brace.
Example
<?php
class X
protected function foo() {}
}
?>
Alternatives
- Add the opening curly bracket between the class signature and its body.
- Add the opening curly bracket between the interface signature and its body.
- Add the opening curly bracket between the trait signature and its body.
- Add the opening curly bracket between the enum signature and its body.
Related error messages
- syntax-error,-unexpected-token-“public”,-expecting-“{”
- syntax-error,-unexpected-token-“private”,-expecting-“{”
syntax error, unexpected token “public”, expecting “]”
Description
Inside the square brackets of an array index, PHP expects an expression identifying the key, followed by the closing ]. public is a reserved word: it can only be used as a visibility modifier, never as the start of an expression, such as an unquoted array key. PHP therefore reports that it was still expecting ] to close the array access.
The same message also appears whenever a previous [ was left unclosed, and a later, unrelated public is the first token that cannot continue the pending index expression.
Example
<?php
$arr = [1, 2, 3];
$y = $arr[public];
?>
Alternatives
- Quote the key if a string was intended:
$arr['public']. - Use a constant or variable holding the intended key instead of the bare word.
- Check that every previous
[in the file has a matching].
Related error messages
- [syntax-error,-unexpected-token-“::”,-expecting-“]”](syntax-error,-unexpected-token-::,-expecting-].html)
- [syntax-error,-unexpected-token-“class”,-expecting-“]”](syntax-error,-unexpected-token-class,-expecting-].html)
- [syntax-error,-unexpected-token-“if”,-expecting-“]”](syntax-error,-unexpected-token-if,-expecting-].html)
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected token “public”, expecting “{”
Description
public and the other visibility options are only seen inside a class or CITE. They mark the start of their definition (property, constant, method), and can only be seen in the body of the CITE.
With an expected opening curly brace, this means the class signature was not finished with the opening curly brace.
Example
<?php
class X
public function foo() {}
}
?>
Alternatives
- Add the opening curly bracket between the class signature and its body.
- Add the opening curly bracket between the interface signature and its body.
- Add the opening curly bracket between the trait signature and its body.
- Add the opening curly bracket between the enum signature and its body.
Related error messages
- syntax-error,-unexpected-token-“protected”,-expecting-“{”
- syntax-error,-unexpected-token-“private”,-expecting-“{”
syntax error, unexpected token “public”
Description
The keyword public is expected in a PHP method body, but not in the body of a method or a function.
This may apply to the other visibilies, protected and private, and also to some other method options, such as abstract.
Example
<?php
class A {
function foo() {
public $x;
}
}
?>
Alternatives
- Close the initial method body, before creating another property or method with a visibility.
- Remove the
publickeyword in the body of the method.
syntax error, unexpected token “use”, expecting “,” or “;”
Description
The previous use command was not properly finished with a semi-colon.
Example
<?php
use A as B
use C as D;
?>
Alternatives
- Add another
usecase, with a comma, and then finish the instruction with;. - Finish the previous
usecase, with a semi colon;. - Remove the next
usekeyword, and replace it with a comma.
Related error messages
syntax error, unexpected token “use”, expecting “{”
Description
The namespace command was now finished properly. It could be finished with a semi-colon ;, and use would be the next instruction. Or it could go be followed by a block of definition, that starts with an open curly bracket.
Example
<?php
namespace A\B\C
use D\E;
?>
Alternatives
- Finish the
namespacewith a semi colon. - Add a block to the
namespace, that encompass theuseinstruction.
syntax error, unexpected token “use”
Description
use expression must be place at the top level of a file, a namespace block, or a class, enum or trait block.
In particular, when set in a structure such as a foreach, it yields a syntax error.
Besides that, the command is actually valid.
Example
<?php
if ($a) {
use stdClass as A;
}
?>
Alternatives
- Move the
useout of the if structure. - Remove the
usecommand.
Related error messages
syntax error, unexpected token “{”, expecting “)”
Description
This is a side effect of the removed support for curly braces as array and string offset syntax. Here, the parser was reading a function call’s argument list and reached the point where it expects the closing parenthesis, but found the leftover curly brace instead. This exact wording appears since PHP 8.0, when curly-brace offset access was removed from the language.
Example
<?php
echo foo($variable{$index});
?>
Alternatives
- Refactor the curly braces to square ones.
Related error messages
- syntax-error,-unexpected-token-“{”
- array-and-string-offset-access-syntax-with-curly-braces-is-no-longer-supported
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected token “{”, expecting “,” or “;”
Description
PHP 8.4 introduced property hooks, which allow defining getters and setters for properties directly in the property definition. Previous PHP versions did not support that syntax, and yield this error.
Example
<?php
class A {
public $prop {
get { return A; }
set { echo __METHOD__, \n; }
}
}
?>
Alternatives
- Upgrade to PHP 8.4.
- Remove the property hooks.
- Move the property hooks to a method.
- Move the property hooks to a magic method.
syntax error, unexpected token “{”, expecting “;”
Description
This is a side effect of the removed support for curly braces as array and string offset syntax. Here, the parser has just finished reading a statement and expects a terminating ;, but instead finds a leftover curly brace that used to introduce an offset expression. This exact wording appears since PHP 8.0, when curly-brace offset access was removed from the language.
Example
<?php
$variable{$index} = 'value';
?>
Alternatives
- Refactor the curly braces to square ones.
Related error messages
- syntax-error,-unexpected-token-“{”
- array-and-string-offset-access-syntax-with-curly-braces-is-no-longer-supported
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected token “{”, expecting variable
Description
With the last comma in the signature of the method, PHP expects another parameter after it, or the end of the signature with a closing parenthesis.
Example
<?php
class A {
public function __construct($b,
{ }
}
?>
Alternatives
- Add a closing parenthesis.
- Add another parameter, then a closing parenthesis.
Related error messages
syntax error, unexpected token “{”
Description
A syntax error is a generic error, where PHP could not compile the code. Here are some classic typo or seemingly valid code that leads to this error.
- Since PHP 8.4, array syntax with curly braces are not valid anymore. It used to yield a warning, and it is now totally abandoned.
- A missing closing parenthesis in a crowded parenthesis space, leads to an error in the next block.
Example
<?php
// the curly bracket array syntax has been removed
$a{1} = 2;
// curly brackets start a block, and blocks are not allowed inside expressions (the && )
$a == 1 && {1} : 3;
?>
Alternatives
- Move to the square bracked array syntax only.
- Add the missing closing parenthesis to the if() statement.
Related error messages
- syntax-error,-unexpected-token-“}”
- syntax-error,-unexpected-token-“{”,-expecting-“)”
- syntax-error,-unexpected-token-“{”,-expecting-“;”
syntax error, unexpected token “}”, expecting “;” or “{”
Description
PHP found a closing curly bracket, but did not encounter its opening equivalent. Since the problem appears in the signature of a method, there are two suggestions: make the method abstract, with a semi-colon ‘;’, or give the method a full body, with the opening curly bracket.
Example
<?php
class A
{
public function __construct()
}
}
?>
Alternatives
- Add an opening curly bracket ‘{’ before the closing one. Possibly, fill the body of the method.
- Replace the closing curly bracket with a semi colon. The method, and possibly the class, must now be abstract.
syntax error, unexpected token “}”
Description
The closing curly bracket usually mark the end of a block of instructions.
When it is reported as an error, it means that the previous instruction was not closed as expected. For example, when a semi-colon was not forgotten on the previous line.
Example
<?php
// print needs a ; at the end of the command
if ($c == 3) { print 'OK'.PHP_EOL }
// The curly brackets are balanced, but not the parenthesis
if (in_array(1, [2, 4]) {}
?>
Alternatives
- Check if the previous line need a semi-colon
;.
Related error messages
- syntax-error,-unexpected-token-“{”
- syntax-error,-unexpected-token-“(”
- syntax-error,-unexpected-token-“)”
- [syntax-error,-unexpected-token-“]”](syntax-error,-unexpected-token-].html)
syntax error, unexpected variable “$%s”, expecting “)”
Description
In a function, method or closure signature, each parameter must be separated from the next one by a comma. Here, the comma between $a and $b is missing, so once PHP has parsed $a as a complete parameter, it expects either another comma or the closing parenthesis of the argument list; instead it finds another variable.
Example
<?php
function foo($a $b) {}
?>
Literal Examples
- syntax error, unexpected variable “$b”, expecting “)”
Alternatives
- Add the missing comma between the two parameters.
- Remove the extra variable if it was left over from editing.
Related error messages
- syntax-error,-unexpected-variable-“$task”,-expecting-“)”
- syntax-error,-unexpected-token-“)”,-expecting-variable
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected variable “$task”, expecting “)”
Description
In a function, method or closure signature, each parameter must be separated from the next one by a comma. Here, the comma between $name and $task is missing, so once PHP has parsed $name as a complete, typed parameter, it expects either another comma or the closing parenthesis of the argument list; instead it finds another variable, $task.
This is the generic “unexpected variable, expecting )” message, reported here with the concrete variable name found in the offending code, $task.
Example
<?php
function schedule(string $name $task) {}
?>
Alternatives
- Add the missing comma between the two parameters.
- Remove the extra variable if it was left over from editing.
Related error messages
- syntax-error,-unexpected-variable-“$%s”,-expecting-“)”
- syntax-error,-unexpected-token-“)”,-expecting-variable
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected variable “$this”, expecting “;” or “{”
Description
An abstract method’s signature must be terminated with a semicolon, since it has no body, and a concrete method’s signature must be followed by a { opening the body. Here, the variable $this was found right after the closing parenthesis of the argument list, where PHP expected one of those two terminators.
$this cannot appear here in any case: it is a read-only pseudo-variable, automatically bound to the current object inside a non-static method, and it can never be declared, assigned or used as a standalone statement outside of an expression.
Example
<?php
abstract class X {
abstract function foo() $this;
}
?>
Alternatives
- Remove
$thisand terminate the abstract method with a semicolon. - If a method body was intended, replace
$thiswith{and the method’s code.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
syntax error, unexpected variable “%s”, expecting “(”
Description
In a function definition, the name of the function is separated from the argument list by an opening parenthesis. This is missing here. This applied to closures, arrow functions and methods’ signatures.
Example
<?php
function foo $name: , $value = 1) {}
function bar ) {}
?>
Alternatives
- Add the missing opening parenthesis.
- Provide a value for the parameter name in the functioncall.
Related error messages
The “Generator” class is reserved for internal use and cannot be manually instantiated
Description
Generator is a PHP native class. It is automagically created when a function or method uses the yield or yield from keyword. There is no other ways to create such an object.
In fact, generator is also a final class, so it cannot be extended too.
Example
<?php
new Generator();
?>
Alternatives
- Use composition to use this class in another class.
Related error messages
The $context parameter has no effect for finfo_buffer()
Description
finfo_buffer() (and finfo::buffer()) accept an optional $context parameter, mirroring the signature of stream-related functions. Unlike finfo_file(), which does use a stream context to open the file it inspects, finfo_buffer() operates directly on an in-memory string and never opens a stream, so the $context argument has never had any effect.
As of PHP 8.5.0, passing a value for $context raises a deprecation notice to reflect that fact.
Example
<?php
$finfo = new finfo(FILEINFO_MIME_TYPE);
$context = stream_context_create();
echo $finfo->buffer('some data', FILEINFO_NONE, $context);
?>
Alternatives
- Stop passing a
$contextargument tofinfo_buffer()/finfo::buffer().
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See finfo_buffer
the $escape parameter must be provided, as its default value will change, either explicitly or via SplFileObject::setCsvControl()
Description
SplFileObject::fgetcsv() and SplFileObject::fputcsv() take an $escape character used to escape the enclosure character inside CSV fields, currently defaulting to \ (backslash) – a default that PHP 9.0 will change to an empty string, disabling escaping entirely by default, to better match RFC 4180 and other CSV parsers.
As of PHP 8.4, calling fgetcsv()/fputcsv() on a SplFileObject without an explicit $escape – and without having set one explicitly via SplFileObject::setCsvControl() either – emits this deprecation notice, so the pending default change does not silently alter behaviour later.
Example
<?php
file_put_contents('/tmp/data.csv', "a,b,c\n");
$file = new SplFileObject('/tmp/data.csv');
$file->setFlags(SplFileObject::READ_CSV);
// No $escape argument, and setCsvControl() was never called to set
// one explicitly either, so the (soon to change) default is used.
var_dump($file->fgetcsv());
?>
Literal Examples
- SplFileObject::fgetcsv(): the $escape parameter must be provided, as its default value will change, either explicitly or via SplFileObject::setCsvControl()
Alternatives
- Pass $escape explicitly on every fgetcsv()/fputcsv() call, e.g. $file->fgetcsv(‘,’, ‘“’, ‘\’).
- Call SplFileObject::setCsvControl() once with the escape character, so every later fgetcsv()/fputcsv() call already has it set.
- Decide now whether the code needs backslash-escaping (pass ‘\’) or the future default (pass ‘’) and stop depending on the implicit default either way.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See fputcsvEscape
the $escape parameter must be provided as its default value will change
Description
The $escape parameter of various PHP functions that deal with CSV files will change in PHP 9.0. The current default value is \ (backslash), and it will be changed to an empty string. To be ready for that version, it is recommended to explicitly set that value, so as to preserve the previous behavior, with a \, or move to the new one, with an empty string.
Example
<?php
$fp = fopen(export.csv, w);
fputcsv($data);
?>
Alternatives
- Add the 5th parameter in the fputcsv() or fgetcsv() calls.
- Add the named parameter
escapein the calls. - Test your application with
escapeset to empty string, and PHP 8.4+.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See fputcsvEscape
the $key_length parameter is deprecated as it is either ignored or truncates the key
Description
openssl_pkey_derive() computes a shared secret from a private key and a peer’s public key (for DH or ECDH key agreement), and accepts an optional $key_length argument that was documented as controlling the length of the derived secret.
In practice, this parameter is either ignored entirely (when it is larger than or equal to the natural size of the underlying prime/curve) or silently truncates the derived key (when it is smaller), which can give a false sense of control over the output length and lead to weakened, truncated secrets being used unknowingly. As of PHP 8.5.0, passing a value for $key_length raises a deprecation notice.
Example
<?php
$sharedSecret = openssl_pkey_derive($peerPublicKey, $privateKey, 32);
?>
Alternatives
- Stop passing
$key_lengthtoopenssl_pkey_derive(), and if a specific length is required, derive it explicitly from the full secret afterwards (e.g. with a KDF such ashash_hkdf()).
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See openssl_pkey_derive
The (real) cast operator has been removed, use (float) instead. Both operator looked like synonyms, and were providing the same feature.
Description
The (real) cast operator was deprecated in PHP 7.x and is completely removed since PHP 8.0. It may be replaced with (float).
Example
<?php
$float = (real) "1.333";
?>
Alternatives
- Use
(float)instead.
In previous PHP versions, this error message used to be :ref:the-(real)-cast-is-deprecated,-use-(float)-instead.
The (real) cast is deprecated, use (float) instead
Description
The (real) cast operator is deprecated since PHP 7.4. It was completely removed in PHP 8.0. (real) was a synonym of (float), although there is no such notion in PHP.
Example
<?php
$float = (real) 1.333;
?>
Alternatives
- Use
(float)instead.
In more recent PHP versions, this error message is now :ref:the-(real)-cast-has-been-removed,-use-(float)-instead.
The (unset) cast is deprecated
Description
Removing a variable, a property or an array index with the cast operator (unset) is deprecated since PHP 7.4, and will be removed in PHP 8.0. It is recommnded to do it with the unset() function.
Example
<?php
(unset) $x;
?>
Alternatives
- Use the unset() function to remove variables.
- Assign null to the variable.
In more recent PHP versions, this error message is now :ref:the-(unset)-cast-is-no-longer-supported.
The (unset) cast is no longer supported
Description
Removing a variable, a property or an array index with the cast operator (unset) was removed in PHP 8.0. It has to be done with the unset() function.
Example
<?php
(unset) $x;
?>
Alternatives
- Use the unset() function to remove variables.
- Assign null to the variable.
In previous PHP versions, this error message used to be :ref:the-(unset)-cast-is-deprecated.
The “salt” option has been ignored, since providing a custom salt is no longer supported
Description
password_hash() used to accept a salt option, which let the caller choose the salt of the hash. This is no longer supported: the option is ignored, and password_hash() generates a random salt itself. The hash is still returned, so the code keeps running, but the custom salt does not appear in it.
A custom salt was a weak practice, as a fixed or badly chosen salt makes it easier to attack many hashes at once. Since the salt is stored inside the hash, password_verify() works without the caller managing it.
Example
<?php
// The salt option is ignored: password_hash() generates its own salt
$hash = password_hash('password', PASSWORD_DEFAULT, ['salt' => 'a-custom-salt-value']);
?>
Literal Examples
- password_hash(): The “salt” option has been ignored, since providing a custom salt is no longer supported
Alternatives
- Remove the
saltoption.password_hash()already generates a random salt for each hash. - To check a password, use
password_verify(), which reads the salt from the stored hash.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The "ssl_method" option is deprecated. Use "ssl" stream context options instead
Description
SoapClient accepts an 'ssl_method' constructor option to pick which SSL/TLS version to use, predating PHP’s general-purpose stream context SSL options. In practice it offers little control: SOAP_SSL_METHOD_TLS and SOAP_SSL_METHOD_SSLv23 both just mean ‘the default’, SOAP_SSL_METHOD_SSLv2 always fails since PHP no longer supports SSL 2, and SOAP_SSL_METHOD_SSLv3 selects a protocol considered insecure for years.
As of PHP 8.1, passing 'ssl_method' emits this deprecation notice; the far more capable 'ssl' stream context options (in particular crypto_method) already cover the same need for every other stream-based extension, including individual TLS versions that ssl_method cannot select at all.
Example
<?php
$client = new SoapClient(null, [
'location' => 'https://example.com/soap',
'uri' => 'https://example.com/soap',
// Selecting the TLS version through this option is deprecated.
'ssl_method' => SOAP_SSL_METHOD_TLS,
]);
?>
Literal Examples
- SoapClient::__construct(): The “ssl_method” option is deprecated. Use “ssl” stream context options instead
Alternatives
- Build a stream context with the desired ‘ssl’ => [‘crypto_method’ => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT] (or similar) and pass it via the ‘stream_context’ constructor option instead.
- Drop ‘ssl_method’ entirely if only the platform default TLS version is needed – that is what SOAP_SSL_METHOD_TLS already resolved to.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The "yield" expression can only be used inside a function
Description
yield is what turns a function into a generator: it can only appear inside a function body (a named function, a method, a closure, or an arrow function). Using it directly in the top-level script code – outside of any function – is meaningless, since there is no generator for it to belong to, and PHP rejects it at compile time.
The same error is raised for any yield (or yield from) written at the top level of an included or required file, as long as it is not nested inside a function definition there.
Example
<?php
yield 1;
?>
Alternatives
- Wrap the code that needs to yield values inside a generator function, and call that function instead.
- Remove the yield statement if it was left over by mistake.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The __sleep() serialization magic method has been deprecated.
Description
Class serialization in PHP has had multiple mechanism introduced to control its behaviour by userland. Initially with the __sleep() and __wakeup() magic methods, then with the Serializable interface and finally with __serialize() and __unserialize().
In the end, the __serialize and __unserialize methods must be used, instead of __sleep and __wakeup.
Example
<?php
class X {
function __sleep() {}
}
?>
Alternatives
- Rename the method to
__serialize.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The __wakeup() serialization magic method has been deprecated.
Description
Class serialization in PHP has had multiple mechanism introduced to control its behaviour by userland. Initially with the __sleep() and __wakeup() magic methods, then with the Serializable interface and finally with __serialize() and __unserialize().
In the end, the __serialize and __unserialize methods must be used, instead of __sleep and __wakeup.
Example
<?php
class X {
function __sleep() {}
}
?>
Alternatives
- Rename the method to
__unserialize.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The arguments array must contain %d items, %d given
Description
When using vsprintf(), the second argument is an array which must hold the same number of elements than there are placeholders in the format string (aka, the first argument).
Example
<?php
var_dump(vsprintf("%04d-%02d-%02d", []));
?>
Literal Examples
- The arguments array must contain 3 items, 0 given
Alternatives
- Add the needed elements to the array.
- Remove the superfluous placeholders in the format string.
The backtick (`) operator is deprecated, use shell_exec() instead
Description
The back tick operator \ is the equivalent to the functionshell_exec()`. It is being deprecated since PHP 8.5.
Example
<?php
echo `ls`;
?>
Alternatives
- Use shell_exec() instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See backtick
The behavior of unparenthesized expressions containing both ‘.’ and ‘+’/‘-’ will change in PHP 8: ‘+’/‘-’ will take a higher precedence
Description
+/- and . operators used to have the same priority. This meant that expressions which mixed them would see them executed from left to right. This was confusing, so PHP 8.0 has made the addition the highest priority, closer to human way of reading the code.
Example
<?php
$b = 2;
$a = 'a '. $b + 1;
?>
Alternatives
- Add parenthesis to make the code less ambiguous.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See dotAndMinus, dotAndPlus
The behavior of unparenthesized expressions containing both ‘.’ and ‘<<’/‘>>’ will change in PHP 8: ‘<<’/‘>>’ will take a higher precedence
Description
<</>> and . operators used to have the same priority. This meant that expressions which mixed them would see them executed from left to right. This was confusing, so PHP 8.0 has made the addition the highest priority, closer to human way of reading the code.
Example
<?php
$b = 2;
$a = 'a '. $b >> 1;
?>
Alternatives
- Add parenthesis to make the code less ambiguous.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See dotAndBitshift
The connection has no charset associated
Description
This error appears when PHP cannot retrieve the character set used by the connection to MySQL. The mysqli_get_charset() function tries to fetch the data from the connexion, but the result was not usable.
Such error is probably circumstancial: the server may have gone away, or crashed, leading to no answer about charset.
Example
<?php
$db = mysqli_init();
$db->real_connect(localhost,user,password,test);
var_dump($db->get_charset());
?>
Alternatives
- Check the server health.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The driver_version property is deprecated
Description
mysqli_driver::$driver_version reads back the internal constant MYSQLI_VERSION_ID, which sounds like it should report the version of the underlying MySQL client library (mysqlnd or libmysqlclient) but does not: it is a hardcoded value (101009) left over from mysqli’s early days as a standalone PECL extension, and it has not tracked anything meaningful for a long time.
As of PHP 8.1, reading this property emits a deprecation notice; it keeps returning the same frozen value for now, ahead of being removed in a future version.
Example
<?php
$driver = new mysqli_driver();
// Reading this property is deprecated; it has always just repeated
// PHP's own version number, not any driver-specific version.
var_dump($driver->driver_version);
?>
Literal Examples
- The driver_version property is deprecated
Alternatives
- Use PHP_VERSION or PHP_VERSION_ID directly if a PHP version number was actually wanted.
- Use mysqli_get_client_info() / mysqli_driver::$client_info if the actual client library version is needed.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The each() function is deprecated. This message will be suppressed on further calls
Description
The function each was deprecated in PHP 7.x and removed in PHP 8.0. It was mainly used in loops like the above, and could be replaced advantageously with a foreach structure.
Example
<?php
$array = ['a', 'b'];
while(list($key, $value) = each($array)) {
print "$key => $value\n";
}
?>
Alternatives
- Replace the while loop with a foreach one.
- Replace the loop with a call to one of the array function.
- Traverse the array with a
yieldoryield fromcall. - Use an
iteratorto traverse the array.
In more recent PHP versions, this error message is now :ref:call-to-undefined-function-each().
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See each
The filter.default ini setting is deprecated
Description
filter.default (with filter.default_flags) names a filter that PHP applies automatically to the $_GET, $_POST, $_COOKIE, $_REQUEST and $_SERVER superglobals themselves, as well as to filter_input() calls that don’t specify their own filter. Its own default is unsafe_raw (no filtering), but changing it to anything else effectively resurrects a magic-quotes-like behaviour: input gets silently sanitized (or mangled) based on a global setting the code reading $_GET/$_POST may not even be aware of, which was one of the classic sources of subtle bugs and security issues in old PHP applications.
As of PHP 8.1, setting filter.default to anything other than unsafe_raw emits this deprecation notice at startup. The setting keeps working for now, but filter.default (and filter.default_flags) are expected to be removed in PHP 9.0.
Example
<?php
// filter.default is PHP_INI_SYSTEM|PHP_INI_PERDIR, so it cannot be
// changed at runtime with ini_set() -- only in php.ini, .user.ini,
// httpd.conf, or via -d on the command line, for example
// php -d filter.default=int script.php
var_dump(ini_get('filter.default'));
?>
Literal Examples
- The filter.default ini setting is deprecated
Alternatives
- Leave filter.default at its default, unsafe_raw, and call filter_var()/filter_input() explicitly wherever input needs sanitizing or validating.
- Search the codebase for any place relying on the implicit global filter and make the filtering explicit there instead.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The float %.*H is not representable as an int, cast occurred
Description
When a float is cast to int – explicitly with (int)/intval(), or implicitly wherever an integer is required, such as an array offset or a bitwise operator – and the value is outside the range representable by PHP_INT_MIN/PHP_INT_MAX, or is NAN or INF, PHP cannot produce a meaningful integer.
Rather than silently returning an arbitrary or platform-dependent bit pattern, PHP emits this warning and returns 0 for NAN/INF, or a value obtained by taking the float modulo the 64-bit integer range for very large finite values – in both cases, a value with no reliable relationship to the original float.
Example
<?php
var_dump((int) 1.0E+20);
// int(0) on 64-bit, and the value bears no relation to 1.0E+20
var_dump((int) NAN);
// int(0)
var_dump((int) INF);
// int(0)
?>
Literal Examples
- The float 1.0E+20 is not representable as an int, cast occurred
- The float NAN is not representable as an int, cast occurred
- The float INF is not representable as an int, cast occurred
Alternatives
- Check the float against
PHP_INT_MIN/PHP_INT_MAX(and againstis_nan()/is_infinite()) before casting it. - Keep the value as a
floator as a string if it may exceed the integer range. - Use
BCMathorGMPif arbitrary-precision integers are required.
Related error messages
- the-float-string–“%s-”-is-not-representable-as-an-int,-cast-occurred
- implicit-conversion-from-float-%.*h-to-int-loses-precision
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The float-string “%s” is not representable as an int, cast occurred
Description
The string contains a numeric value, that could be parsed, even partially. Yet, the resulting number is bigger than the larger supported integer PHP_INT_MAX. At that point, PHP replace the parse numeric value to the maximum integer value.
The problem does not happen with float numbers, which are converted to INF infinity when they can’t be represented anymore.
This problem is often related to the presence of the e character in the string, which yield a possible float number.
Example
<?php
var_dump((int) 9E82);
//9223372036854775807
var_dump((float) 9E82);
//float(9.0E+82)
?>
Literal Examples
- The float-string “9E82” is not representable as an int, cast occurred
Alternatives
- Use the string, rather than convert it to an integer.
- Check if the string can be converted before using the cast.
- Compare the resulting value with
PHP_INT_MAX: it might be very far from the expected conversion.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The magic method %s::%s() must have public visibility
Description
The magic methods must have the public visibility, as their features are available to external sources. It may also use the default visibility.
Example
<?php
class X {
private function __isset($x) {}
protected function __get($x) {}
}
?>
Literal Examples
- The magic method X::__isset() must have public visibility
- The magic method X::__get() must have public visibility
- The magic method X::__set() must have public visibility
Alternatives
- Set the visibility to
public. - Remove the visibility, to use the default of
public. - Remove the magic method.
The maximum representable range is 2_147_483_647 seconds (roughly 68 years)
Description
PHP 8.6 introduces Time\Duration, a value object representing a span of time as whole seconds plus nanoseconds. Internally, the number of seconds is validated so that the whole duration, expressed in nanoseconds, still fits in a single platform integer (zend_long).
On a 32-bit build of PHP, where zend_long is only 32 bits wide, that ties the maximum number of seconds to PHP_INT_MAX on that platform: 2_147_483_647 seconds, or roughly 68 years. Passing a larger value throws a Time\TimeException. On 64-bit builds, the equivalent, larger limit is described separately (see the-maximum-representable-range-is-9_223_372_035-seconds-(roughly-292-years)).
Example
<?php
use Time\Duration;
// on a 32-bit build of PHP
$duration = Duration::fromSeconds(3_000_000_000);
?>
Literal Examples
- The maximum representable range is 2_147_483_647 seconds (roughly 68 years)
Alternatives
- Keep durations built from Duration::fromSeconds() (or the constructor) within PHP_INT_MAX seconds for the target platform.
- On 32-bit systems, split very long spans of time into smaller Duration values, or use DateInterval instead.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
Description
PHP 8.6 introduces Time\Duration, a value object representing a span of time as whole seconds plus nanoseconds. Even though a 64-bit zend_long could count seconds far beyond any realistic duration, $seconds is deliberately capped at 9_223_372_035, so that the whole duration can still be expressed as a single count of nanoseconds without overflowing a 64-bit integer (roughly PHP_INT_MAX divided by one billion). That works out to about 292 years.
Passing a larger number of seconds to Duration::fromSeconds() (or the constructor) throws a Time\TimeException, instead of silently producing a value that could overflow later.
Example
<?php
use Time\Duration;
$duration = Duration::fromSeconds(9_223_372_036);
?>
Literal Examples
- The maximum representable range is 9_223_372_035 seconds (roughly 292 years)
Alternatives
- Keep durations within 9_223_372_035 seconds (about 292 years).
- For spans of time longer than that, model them with something other than Duration, such as separate DateTimeImmutable endpoints.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The modifiers of the trait method %s() are changed, but this method does not exist. Error
Description
Inside the use block of a class, a conflict-resolution rule can change the visibility of a trait method without renaming it, by writing method as visibility; – with no trait name before the method, and no new name after the modifier.
Here, bar is not qualified with a trait name, so PHP looks for a method called bar in every trait used by the class. Since none of them declares it, and the rule does not introduce an alias (there is no new name after protected), PHP reports that the modifiers of a non-existent method were changed, rather than reporting a missing alias target.
Example
<?php
trait A {
public function foo() {}
}
class C {
use A {
bar as protected;
}
}
?>
Literal Examples
- The modifiers of the trait method bar() are changed, but this method does not exist. Error
Alternatives
- Fix the typo in the method name so it matches an existing method of one of the used traits.
- Remove the rule if changing the visibility of that method is no longer needed.
Related error messages
- an-alias-was-defined-for-method-%s(),-which-exists-in-both-%s-and-%s.-use-%s::%s-or-%s::%s-to-resolve-the-ambiguity
- a-precedence-rule-was-defined-for-%s::%s-but-this-method-does-not-exist
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The MT_RAND_PHP variant of Mt19937 is deprecated
Description
Random\Engine\Mt19937 (and the legacy mt_srand()/mt_rand() functions) support two variants of the Mersenne Twister algorithm, selected via the $mode argument: MT_RAND_MT19937, the correct, standard implementation, and MT_RAND_PHP, a non-standard variant kept only for backward compatibility with PHP’s own mt_rand() behaviour prior to PHP 7.1. MT_RAND_PHP uses a biased scaling algorithm and, before PHP 8.2, exhibited undefined behaviour for some seed values.
As of PHP 8.3, constructing an engine (or seeding the legacy PRNG) with MT_RAND_PHP emits this deprecation notice; the special-cased, non-standard variant exists purely to reproduce historical output and should not be used in new code.
Example
<?php
// MT_RAND_PHP selects PHP's own historical, biased reimplementation
// of the Mersenne Twister instead of the correct, standard one.
$engine = new Random\Engine\Mt19937(1234, MT_RAND_PHP);
$randomizer = new Random\Randomizer($engine);
var_dump($randomizer->getInt(0, 100));
?>
Alternatives
- Use MT_RAND_MT19937 (or simply omit the $mode argument, since it is the default) to get the correct, standard Mersenne Twister implementation.
- For new code, prefer a modern engine such as Random\Engine\Secure via the Random\Randomizer API instead of seeding Mt19937 manually.
- Only keep MT_RAND_PHP where reproducing PHP’s historical, legacy random sequence bit-for-bit is an explicit requirement.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The parent constructor was not called: the object is in an invalid state
Description
When extending certain PHP native classes, the child class must call the parent constructor to finish the instantiation of the object.
The problem is not detected at instantiation time, but later, as soon as any of the parent resources are used, but found to be in invalid state.
PHP does not automatically call the parent constructor when creating a child instance. It must be explicit in the code.
Some classes that needs such initialisation are: SplFileObject, SplDirectory, GlobIterator. The list is not exhaustive.
Example
<?php
// PHP bug 8318
class Bug8318 extends \SplFileObject
{
public function __construct()
{
}
public function fpassthru(): int
{
return 0;
}
}
$cl = new Bug8318;
try {
$cl->fpassthru();
} catch (\Error $e) {
var_dump($e);
}
?>
Alternatives
- Call the parent constructor.
- Use another parent class.
The PDO extension must be loaded first in order to load PDO drivers
Description
Driver extensions such as pdo_mysql, pdo_sqlite or pdo_pgsql are separate shared extensions from the core pdo extension: at startup, each of them registers itself with the core PDO extension so that it can be looked up later by PDO::getAvailableDrivers() and by the new PDO("driver:...") DSN syntax.
That registration only works if the core pdo extension has already finished loading and initializing by the time the driver extension’s own module init runs. If pdo was never loaded at all, for instance because it was built as a shared extension and its extension=pdo line is missing, commented out, or ordered after the driver in php.ini on a setup old enough not to resolve this automatically, PHP fails to start with this fatal error the moment it tries to register the driver.
Example
; php.ini, with the pdo shared extension missing or disabled,
; while a PDO driver extension is still enabled
;extension=pdo
extension=pdo_sqlite
Literal Examples
- The PDO extension must be loaded first in order to load PDO drivers
Alternatives
- Make sure extension=pdo (or a statically-built pdo) is enabled; most current PHP builds compile pdo statically or resolve module dependencies automatically, so this is mostly seen on custom or older builds.
- If php.ini lists extensions manually, make sure pdo is loaded before any pdo_* driver extension.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The PDO::FETCH_SERIALIZE mode is deprecated
Description
Combined with PDO::FETCH_CLASS, the PDO::FETCH_SERIALIZE flag was meant to fetch a row by unserialize()-ing one of its columns into an instance of the target class, relying on that class implementing the Serializable interface. Beyond depending on Serializable – which is itself being phased out in favour of __serialize()/__unserialize() – the flag has a long-standing implementation bug that makes it not actually usable as documented.
As of PHP 8.1, setting or using this fetch mode emits this deprecation notice, ahead of its planned removal in PHP 9.0.
Example
<?php
$pdo = new PDO('sqlite::memory:');
$pdo->exec('CREATE TABLE t (x TEXT)');
$stmt = $pdo->query('SELECT x FROM t');
// Combined with FETCH_CLASS, this flag was meant to automatically
// unserialize() the raw column into the target class.
$stmt->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_SERIALIZE, 'stdClass');
?>
Literal Examples
- PDOStatement::setFetchMode(): The PDO::FETCH_SERIALIZE mode is deprecated
- PDOStatement::fetch(): The PDO::FETCH_SERIALIZE mode is deprecated
Alternatives
- Fetch the raw column value with a plain fetch mode, then call unserialize() on it explicitly and assign the result where needed.
- Store structured data as JSON instead of a serialized PHP value, and decode it with json_decode() after fetching.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The predefined locally scoped $http_response_header variable is deprecated, call http_get_last_response_headers() instead
Description
The PHP variable $http_response_header is automagically created after a call to a remote resource. It contains the returned headers, for further analysis. This variable is deprecated since PHP 8.5, and will disappear in PHP 9.0. It should be replaced with a call to http_get_last_response_headers().
Example
<?php
file_get_contents(https://www.php.net/);
var_dump($http_response_header); // variable is populated in the local scope
?>
Alternatives
- Call
http_get_last_response_headers()instead of relying on the variable.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See http_response_header
The return value of function %s() should either be used or intentionally ignored by casting it as (void)%S code
Description
.
Example
<?php
#[NoDiscard]
function foo() {
return 1;
}
foo();
?>
Literal Examples
- The return value of function foo() should either be used or intentionally ignored by casting it as (void)
Alternatives
- Add the
(void)cast to the function call, so as to ignore the returned value. - Store the result of the function call in a variable and use it.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The return value of function %s() should either be used or intentionally ignored by casting it as (void)%S
Description
When a function has the NoDiscard attribute, it means that its returned value must be collected and used. When the value is simply ignored, PHP stops execution with a fatal error.
Example
<?php
#[\NoDiscard]
function foo() {
return 1;
}
foo();
?>
Alternatives
- Store the returned value in a variable, and use it to check the returned value.
- Use the function call as an argument of another function.
- Use the
(void)cast, to explicitly ignore the result.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The return value of method %s::%s() should either be used or intentionally ignored by casting it as (void)%S
Description
When a method has the NoDiscard attribute, it means that its returned value must be collected and used. When the value is simply ignored, PHP stops execution with a fatal error.
Example
<?php
#[\NoDiscard]
function foo() {
return 1;
}
foo();
?>
Alternatives
- Store the returned value in a variable, and use it to check the returned value.
- Use the function call as an argument of another method.
- Use the
(void)cast, to explicitly ignore the result.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The specified %s is malformed%s%s%s
Description
This is the detailed variant of the parsing error raised by the native URI extension, introduced in PHP 8.5, when a string handed to Uri\Rfc3986\Uri or Uri\WhatWg\Url cannot be parsed as a valid URI/URL. In addition to naming what was being parsed (URI or URL), the extra placeholders append the detailed diagnostic produced by the underlying parser, such as the specific validation error and, when possible, a pointer to the offending part of the string.
Example
<?php
use Uri\Rfc3986\Uri;
try {
$uri = new Uri('https:// example.com');
} catch (\Uri\InvalidUriException $e) {
echo $e->getMessage();
}
?>
Alternatives
- Fix the malformed component reported in the exception message before constructing the URI.
- Validate or normalize untrusted input before passing it to the
Uriclasses. - Call
Uri\InvalidUriException::getErrors()to inspect the individual validation errors programmatically.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The specified %s is malformed
Description
The native URI extension, introduced in PHP 8.5, throws this exception when the string passed to Uri\Rfc3986\Uri or Uri\WhatWg\Url cannot be parsed as a valid URI/URL at all, and no further diagnostic detail is available to attach to the message. %s names what was being parsed (URI for the RFC 3986 parser, URL for the WHATWG parser).
Example
<?php
use Uri\Rfc3986\Uri;
try {
$uri = new Uri('not a valid uri');
} catch (\Uri\InvalidUriException $e) {
echo $e->getMessage();
}
?>
Literal Examples
- The specified URI is malformed
- The specified URL is malformed
Alternatives
- Check the input string against the expected URI/URL syntax before parsing it.
- Wrap the constructor call in a try/catch block and report or discard invalid input gracefully.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The specified scheme is malformed
Description
A URI scheme must be a non-empty string starting with a letter, followed only by letters, digits, +, - or . (RFC 3986, section 3.1). Uri\Rfc3986\Uri::withScheme() and Uri\Rfc3986\UriBuilder::setScheme() validate this and throw when the value does not fit that grammar — including an empty string, as shown above.
The WHATWG-flavored Uri\WhatWg\Url::withScheme() reports the same message, though a parse failure (rather than a modification failure) additionally appends the specific WHATWG validation error in parentheses, e.g. The specified scheme is malformed (MissingSchemeNonRelativeUrl).
Example
<?php
$uri = Uri\Rfc3986\Uri::parse('https://example.com');
$uri = $uri->withScheme('');
?>
Alternatives
- Use a scheme made only of ASCII letters, digits,
+,-and., starting with a letter. - Do not pass an empty string to withScheme() / setScheme().
Related error messages
In more recent PHP versions, this error message is now :ref:failed-to-update-the-scheme.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The specified URI is malformed
Description
Uri\Rfc3986\Uri::__construct() and Uri\Rfc3986\Uri::parse() reject any input string that does not conform to the RFC 3986 URI grammar as a whole — as opposed to a failure on a single component such as the scheme or host. An empty scheme before ://, as above, is one such case, but any structurally invalid URI string triggers it.
The WHATWG-flavored Uri\WhatWg\Url (used via Uri\WhatWg\Url::parse() or its constructor) throws Uri\WhatWg\InvalidUrlException with the same base message, but appends the specific WHATWG validation failure in parentheses, e.g. The specified URI is malformed (HostMissing), and exposes the full list of validation errors through the exception’s errors property.
Example
<?php
new Uri\Rfc3986\Uri('://example.com');
?>
Alternatives
- Validate or normalize the URI string before parsing it, or wrap the parse call in a try/catch.
- When using the WHATWG parser, inspect the exception’s
errorsproperty for the precise reason.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The specified URL cannot have password
Description
The WHATWG URL Standard, implemented by the Uri\WhatWg\Url class introduced in PHP 8.5, forbids credentials and a port on file: URLs: a local file path has no notion of an authenticated remote host. Calling withPassword() on a URL whose scheme is file therefore throws instead of silently producing an invalid URL.
Example
<?php
use Uri\WhatWg\Url;
$url = new Url('file:///path/to/file');
$url = $url->withPassword('secret');
?>
Alternatives
- Do not set a password on a
file:URL. - Use a scheme that supports userinfo components, such as
ftporhttps, if credentials are actually needed.
Related error messages
In previous PHP versions, this error message used to be :ref:the-specified-url-cannot-have-username.
In more recent PHP versions, this error message is now :ref:the-specified-url-cannot-have-port.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The specified URL cannot have port
Description
The WHATWG URL Standard, implemented by the Uri\WhatWg\Url class introduced in PHP 8.5, forbids credentials and a port on file: URLs: a local file path has no notion of a remote network endpoint. Calling withPort() on a URL whose scheme is file therefore throws instead of silently producing an invalid URL.
Example
<?php
use Uri\WhatWg\Url;
$url = new Url('file:///path/to/file');
$url = $url->withPort(8080);
?>
Alternatives
- Do not set a port on a
file:URL. - Use a scheme that supports a port component, such as
httporftp, if a network endpoint is actually needed.
Related error messages
In previous PHP versions, this error message used to be :ref:the-specified-url-cannot-have-password.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The specified URL cannot have username
Description
The WHATWG URL Standard, implemented by the Uri\WhatWg\Url class introduced in PHP 8.5, forbids credentials and a port on file: URLs: a local file path has no notion of an authenticated remote host. Calling withUsername() on a URL whose scheme is file therefore throws instead of silently producing an invalid URL.
Example
<?php
use Uri\WhatWg\Url;
$url = new Url('file:///path/to/file');
$url = $url->withUsername('root');
?>
Alternatives
- Do not set a username on a
file:URL. - Use a scheme that supports userinfo components, such as
ftporhttps, if credentials are actually needed.
Related error messages
In more recent PHP versions, this error message is now :ref:the-specified-url-cannot-have-password.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The specified userinfo is malformed
Description
The userinfo component of a URI may only contain unreserved characters, the sub-delimiters, :, and percent-encoded octets (RFC 3986, section 3.2.1). Uri\Rfc3986\Uri::withUserInfo() and Uri\Rfc3986\UriBuilder::setUserInfo() throw when the given string contains a character outside that set — here, the unencoded /.
Example
<?php
$uri = Uri\Rfc3986\Uri::parse('https://example.com');
$uri = $uri->withUserInfo('us/r:password');
?>
Alternatives
- Percent-encode any reserved or non-ASCII character before passing it as userinfo.
- Restrict userinfo to unreserved characters, sub-delimiters and
:.
Related error messages
In previous PHP versions, this error message used to be :ref:cannot-set-a-userinfo-without-having-a-host.
In more recent PHP versions, this error message is now :ref:failed-to-update-the-userinfo.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The SQLite3 object has not been correctly initialised or is already closed
Description
There was an attempt to use the Sqlite3 database, while it is not yet initialised, or already closed.
When extending the Sqlite3 class, make sure the constructor calls the parent constructor, so that Sqlite3 is actually initiliazed.
Note that the Sqlite3 object was not unset yet, so it still exists. It would have been another error then.
Example
<?php
// Not yet initialized object
$sqlite3 = new class (':memory:') extends Sqlite3 {
function __construct() {}
};
$sqlite3->query('SELECT 1'); // OK
// already closed object
$sqlite3 = new Sqlite3(':memory:');
$sqlite3->query('SELECT 1'); // OK
$sqlite3->close();
$sqlite3->query('SELECT 1'); // Not OK
?>
Alternatives
- Check that the parent class of an extended Sqlite3 class is actually called.
- Check that the parent class was not already destroyed.
- Check that whole object is destroyed, not just the parent class.
Related error messages
- call-to-a-member-function-%s()-on-%s
- %s():-return-value-of-the-authorizer-callback-must-be-of-type-int,-%s-returned
- %s():-return-value-of-the-collation-callback-must-be-of-type-int,-%s-returned
- cannot-directly-construct-directory,-use-dir()-instead
- datetimezone-object-is-unconstructed
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
The use statement with non-compound name '%s' has no effect
Description
This warning reports a useless use expression. The use expression imports the final name of a fully qualified name to be used in the current file. When applying use to a simple name, without any \ separator, PHP does not import it, as it is already treated as such by default.
Example
<?php
use Some\Space\Functions; // allow Functions to be used in this file
use Closure; // Closure is already handled that way, no need to import it
function foo(Closure $closure) {}
?>
Alternatives
- Remove the single name use expressions.
- Fix the imported name to include a namespace, if applicable.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Too few arguments to function %s%s%s(), %d passed and %s %d expected
Description
This error reports that not enough parameters were used when calling a method or a function. All the arguments in the method signature are compulsory.
While there is an error message when there are missing arguments at call time, there is not error when too many arguments are provided.
Example
<?php
function foo($a, $b) {}
foo(1);
?>
Literal Examples
- Too few arguments to function foo(), 1 passed and exactly 2 expected
Alternatives
- Provide more arguments to the method call.
- Add default values to the missing parameters in the method signature.
Related error messages
Too few arguments to function %s%s%s(), %d passed and %s %d
Description
This error reports that not enough parameters were used when calling a method or a function. A number of the arguments in the method signature are compulsory and at least that many argument must be provided.
Although parameters with default values should be all in the tail of the signature, it is still a valid, yet deprecated, feature. Then, using positional arguments, the code might yield this error as some of the positional arguments might fill some default parameters, leaving unsatisfied parameters later in the list.
While there is an error message when there are missing arguments at call time, there is not error when too many arguments are provided.
Example
<?php
function foo($a, $b, $c = 2) {}
foo(1);
// deprecated features: $c should be before $b, or get a default value, or $b might have no default value.
function bar($a, $b = 1, $c) {}
bar(1,2);
// Here, $c is not provided,
?>
Literal Examples
- Too few arguments to function foo(), 1 passed and exactly 2 expected
Alternatives
- Use named parameters to assign arguments to the compulsory arguments.
- Provide more arguments to the method call.
- Add default values to the missing parameters in the method signature.
Related error messages
- too-few-arguments-to-function-%s%s%s(),-%d-passed-in-%s-on-line-%d-and-%s-%d-expected
- too-few-arguments-to-function-%s%s%s(),-%d-passed-and-%s-%d-expected
Too few arguments to function %s%s%s(), %d passed in %s on line %d and %s %d expected
Description
This error is emitted when the number of arguments to call a method or a function is not enough.
Without the required number of arguments at function call, the function cannot execute, as some variables would be missing.
This error covers situations where all the arguments are compulsory.
Example
<?php
function foo($a, $b) {}
foo(1);
?>
Literal Examples
- Too few arguments to function foo(), 1 passed in file.php on line 5 and exactly 2 expected
Alternatives
- Add the missing arguments.
- Add default values to the missing arguments.
Related error messages
Too few arguments
Description
Functions such as printf() require at least one argument, the format. In that argument, the function will identify and require more arguments, passed after this first one. When there is not enough arguments for the first one, this error appears.
Not that extra arguments are ignored silently by PHP.
This applies to printf(), sprintf(), fprintf().
Example
<?php
printf('%s %s', 1);
?>
Literal Examples
- printf(): Too few arguments
Alternatives
- Check that the format (first argument), has only the required placeholders
%s,%i… - Check that the
printf()has enough arguments to match the format.
In more recent PHP versions, this error message is now :ref:%d-arguments-are-required,-%d.
Trait “%s” not found
Description
This error appears when a trait is mentioned in the conflict resolution expression, but the trait is not part of the class.
PHP takes into consideration all the traits, even if they are added later than the conflict class.
Example
<?php
class X {
// C is not a used trait
use A, B { C::d insteadof E;}
// E is a used trait, even if is not in the use above.
use E;
}
?>
Literal Examples
- Trait “E” not found
Alternatives
- Add the missing trait.
- Remove the missing trait and its conflict resolution.
Trait %s used by %s is deprecated%S
Description
PHP 8.4 introduced the #[\Deprecated] attribute to flag functions, methods and class constants as deprecated. PHP 8.5 extends this to traits: a trait declared with #[\Deprecated] emits this deprecation notice as soon as another class use-s it, pinpointing the class doing the using.
The optional since and message arguments of the attribute are appended to the notice, for example “ since 1.0, use LoggerTrait instead“, to help locate a replacement.
Example
<?php
#[\Deprecated(message: 'use LoggerTrait instead', since: '1.0')]
trait DeprecatedLoggingTrait {
public function log(string $message): void {
echo $message, PHP_EOL;
}
}
class Service {
use DeprecatedLoggingTrait;
}
?>
Literal Examples
- Trait DeprecatedLoggingTrait used by Service is deprecated since 1.0, use LoggerTrait instead
Alternatives
- Stop using the deprecated trait and switch to the alternative mentioned in the deprecation message.
- If you own the trait, keep the
#[\Deprecated]attribute until the trait is actually removed, so callers get a clear migration path.
Related error messages
- function-%s()-is-deprecated%s
- constant-%s-is-deprecated
- constant-%s::%s-is-deprecated
- cannot-instantiate-trait-%s
Related error messages
Trait method %s::%s has not been applied as %s::%s
Description
Two methods with the same name were imported with two distinct traits: PHP could not decide which one to use.
Example
<?php
trait T {
public function foo() { return 3; }
}
trait U {
public function foo() { return 2; }
}
class Bar {
use T, U;
}
$x = new Bar();
var_dump($x->foo());
?>
Literal Examples
- Trait method U::foo has not been applied as Bar::foo, because of collision with T::foo
Alternatives
- Change the name of the method in one of the trait.
- Add aliasing when importing the traits.
- Only use one of the trait.
- Make one trait use the other one.
Related error messages
Traits cannot have constants
Description
Constants int traits were added in PHP 8.2. Until then, they were not allowed: at compile time this error was yield.
Example
<?php
trait T {
const X = 1;
}
echo T::X;
?>
Alternatives
- Put the constant in the host class.
- Put the constant in an interface.
- Do not use the constant.
- Move to PHP 8.2 or later.
Related error messages
In more recent PHP versions, this error message is now :ref:cannot-access-trait-constant-%s::%s-directly.
Trying to access array offset on %s
Description
Null, boolean (true and false), integers and floats are not valid with the array syntax. That syntax uses the square brackets with an index, appended after the value.
Often, such syntax is used on returned values, which may be an array, or false (or null) in case of error: most of the time it is a valid array, but sometimes, it is a scalar type. Such usage is now reported since PHP 8.3.
Example
<?php
echo null[1];
//Warning: Trying to access array offset on null
$true = true;
echo $true['a'];
//Warning: Trying to access array offset on true
$true = false;
echo $true[[33]]; // also, invalid idnex
//Warning: Trying to access array offset on false
?>
Literal Examples
- Trying to access array offset on true
- Trying to access array offset on false
- Trying to access array offset on null
Alternatives
- Check for types before using an array syntax on a returned value.
- Initialize variables with an array, whenever it will be used with this type later.
Related error messages
Trying to clone an uncloneable object of class %s
Description
It is not possible to instantiate certain classes. This is the case of enumerations and generators.
It is also not possible to clone an enumeration cases, which are actually of the same type as the enumeration itself. The only usage is to access the cases of the enumeration: they are directly the expected objects.
On the other hand, it is possible to clone a closure.
Example
<?php
enum E {
case A;
}
clone E::A;
$g = function () { yield 1; };
clone $g;
$c = function () { return 1; };
clone $c;
?>
Literal Examples
- Trying to clone an uncloneable object of class e
Alternatives
- Use the case
E::A. Make sure it is not a class constant, which might be cloned. - For generator, call the original variable anytime the code needs a new source for a loop.
Trying to invoke %s method %s::%s() from scope %s
Description
This error reports that the requested method exists, but is not available from the context of call. Here, the method is protected and should only be called from a child class of x.
There are distinct messages for calling an unknown method, or calling a private method.
Example
<?php
class X {
protected function foo() {}
}
class Y {
function g() {
$x = new X;
$x->foo();
}
}
(new Y)->g();
?>
Alternatives
- Check the name of the method for typo.
- Check the object of the method is the correct one.
Related error messages
Type %c: unknown format code
Description
pack() and unpack() convert data between a string representation and another. They both use a format string, passed as first argument, that specifies how the data of the second argument are transformed. This format string uses a limited set of letters (and @) to express these transformation. Any other character is not recognized and produces this error.
The valid characters are : a, A, h, H, c, C, s, S, n, v, i, I, l, L, N, V, q, Q, J, P, f, g, G, d, e, E, x, X, Z, @
The format is checked after collecting the parameters, and before attempting the transformation.
Example
<?php
$array = unpack("z", $someData);
?>
Literal Examples
- Type z: unknown format code
Alternatives
- Remove the unknown characters.
- Fix the unknown character with a valid one.
Related error messages
Type %s cannot be part of an intersection type
Description
An intersection type, like string&Iterator, requires a value to be an instance of every listed type at once. That is only meaningful for class and interface names: a value can implement several interfaces simultaneously.
Scalar and compound pseudo-types (int, float, string, bool, array, callable, iterable, mixed, void, never, null, false, true), as well as self, parent and static, cannot be combined into an intersection, since nothing can be, for instance, a string and an object implementing Iterator at the same time.
Example
<?php
function foo(): string&Iterator {}
?>
Literal Examples
- Type string cannot be part of an intersection type
Alternatives
- Remove the scalar or pseudo-type from the intersection, and keep only class or interface names.
- Use a union type (
|) instead, if any of the alternatives is acceptable.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Type %s contains both iterable and array, which is redundant
Description
Since PHP 8.0 and the advent of union types, it is possible to write a type with duplicate type in it. This is obviously the case of the second function, in example.
It is less obvious to spot that array and iterable are redundant, yet, iterable = array|Traversable. So, iterable is sufficient, to also cover array.
This is a specific case of the general error that target any duplicate type in a definition.
Example
<?php
function foo() : array|iterable { }
function goo() : array|array { }
?>
Literal Examples
- Type iterable|array contains both iterable and array, which is redundant
Alternatives
- Remove the
arraytype, and only useiterablefor both. - Remove the
iterabletype, and only usearrayfor this type.
Related error messages
Related error messages
In more recent PHP versions, this error message is now :ref:duplicate-type-%s-is-redundant.
Type %s contains both object and a class type
Description
The object type already matches an instance of any class. Adding a specific class name next to it in a union type, such as object|Test, does not widen what is accepted: every value that matches Test already matches object. PHP detects this redundancy purely from the type names, without needing Test to be defined or loaded.
The full message reads: Type %s contains both object and a class type, which is redundant.
Example
<?php
function test(): object|Test {
}
?>
Literal Examples
- Type Test|object contains both object and a class type, which is redundant
Alternatives
- Remove the specific class name, and keep only
object. - Remove
object, and keep only the specific class name, if that narrower type is what is actually intended.
Related error messages
- type-%s-contains-both-iterable-and-array
- type-contains-both-true-and-false,-bool-must-be-used-instead
- duplicate-type-%s-is-redundant
- type-%s-cannot-be-part-of-an-intersection-type
- type-%s-is-redundant-as-it-is-more-restrictive-than-type-%s
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Type %s is redundant as it is more restrictive than type %s
Description
DNF (Disjunctive Normal Form) types, added in PHP 8.2, allow an intersection group to be combined inside a union, as in (A&B)|C. If one of the union’s plain members already appears on its own, here A, then any intersection group built from that same name, such as A&B, cannot accept any value beyond what A alone already accepts: satisfying A&B always implies satisfying A.
PHP detects this purely by comparing the type names in the declaration, without loading any class, and rejects the more restrictive branch as dead code.
Example
<?php
interface A {}
interface B {}
function test(): (A&B)|A {}
?>
Literal Examples
- Type A&B is redundant as it is more restrictive than type A
Alternatives
- Remove the redundant intersection group, and keep only the broader standalone type.
- If the intersection group was meant to be independent, use a type that is not already implied by one of the union’s other members.
Related error messages
- type-%s-is-redundant-with-type-%s
- duplicate-type-%s-is-redundant
- type-%s-contains-both-object-and-a-class-type
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Type %s is redundant with type %s
Description
In a DNF (Disjunctive Normal Form) type, two intersection groups can look textually different while describing the exact same combination of types once names are resolved. Here, B is only a local alias for A (introduced by use A as B;), so X&A and X&B are, in fact, the very same intersection written twice.
PHP resolves use aliases at compile time, notices that the second group adds nothing over the first, and reports it as redundant.
Example
<?php
interface X {}
use A as B;
function foo(): (X&A)|(X&B) {}
?>
Literal Examples
- Type X&A is redundant with type X&A
Alternatives
- Remove the duplicated intersection group.
- Use the class’s real name consistently, instead of mixing the name and its alias.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Type contains both true and false, bool must be used instead
Description
PHP has several types. They may combined to provide the same type safety one another: PHP reports those situations, and prevents them.
Here, the bool type represents true|false. So, when both true and false are used in the type, they should be replaced with bool.
bool|true or bool|false yields another error; bool&true is not possible, at all.
Example
<?php
function foo() : int|true|false {}
?>
Alternatives
- Use the bool type instead.
- Remove the usage of either true or false, or both.
Related error messages
- duplicate-type-%s-is-redundant
- null-cannot-be-marked-as-nullable
- type-%s-contains-both-object-and-a-class-type
Type declaration ‘%s’ must be unqualified
Description
Scalar types are absolute, and shall not be written with the initial \. It is always omitted.
This error is reported for string, int, bool, iterable, never, void, object, float, null, mixed, true, false.
For some reason, array and callable are still not reported with this error. resource is also ignored, although it is only reserved, and not supported anyway.
Example
<?php
function foo(\string $x) {}
?>
Literal Examples
- Type declaration ‘array’ must be unqualified
- Type declaration ‘string’ must be unqualified
- Type declaration ‘int’ must be unqualified
- Type declaration ‘null’ must be unqualified
Alternatives
- Remove the leading backslash.
- Remove the whole type.
- Use a class type, which supports the leading backslash.
Related error messages
- is-an-invalid-class-name
- ‘-%s’-is-an-invalid-class-name
- cannot-use–“%s-”-as-%s-as-it-is-reserved
- cannot-use-“%s”-as-a-type-name-as-it-is-reserved
Type mixed can only be used as a standalone type
Description
mixed is a special type, that represents all the available types. There is no need to combine this type in an union, as all the types are already compiled in mixed; Nor it can be combined in an intersectional type.
Example
<?php
function foo(A|mixed $i = null) {}
?>
Alternatives
- Remove the mixed type and use other types.
- Remove the mixed type entirely.
Related error messages
- type-mixed-cannot-be-marked-as-nullable-since-mixed-already-includes-null
- never-can-only-be-used-as-a-standalone-type
- void-can-only-be-used-as-a-standalone-type
Type mixed cannot be marked as nullable since mixed already includes null
Description
mixed is a special type, that represents all the available types, include null.
Example
<?php
function foo(?mixed $i = null) {}
?>
Alternatives
- Remove the
?type with mixed. - Keep the
?type, and replacemixed, with some other type.
Related error messages
Type must be a single character
Description
The type argument of the snmp2_set() function is a list of types: one or more. Each type must a string of a single character, no more, no less.
The allowed values are : ‘=’, ‘i’, ‘u’, ‘s’, ‘x’, ‘d’, ‘n’, ‘o’, ‘t’, ‘a’, ‘b’, ‘U’, ‘I’, ‘F’, ‘D’.
Example
<?php
$z = snmp2_set(hostname: $hostname,
community: $communityWrite,
object_id: array($oid1, $oid2),
type: array('s','sb'),
value: array($newvalue1, $newvalue2),
);
?>
Alternatives
- Remove any invalid type.
- Remove types that are more than one character.
- Remove types that are less than one character.
Type of %s::$%s must be %s%s (as in class %s)
Description
Property definitions must be compatible one another, between a parent and a child class. With this error message, the parent class defined a type for the property, and so, the child class should also define it. On the other hand, it may change the default value.
Example
<?php
class X {
public $a;
}
class Y extends X {
public array $a;
}
?>
Literal Examples
- Type of X::$a must be array (as in class Y)
Alternatives
- Use the type to the child class in the parent, and the sibling classes.
- Use the type of the parent class.
Related error messages
- type-of-%s::$%s-must-not-be-defined-(as-in-class-%s)
- set-type-of-%s::$%s-must-be-supertype-of-%s-(as-in-%s-%s)
- type-of-%s::%s-must-be-compatible-with-%s::%s-of-type-%s
Type of %s::$%s must be omitted to match the parent definition in class %s
Description
A property cannot be redefined, by adding the mixed type to it. It looks like untyped property and mixed type property should behave the same, but they are not: in particular, typed properties have an ‘uninitialized’ state, which yields fatal errors when the property is read, which does not apply to untyped properties.
Example
<?php
class Foo
{
public $property;
}
class Bar extends Foo
{
public mixed $property;
}
?>
Literal Examples
- Type of X::$p must be omitted to match the parent definition in class X
Alternatives
- Add the
mixedtype to the parent property definition. - Remove the
mixedtype from the child property definition.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Type of %s::$%s must not be defined (as in class %s)
Description
Property definitions must be compatible one another, between a parent and a child class. With this error message, the parent class did not define a type for the property, and so, the child class should also not define it. On the other hand, it may change the default value.
Example
<?php
class X {
public $a;
}
class Y extends X {
public array $a;
}
?>
Literal Examples
- Type of Y::$a must not be defined (as in class X)
Alternatives
- Add the type to the parent class, and the sibling classes.
- Remove the type in the child class.
Related error messages
Type of %s::%s must be compatible with %s::%s of type %s
Description
PHP 8.3 introduced typed class constants: a class constant may declare the type of value it holds, and that type is enforced. When a class overrides a typed constant inherited from a parent class or an implemented interface, the overriding constant’s type must be covariant with the parent’s, meaning it must be the same type, or a subtype of it, never a wider or unrelated one.
Here, Colorful::COLOR is typed string, but Item redeclares it as int, which is not a subtype of string. Since callers relying on Colorful::COLOR expect a string, PHP rejects the mismatch at compile time.
Example
<?php
interface Colorful {
const string COLOR = 'unknown';
}
class Item implements Colorful {
const int COLOR = 1;
}
?>
Literal Examples
- Type of Item::COLOR must be compatible with Colorful::COLOR of type string
Alternatives
- Use the same type as the parent constant, or a subtype of it.
- Remove the type declaration from the child constant’s declaration, if the language version allows omitting it.
- Rename the constant, if it is not meant to override the parent one.
Related error messages
- declaration-of-%s::%s()-must-be-compatible-with-%s::%s()
- type-of-%s::$%s-must-be-%s%s-(as-in-class-%s)
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Type of parameter $%s of hook %s::$%s::set must be compatible with property type
Description
When a set hook declares an explicit parameter type, that type is what callers of $object->prop = $value are constrained to. Because the hook is the only way to write to the property, its parameter type must be able to accept every value that the property’s own declared type allows; it must be the same as, or wider (contravariant) than, the property type, never narrower.
In the example, $prop is declared as string|array, but the set hook only accepts string. An assignment of an array would satisfy the property’s declared type but be rejected by the hook’s parameter type, which PHP considers an incompatible, and therefore invalid, declaration.
The same error occurs when the property itself has no explicit type (implicitly mixed) but the set hook restricts its parameter to a specific type, since mixed is wider than any concrete type.
Example
<?php
class Test {
public string|array $prop {
set(string $prop) {}
}
}
?>
Literal Examples
- Type of parameter $prop of hook Test::$prop::set must be compatible with property type
Alternatives
- Widen the
sethook’s parameter type so that it accepts everything the property’s declared type allows, e.g. changeset(string $prop)toset(string|array $prop). - Remove the explicit type from the
sethook’s parameter, letting it default to the property’s type. - Narrow the property’s declared type to match what the
sethook is willing to accept.
Related error messages
- set-type-of-%s::$%s-must-be-supertype-of-%s-(as-in-%s-%s)
- get-hook-of-property-%s::$%s-must-not-have-a-parameter-list
- get-hook-of-backed-property-%s::%s-with-set-hook-may-not-return-by-reference
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Typed property %pS::$%pS must not be accessed before initialization
Description
Typed properties are undefined until they are assigned for the first time, either through a default value or by an explicit assignment. This differs from untyped properties, where reading before assignment simply yields NULL: because a typed property must always hold a value matching its declared type, and NULL is not a valid value unless the type is nullable, PHP raises an error instead of inventing one.
The coalesce ??, isset() and empty() operators can be used to check whether the property has been initialized, even though it is not set. Be careful not to confuse an uninitialized property with one that is merely empty.
Example
<?php
class X {
public int $property;
}
$x = new X;
echo $x->property;
?>
Literal Examples
- Typed property X::$property must not be accessed before initialization
Alternatives
- Give the property a default value.
- Avoid calling unset() on typed properties, as it resets them to the uninitialized state.
- Assign the property in the constructor.
- Use isset(), empty() or ?? to check the property’s status before reading it.
Related error messages
- typed-property-%s::$%s-must-not-be-accessed-before-initialization
- attempt-to-unset-static-property-%s::$%s
- object-not-initialized
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Typed property %s::$%s must not be accessed before initialization
Description
Typed properties are undefined until they are assigned for the first time. Such happens with a default value, or at the first assignation.
The difference with untyped values, is that PHP emits that error when the property is not typed. On the other hand, an undefined property gets a NULL value instead.
The coalesce ??, isset() and empty() operators may be used to check if the property exists, even when it is not defined. Be careful to avoid confusing an undefined property and its empty equivalent.
Example
<?php
class X {
public int $property;
}
$x = new X;
echo $x->p;
?>
Literal Examples
- Typed property x::$p must not be accessed before initialization
Alternatives
- Give a default value to the property.
- Remove usage of unset() on properties, as they are then reset to uninitialized state.
- Set the value of the property in the constructor.
- Use isset(), empty() or ?? to check the status of the property before usage.
Related error messages
- attempt-to-unset-static-property-%s::$%s
- object-not-initialized
- typed-static-property-%s::$%s-must-not-be-accessed-before-initialization
- default-value-for-property-of-type-%s-may-not-be-null.-use-the-nullable-type-%s-to-allow-null-default-value
Related error messages
Typed static property %s::$%s must not be accessed before initialization
Description
Typed static properties are undefined until they are assigned for the first time. Such happens with a default value, or at the first assignation.
The difference with untyped values, is that PHP emits that error when the property is not typed. On the other hand, an undefined property gets a NULL value instead.
The coalesce ??, isset() and empty() operators may be used to check if the property exists, even when it is not defined. Be careful to avoid confusing an undefined property and its empty equivalent.
Example
<?php
class X {
public static int $property;
}
echo x::$property;
?>
Literal Examples
- Typed static property x::$p must not be accessed before initialization
Alternatives
- Give a default value to the property.
- Set the value of the property in the constructor.
- Use isset(), empty() or ?? to check the status of the property before usage.
Related error messages
- attempt-to-unset-static-property-%s::$%s
- typed-property-%s::$%s-must-not-be-accessed-before-initialization
Related error messages
Unable to generate salt
Description
password_hash() creates a random salt for each hash, using random bytes from the operating system. If those bytes cannot be read, no salt can be made, so no hash is produced and this error is thrown.
This is an environment problem rather than a problem in the code that calls password_hash(). It is rare, and it is usually reported on systems where the random source is not available to PHP, or where entropy is missing, such as some containers and virtual machines.
Example
Literal Examples
- Unable to generate salt
Alternatives
- Check that
random_bytes()works on the system, for example by callingrandom_bytes(16)in a small script. - Check the random source of the operating system and of the container or virtual machine, and make sure PHP can read from it.
- Check the PHP build and its extensions, as a broken build can also lead to this error.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Unbacked enum %s cannot be converted to a string
Description
http_build_query() function convert an array of strings to their URL encoded version. When encountering an enumeration, it makes it work with string and integer enumerations, but not with the unbacked enumerations.
Example
<?php
enum E {
case A;
}
try {
echo http_build_query(['e' => E::A]);
} catch (ValueError $e) {
echo $e->getMessage(), \n;
}
?>
Alternatives
- Add a type to the enumeration,
stringorint. Then, add values to the cases. - Convert the enumeration cases into strings before using them with http_build_query().
Related error messages
Unclosed '(' does not match ']'
Description
This is a variation of the unbalanced parenthesis or square brackets. Here, the parenthesis were not closed before the nesting square brackets was closed.
Example
<?php
$array[foo(1,2];
?>
Alternatives
- Close the parenthesis before closing the square bracket.
Related error messages
- [unmatched-‘]’](unmatched-].html)
- unmatched-‘}’
- unmatched-‘)’
Unclosed '(' on line %s does not match ']'
Description
PHP keeps track of parenthesiss and square brackets. Any of them that is opened, must be closed by the corresponding one. In the current situation, an open parenthesiss is followed by a closing square bracket, which does not match.
Example
<?php
$array = [foo(1, 2];
?>
Literal Examples
- Unclosed ‘(’ on line 17 does not match ‘]’
Alternatives
- Close the parenthesis before the closing square bracket.
- Open a square bracket after the opening parenthesis.
Unclosed ‘(’
Description
The closing parenthesis is missing.
It might be missing, as in the first two examples; it might also be inside a string, as in the third example: the double quote is not closed, which includes the closing square bracket, and makes it missing.
Example
<?php
// These should be at the end of a code, without ; not ?>
foo($b, 3
$a = 10 * (2 + 3
// closing parenthesis is in the double quoted string
$b = 'c' . ( "d . $e)
?>
Alternatives
- Check that the square brackets are balanced.
- Check that the closing square brackets are not hidden in a string.
Related error messages
- unclosed-‘{’
- [unclosed-’’
- unmatched-‘)’
- [unmatched-‘]’](unmatched-].html)
Unclosed ‘[’
Description
The closing square bracket is missing.
It might be missing, as in the first example; it might also be inside a string, as in the second example: the double quote is not closed, which includes the closing square bracket, and makes it missing.
Example
<?php
// This should be at the end of a code, without ; not ?>
$a[$b[3]
$a["3] = 4;
?>
Alternatives
- Check that the square brackets are balanced.
- Check that the closing square brackets are not hidden in a string.
Related error messages
Unclosed ‘{’
Description
The most frequent situation is an unbalanced block: blocks are delimited with curly brackets, and there must be the same number of opening and closing. In this case, one (at least) too many opening is missing its closing bracket.
Alternatively, both brackets are apparently available, but one of them is in a string: see the last entry, where a double-quoted string was started, but never finished. The whole code, after the double-quote, is now in a string, and PHP discarded the closing bracket as a literal, not a token.
This error may related to the PHP short tags. In the heart of the B method, the PHP tag is closed, then opened again. That second opening is using the PHP short tags. When this directive is disabled, it makes the rest of the text after the closing tag literal, and it is not parsed anymore into PHP code. Since the closing brackets are there, PHP reports they are missing.
Example
<?php
{ $a = 1+2;
class A
{
public function B()
{
?>C<?
}
}
// bracket is buried in the string
{ $b = "1+2; }
?>
Alternatives
- Make the short open tag a full
<?php. - Activate the short open tag directive
<?php. - Check that double quotes are all balanced.
- Check that curly brackets are all balanced.
Related error messages
Undefined array key
Description
This notice is emitted when an offset (string or integer) is being used before being defined. In a word, the element at this offset does not exist, so PHP creates it on the fly, as NULL, then uses it.
Example
<?php
// undefined array key 4
echo [1,2,3][4];
// undefined array key 'a'
echo [1,2,3]['a'];
// undefined array key 1
list($a, $b) = ['c'];
?>
Alternatives
- Test the existence of the offset before usage.
- Gives the offset a default value before usage.
- Check that the right operand of a list() call has enough elements to fit the left operand.
Related error messages
In previous PHP versions, this error message used to be :ref:undefined-offset.
Undefined class constant ‘%s::%s’
Description
The requested class constant doesn’t exist.
In the case of an enumeration, this error message is also displayed for the cases: they do have the same syntax, so it is not possible to know if it is a constant or a case.
Example
<?php
class X {}
echo X::Y;
enum E { case A;}
echo E::B;
?>
Literal Examples
- Undefined class constant ‘x::Y’
- Undefined class constant ‘e::B’
Alternatives
- Find the actual name of the requested class constant.
- Find the actual class of the requested class constant.
- Define the class constant in the class, or its traits, interfaces or parents.
In more recent PHP versions, this error message is now :ref:undefined-constant-%s::%s.
Undefined constant “%s”
Description
The requested constant doesn’t exist.
The constant may be defined at different places in the code :
- In the running code: it could be in a different file, which was not included yet, or later in the code.
- In a dependency: use the name of the constant to find which dependency defines this constant. Then, make sure the dependency is satisfied.
- In an extension: use the name of the constant to find which PHP extension defines this constant. For example,
XML_PI_NODEis from the ext/xml extension, which may not be in the current PHP engine.
There is a distinct message for class constants.
It is possible to create a circular definition of constant, that leads to this error message. This is the case with a direct recursive definition, where the constant is used to define itself. Since the constant is not defined yet, it cannot be used in the right expression, and that leads to an ‘undefined constant’ error.
It is also possible to build such recursive structure by using an object, and using that constant in the class of the related object.
Example
<?php
// early usage of the constant
echo A;
const A = 2;
// Recursive constant definition
const A = A + 1;
// Recursive constant definition (longer version)
class X {
const B = C;
}
const C = new X;
?>
Literal Examples
- Undefined constant “A”
- Undefined constant “XML_PI_NODE”
Alternatives
- Find the actual name of the requested constant.
- Check the namespace, or its import:
use const. - Check if the constant is used after its definition.
- Check if the constant is defined in a PHP extension, and the extension was forgotten.
- Check if the constant is defined in a dependency, and the dependency was forgotten.
Related error messages
Undefined constant %s::%s
Description
The requested class constant could not be found.
The error message is distinct for the global constants, although there is no mention of class in this one.
Example
<?php
class X {
const Z = 1;
private A = 2;
}
echo X::Y;
?>
Literal Examples
- Undefined constant X::CONSTANT
Alternatives
- Find the actual name of the requested class constant.
- Find the actual class of the requested class constant.
- Check the namespace, or its import.
- Check the visibility of the class constant: it may be private, or protected.
- Check the autoload system, to make sure the definition could be found.
- Define the class constant in the class, or its traits, interfaces or parents.
Related error messages
In previous PHP versions, this error message used to be :ref:undefined-class-constant-'%s::%s'.
Undefined global variable %s
Description
$GLOBALS is a superglobal that stores all the defined global variables. It yields this warning when trying to reach a global via one of its index.
Example
<?php
function foo() {
echo $GLOBALS['a'];
}
foo();
?>
Literal Examples
- Undefined global variable $a
- Undefined global variable $GLOBALS
Alternatives
- Create the global with the
globalkeyword before accessing it.
Undefined offset
Description
This notice is emitted when an offset (string or integer) is being used before being defined. In a word, the elemenent at this offset is not created yet, so PHP creates it on the fly, as NULL, then uses it.
Example
<?php
echo [1,2,3][4];
?>
Alternatives
- Test the existence of the offset before usage.
- Gives the offset a default value before usage.
In more recent PHP versions, this error message is now :ref:undefined-array-key.
Undefined property %s::$%s
Description
This error is reported when reading an undefined property. The property must be defined before usage, or, in older PHP versions, the property must have been assigned.
This error is related to properties: a different error is emitted for static properties.
Example
<?php
class X {
public $a = 1;
}
$x = new X;
echo $x->a;
echo $x->b;
?>
Literal Examples
- Undefined property x::$b
Alternatives
- Define the property before using it.
- Fix the name of the property, and replace it with an existing one.
- Define the magic property method __get() to make any property available.
Related error messages
- access-to-undeclared-static-property-%s::$%s
- property-%s-does-not-exist
- property-%s::$%s-does-not-exist
Undefined variable $%S
Description
This error appears when a variable is used, aka read, while it was not defined before.
This might be a variable passed by argument to a method; a variable used with a short assignation operator or an argument of the PHP native function compact.
Example
<?php
$x += 1;
foo($a);
compact('undefined');
function foo($a) {}
?>
Alternatives
- Use another variable.
- Check the variable before usage.
- Give a default value to the variable before usage.
Undefined variable
Description
This notice is emitted when a variable is being used before being defined. In a word, the variable is not created yet, so PHP creates it on the fly, as NULL, then uses it.
The situation arises when reading a variable, such as the echo call here. It doesn’t happen upon writing, as it is the way to make a variable definition.
It also happens when using the compact native function: it collects the values of variables into an array, and emits this error whenever the variable doesn’t exist. The entry is also skipped in the result.
The error may be related to a PHP defined variable, which is not available due to version or context. For example, $phperrormsg was removed in PHP 8.0, and $_GET is not available in command line context, aka, without a web server.
Example
<?php
echo $x;
compact('a');
?>
Alternatives
- Give the variable a default value.
- Check if the version supports the PHP defined variable.
- Check if the context supports the variable: web or command line.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See compactThrowsNotice
Unexpected character in input: '\’ (ASCII=92)
Description
This linting error appears at linting time, until PHP introduced namespaces, whose separator is \. Then, it was added to the recognized characters.
Example
<?php
use \A\B as C;
?>
Alternatives
- Upgrade to PHP 5.3 or later.
- Replace the backslash by an underscore.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
unexpected NAN value was coerced to %s
Description
When a NAN (Not a Number) float value is coerced to another type such as int or string, PHP emits this warning. NAN is a special float value that represents an undefined or unrepresentable result of a floating-point operation.
Coercing NAN to int produces 0, and coercing it to string produces an empty string. These results are misleading since NAN is not equivalent to zero or empty. The warning alerts developers that a NAN value is silently converted, which is almost certainly unintended.
NAN is produced by operations like acos(8), log(-1), sqrt(-1), or 0.0/0.0.
Example
<?php
// NAN coerced to int
$a = (int) NAN;
// $a = 0
// NAN coerced to string
$b = (string) NAN;
// $b = ""
// NAN passed to an integer parameter
function foo(int $x) {}
foo(NAN);
?>
Literal Examples
- unexpected NAN value was coerced to int
- unexpected NAN value was coerced to string
Alternatives
- Check for
is_nan()before coercing or passing the value to a typed parameter. - Handle
NANexplicitly at its source by validating the result of math operations. - Use
is_finite()to filter out bothNANandINFbefore using a float value.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Unhandled match case %s
Description
The error is emitted when the matching value is not found in the list of entry of the expression (here true is not in the list of 1 and 2), and also when the expression doesn’t have a default entry. That default entry would act as a catch-all entry, and would process unknown values.
Example
<?php
match(3) {
1, 2 => 'foo',
};
?>
Literal Examples
- Unhandled match case 3
Alternatives
- Add the missing entry in the list.
- Add the missing default in the match.
- Weed out the value before submitting it to the match().
Uninitialized string offset
Description
This error appears when using the array syntax on strings, while the requested index is too large, or too small.
An offset is too big when it is beyond the length of the string. An offset is too small with it is below the length of the string, multiplied by -1. All values between - strlen($string) and strlen($string) are valid.
This error is displayed when the string offset is read. It becomes a Illegal string offset when the syntax is used to write a character.
Example
<?php
$string = 'abc';
//Uninitialized string offset
echo $string[-10];
//Uninitialized string offset that is too big
echo $string[5];
?>
Literal Examples
- Uninitialized string offset 1
- Uninitialized string offset 5
- Uninitialized string offset -5
Alternatives
- Check for the size of the string before using the offset.
- Use substr(), which returns empty string for out of range offsets.
Related error messages
Unknown digest algorithm: %s
Description
The digest algorithm name passed to a hash function is not recognized by PHP’s Hash extension.
The hash(), hash_file(), and hash_hmac() functions rely on a registry of supported algorithms. When an algorithm name is not found in that registry, this warning is emitted and the function returns false.
The list of available algorithms depends on the extensions loaded at runtime. Algorithms may be added or removed depending on the PHP version and compiled extensions.
Algorithms are case-insensitive, but misspellings will still produce this error.
Example
<?php
// hash() with a valid algorithm works
hash('sha256', 'my data');
// hash() with an unknown algorithm triggers the warning
hash('unknown_algo', 'my data');
// hash_file() also triggers it
hash_file('bad_algo', '/tmp/file.txt');
// hash_hmac() too
hash_hmac('invalid', 'my data', 'secret');
?>
Literal Examples
- Unknown digest algorithm: blowfish
- Unknown digest algorithm: tiger
- Unknown digest algorithm: sha3-224
Alternatives
- Check available algorithms with hash_algos() before using one.
- Use one of the standard algorithms: md5, sha1, sha256, sha512, sha3-256.
- Verify the algorithm is available by checking in_array($algo, hash_algos()).
- Install or enable the required extension that provides the algorithm (e.g. hash with GOST support).
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Unknown filter with ID
Description
filter_var_array(), and other filter functions, use the second argument to identify which filter to apply. They are usually provided as constants, such as FILTER_SANITIZE_STRING. There are a limited, although long, set of such constants, and not all integer values are used. This is the case for -1.
Example
<?php
var_dump(filter_var_array(array(=>), 128));
?>
Literal Examples
- Unknown filter with ID -1
- Unknown filter with ID 128
Alternatives
- Use a valid constant to specify the filter.
- Do not use literal integers, but constants.
Unknown format specifier “%c
Description
printf() accepts a string of formats, as the first arguments. A format is a % character, followed by a letter. Some letters are not allowed: a, i, j, k, l, m, n, p, q, r, t, v, w, y, z, A, B, C, D, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, Y, Z.
Example
<?php
printf(\%we3e\, 123);
//Unknown format specifier \w\
?>
Alternatives
- Replace the reported letter with a valid format letter.
- Duplicate the % sign, to make it literal.
Unknown hook “%s” for property %s::$%s, expected “get” or “set”
Description
Property hooks can only be named ‘get’ or ‘set’, as of PHP 8.4. In the future, there may be new ones, but not in that version. Also, case is not important.
Example
<?php
class X
{
public string $property {
got {
$this->name = $value;
}
}
}
?>
Literal Examples
- Unknown hook “got” for property X::$property, expected “get” or “set”
Alternatives
- Use ‘set’ or ‘get’ as the name of the hook.
- Wait for a future version of PHP.
Unknown hook "%s" for property %s::$%s
Description
There can be only two property hooks: get and set, and their case variations. All others are currently explicitly forbidden.
Example
<?php
class Test {
public $prop {
foobar {}
}
}
?>
Literal Examples
- Unknown hook “foobar” for property Test::$prop
Alternatives
- Use one of the valid names.
- Remove the property hook.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Unknown named parameter $%s
Description
Named parameters are the parameters of the function, or method. Their actual name is the name of the variable, without the leading $ sign.
With named parameters, the case is important, just like with variables.
Example
<?php
function foo($a, $b) {}
foo(c: 1);
?>
Literal Examples
- Unknown named parameter $c
Alternatives
- Check the case of the parameter.
- Check the signature of the method to see if that parameter actually exists.
- Add the parameter to the method signature.
- Remove the name in the method call, and rely on positional arguments.
- Check the actual method definition: interfaces have precedence, then in the class hierarchy, it is the last defined method, in class or trait.
Unknown or bad format (%s)
Description
This error is emitted by the Date extension, when creating a DatePeriod class. That class requires a start date as the first argument, and the provided value could not be parsed.
Example
<?php
new DatePeriod('L');
?>
Literal Examples
- Unknown or bad format (L)
Alternatives
- Use a valid date.
- Use a DateTimeInterface object as first argument: DateTimeImmutable, DateTime, etc.
- Use the DatePeriod::createFromISO8601String() method to handle ISO 8601 formats.
Unknown parser
Description
This is an internal error, raised during testing. It relates to the URI class, and the available parsers.
Example
Alternatives
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
unlink of “%s” failed, file does not exist
Description
PHP reports failure when trying to remove a file that does not exists in a phar archive. This error message does not appear when using the regular filesystem, or the delete method on a phar object.
This error message is part of the stream system.
Example
<?php
try {
$phar = new Phar('/tmp/myphar.phar');
$phar->addFromString('foo.txt', 'hello');
unset($phar);
$phar = new Phar('/tmp/myphar.phar');
unlink('phar:///tmp/myphar.phar/oops');
} catch (Exception $e) {
// handle errors
print $e->getMessage();
}
?>
Literal Examples
- unlink of “oops” failed, file does not exist
Alternatives
- Check if the file is available before removing it, with
Phar::offsetExists.
Related error messages
Unmatched ‘)’
Description
PHP has encountered a closing parenthesis, but has no related opening parenthesis.
In more complex situations, there might be opening and closing parenthesis: this error reports that there are more closing ones than opening. Eventually, some will not have a matching bracket.
Inside double-quoted strings, the unmatched closing brackets are ignored, and used as literal value.
Example
<?php
$a = 1 + 2)
// One too many parenthesis
if (in_array(foo(), array()))) { doSomething(); }
?>
Alternatives
- Remove the closing curly bracket.
- Add an opening closing curly bracket.
Related error messages
- unclosed-‘(’
- unmatched-‘}’
- [unmatched-‘]’](unmatched-].html)
- [unclosed-‘(’-does-not-match-‘]’](unclosed-(-does-not-match-].html)
- syntax-error,-unexpected-string-content
- syntax-error,-unexpected-variable-“%s”,-expecting-“(”
Unmatched ‘]’
Description
PHP has encountered a closing parenthesis, but has no related opening parenthesis.
In more complex situations, there might be opening and closing parenthesis: this error reports that there are more closing ones than opening. Eventually, some will not have a matching bracket.
Inside double-quoted strings, the unmatched closing brackets are ignored, and used as literal value.
Example
<?php
$a[1 + 2 = 3;
// One too many parenthesis
if (in_array(foo(), array()))) { doSomething(); }
?>
Alternatives
- Remove the closing curly bracket.
- Add an opening closing curly bracket.
Related error messages
- unclosed-‘(’
- unmatched-‘}’
- unmatched-‘)’
- [unclosed-‘(’-does-not-match-‘]’](unclosed-(-does-not-match-].html)
- syntax-error,-unexpected-string-content
Unmatched ‘}’
Description
PHP has encountered a closing curly brackets, but has no related opening curly bracket.
In more complex situations, there might be opening and closing brackets: this error reports that there are more closing ones than opening. Eventually, some will not have a matching bracket.
Inside double-quoted strings, the unmatched closing brackets are ignored, and used as literal value.
Example
<?php
$a = 1 + 2}
// 3 opening, 4 closing.
{{{$b = 1 + 2}}}}
// this unmatched closing bracket is taken as literal
$b = "$a} = 1+2";
?>
Alternatives
- Remove the closing curly bracket.
- Add an opening closing curly bracket.
Related error messages
- unclosed-‘{’
- [unmatched-‘]’](unmatched-].html)
- unmatched-‘)’
- [unclosed-‘(’-does-not-match-‘]’](unclosed-(-does-not-match-].html)
- syntax-error,-unexpected-string-content
Unparenthesized a ? b : c ? d : e is not supported.
Description
The nested ternary operator requires a clear definition of priorities, by using parenthesis.
The code above could be understood as ($a ? $b : $c) ? $d : $e or $a ? $b : ($c ? $d : $e). Until PHP 8.0, the engine choose the second option; Since then, it must be explicitly written.
Note that, in the error message, the letters represent a full expression. They may be variables, as in the illustration, but any other expression.
Example
<?php
$x = $a ? $b : $c ? $d : $e;
?>
Alternatives
- Write the expression as
($a ? $b : $c) ? $d : $e. - Write the expression as
$a ? $b : ($c ? $d : $e). - Rewrite the expression as an if/then.
Related error messages
Unparenthesized a ? b : c ?: d is not supported.
Description
Mixing a full ternary with the short ternary operator (?:) requires a clear definition of priorities, by using parenthesis.
The code above could be understood as ($a ? $b : $c) ?: $d or $a ? $b : ($c ?: $d). Until PHP 8.0, the engine chose the first option, since the ternary operator was left-associative; since then, it must be explicitly written.
Note that, in the error message, the letters represent a full expression. They may be variables, as in the illustration, but any other expression.
Example
<?php
$x = $a ? $b : $c ?: $d;
?>
Alternatives
- Write the expression as
($a ? $b : $c) ?: $d. - Write the expression as
$a ? $b : ($c ?: $d). - Rewrite the expression as an if/then.
Related error messages
- unparenthesized-
a-?-b-:-c-?-d-:-e-is-not-supported. - unparenthesized-
a-?:-b-?-c-:-d-is-not-supported.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Unparenthesized a ?: b ? c : d is not supported.
Description
Mixing the short ternary operator (?:) with a full ternary requires a clear definition of priorities, by using parenthesis.
The code above could be understood as ($a ?: $b) ? $c : $d or $a ?: ($b ? $c : $d). Until PHP 8.0, the engine chose the first option, since the ternary operator was left-associative; since then, it must be explicitly written.
Note that, in the error message, the letters represent a full expression. They may be variables, as in the illustration, but any other expression.
Example
<?php
$x = $a ?: $b ? $c : $d;
?>
Alternatives
- Write the expression as
($a ?: $b) ? $c : $d. - Write the expression as
$a ?: ($b ? $c : $d). - Rewrite the expression as an if/then.
Related error messages
- unparenthesized-
a-?-b-:-c-?-d-:-e-is-not-supported. - unparenthesized-
a-?-b-:-c-?:-d-is-not-supported.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Unserialization of %s is not allowed, override __serialize() and __unserialize() to implement it
Description
This is the mirror error of the serialization one. Some internal classes hold state, such as a connection handle or a resource, that cannot be meaningfully rebuilt from a plain serialized string. Unless the class implements __serialize() and __unserialize() (available since PHP 7.4) to define its own restoration logic, unserialize() refuses to instantiate the object from serialized data and throws this exception instead of returning a half-built, unusable instance.
Example
<?php
$serialized = 'O:3:PDO:0:{}';
$pdo = unserialize($serialized);
?>
Literal Examples
- Unserialization of PDO is not allowed, override __serialize() and __unserialize() to implement it
Alternatives
- Create a subclass that implements
__serialize()and__unserialize()to control exactly how the object is restored. - Do not serialize instances of this class in the first place; persist the data needed to recreate it and rebuild the object manually.
Related error messages
In previous PHP versions, this error message used to be :ref:serialization-of-%s-is-not-allowed,-override-__serialize()-and-__unserialize()-to-implement-it.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Unserializing the ‘S’ format is deprecated
Description
When using the unserialize() function, the string should not use S (upper case S) to format a string. It should only use s (lower case S).
Other formats, such as i, b or N are already case sensitive.
Example
<?php
$encoded = 'S:3:"abc";';
unserialize($encoded);
?>
Alternatives
- Turn the
Sinto lower cases. This might be tricky. - Serialize all over the stored strings with lower case.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See unserialize_S
Unsupported declare '%s'
Description
declare sets some directives for the file or block. The possible directives are limited to three: strict_types, the most common, ticks and encoding.
Example
<?php
declare(a = 1);
?>
Alternatives
- Use one of the three valid declare directives.
- Remove the declare call.
Unsupported operand types
Description
This error is emitted when PHP cannot find a reasonable way to use the parameters of an operator.
In the code example, the string ‘a4.4a’ cannot be converted to an integer or a float. This yield the error.
PHP could do with ‘4.4a’ (cast to 4.4 and a warning), or with ‘4.4’ (cast to a float silently).
On the other hand, the ‘a4.4a’ string cannot be converted to a numeric and it yields the error. Other types, such as an array, an object or a resource would yield the same error. Boolean and null are converted to integers.
This error applies to all operators, with matching constraints.
Conversion to string my be automatically happening, when the strict_type directive is not active.
The error is reported for the first or the second argument. It may also applies to both, though PHP stops at the first one it finds.
Example
<?php
echo a4.4a ** 4;
?>
Alternatives
- Use an explicit cast to ensure the correct type of the operand.
- Check the value before using it with the operator.
Related error messages
- a-non-numeric-value-encountered
- cannot-perform-bitwise-not-on-%s
- a-non-well-formed-numeric-value-encountered
Unsupported operand types: %s %s %s
Description
This error is reported when the types of the operands are valid (here, int and string), but they are not compatible one another. It is possible to use the & operator with two integers, or with two strings but not with one string and one integer.
Example
<?php
1 & 'B';
?>
Literal Examples
- Unsupported operand types: int & string
Alternatives
- Make both sides of the operator the same type.
Unterminated comment starting line %
Description
Multi-line comments, written with /* ... */ or /** ... */, require a closing tag. When that closing tag is missing before the end of the file, PHP cannot determine where the comment was meant to stop and raises a compile error.
This problem does not affect single-line comments (// or #), since those are automatically closed by the end of the line.
Example
<?php
/*
comment
Missing final / below
*
?>
Literal Examples
- Unterminated comment starting line 3
Alternatives
- Check that the closing tag is complete, with both
*and/. - Check that a closing tag has not been omitted entirely.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Unterminated comment starting line %d
Description
The multi-line comments with /* ... */ and /** ... */ require a closing tag. When that closing tag is missing, the error is emitted.
This problem does not occur with the single line comment //, as this comment only ends with the end of the line.
Example
<?php
/*
comment
Missing final / below
*
?>
Literal Examples
- Unterminated comment starting line 3
Alternatives
- Check if the closing tag is complete, with
*and/. - Check if the closing tag is not missing entirely.
Usage of ldap_connect with two arguments is deprecated
Description
ldap_connect() used to accept a hostname and a port as two separate arguments. Passing them separately does not let the caller express whether the connection should use ldap:// or ldaps://, or list several servers at once, which a single LDAP URI can do naturally.
Calling ldap_connect() with a separate hostname and port is now deprecated in favor of passing a single LDAP URI.
Example
<?php
$ldap = ldap_connect('ldap.example.com', 389);
?>
Alternatives
- Pass a single LDAP URI instead, for example
ldap_connect('ldap://ldap.example.com:389')orldap_connect('ldaps://ldap.example.com').
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Usage of session.referer_check INI setting is deprecated
Description
session.referer_check makes session_start() check that the Referer HTTP header sent by the client starts with a given substring, rejecting the session otherwise. This mechanism dates back to a time when it was considered a lightweight session-hijacking mitigation, but the Referer header is client-supplied and trivially spoofed, so it provides no real security guarantee.
As part of the deprecation of PHP’s automatic, URL-based session ID propagation (also affecting session.use_trans_sid and related directives), setting session.referer_check to a non-empty value is deprecated as of PHP 8.4.0.
Example
<?php
ini_set('session.referer_check', 'example.com');
?>
Alternatives
- Remove
session.referer_checkfromphp.iniand from the code; do not rely on theRefererheader for session security. - Use proper session security measures instead, such as regenerating the session ID on privilege change and binding sessions to other verified signals.
Usage of session.trans_sid_hosts INI setting is deprecated
Description
session.trans_sid_hosts restricts on which hosts PHP is allowed to rewrite URLs to inject the session ID (trans sid), which only matters when session.use_trans_sid is enabled in the first place. Trans sid itself – propagating the session ID through the URL and hidden form fields instead of only a cookie – is a legacy mechanism being phased out because it leaks session IDs into logs, the Referer header, and shared/bookmarked links.
As of PHP 8.4, setting session.trans_sid_hosts to any non-empty value emits this deprecation notice, as part of a broader deprecation of GET/POST (URL-based) session propagation ahead of its removal in PHP 9.0.
Example
<?php
// A non-empty value (the empty-string default is fine) triggers the
// deprecation as soon as it's applied.
ini_set('session.trans_sid_hosts', 'example.com');
?>
Literal Examples
- ini_set(): Usage of session.trans_sid_hosts INI setting is deprecated
Alternatives
- Leave session.trans_sid_hosts empty and keep session.use_trans_sid disabled (its default), relying on cookies only.
- If trans sid is still required for a specific legacy integration, treat the whole feature – not just this setting – as something to migrate away from before PHP 9.0.
Related error messages
- usage-of-session.trans_sid_tags-ini-setting-is-deprecated
- enabling-session.use_trans_sid-ini-setting-is-deprecated
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Usage of session.trans_sid_tags INI setting is deprecated
Description
session.trans_sid_tags lists which HTML tag/attribute pairs (e.g. a=href, form=) PHP rewrites to inject the session ID when trans sid (session.use_trans_sid) output rewriting is active. Trans sid – propagating the session ID through the URL and hidden form fields instead of only a cookie – is a legacy mechanism being phased out because it leaks session IDs into logs, the Referer header, and shared/bookmarked links.
As of PHP 8.4, setting session.trans_sid_tags to anything other than its default value (a=href,area=href,frame=src,form=) emits this deprecation notice, as part of a broader deprecation of GET/POST (URL-based) session propagation ahead of its removal in PHP 9.0.
Example
<?php
// Changing it away from its default list of tags triggers the
// deprecation as soon as it's applied.
ini_set('session.trans_sid_tags', 'a=href');
?>
Literal Examples
- ini_set(): Usage of session.trans_sid_tags INI setting is deprecated
Alternatives
- Leave session.trans_sid_tags at its default and keep session.use_trans_sid disabled (its own default), relying on cookies only.
- If trans sid is still required for a specific legacy integration, treat the whole feature – not just this setting – as something to migrate away from before PHP 9.0.
Related error messages
- usage-of-session.trans_sid_hosts-ini-setting-is-deprecated
- enabling-session.use_trans_sid-ini-setting-is-deprecated
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Use of “parent” in callables is deprecated
Description
Since PHP 8.2, it is not possible anymore to use parent as a string, when creating a callable. parent is a keyword with contextual meaning. Then, it has little meaning as a string and leads to confusion.
Example
<?php
class X {
static function foo() {
echo __METHOD__;
}
static function test() {
call_user_func(array('parent','foo'));
}
}
X::test();
?>
Alternatives
- Use
parent::classto make this class name non-ambiguous. - Use another way to create a closure for the method, such as
parent::foo(...).
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See codes/parentInCallable
Use of “self” in callables is deprecated
Description
Since PHP 8.2, it is not possible anymore to use self as a string, when creating a callable. self is a keyword with contextual meaning. Then, it has little meaning as a string and leads to confusion.
Example
<?php
class X {
static function foo() {
echo __METHOD__;
}
static function test() {
call_user_func(array('self','foo'));
}
}
X::test();
?>
Alternatives
- Use
self::classto make this class name non-ambiguous. - Use another way to create a closure for the method, such as
self::foo(...).
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See codes/selfInCallable
Use of “static” in callables is deprecated
Description
Since PHP 8.2, it is not possible anymore to use static as a string, when creating a callable. static is a keyword with contextual meaning. Then, it has little meaning as a string and leads to confusion.
Example
<?php
class X {
static function foo() {
echo __METHOD__;
}
static function test() {
call_user_func(array('static','foo'));
}
}
X::test();
?>
Alternatives
- Use
static::classto make this class name non-ambiguous. - Use another way to create a closure for the method, such as
static::foo(...).
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See codes/staticInCallable
Use of "parent" in callables is deprecated
Description
The relative class names self, parent and static only have a meaning inside a class body, resolved against the scope currently active. Nothing stops a string or array callable from containing parent, e.g. 'parent::method' or ['parent', 'method'], but such a callable has no fixed target: PHP resolves parent against the parent of whatever class scope happens to be active where the callable is finally invoked (through call_user_func(), is_callable(), etc.), which can be a completely different class hierarchy than the one where the string was built.
As of PHP 8.2, resolving a callable that uses parent this way emits Use of "parent" in callables is deprecated. The callable still works for now – and keeps resolving against the invocation-time scope – but this implicit, moving-target behaviour is expected to be removed in a future version.
Example
<?php
class Base {
public static function bar() {
return 'Base::bar called';
}
}
class Foo extends Base {
public static function make() {
// The string is built here, inside Foo, but 'parent' is NOT
// resolved against Foo's parent (Base) -- see where it is
// actually invoked below.
return 'parent::bar';
}
}
class OtherBase {
public static function bar() {
return 'OtherBase::bar called';
}
}
class Other extends OtherBase {
public function run($callable) {
// 'parent' resolves against THIS scope's parent (OtherBase),
// not against Base, which is Foo's parent.
var_dump(call_user_func($callable));
}
}
$callable = Foo::make(); // the string 'parent::bar'
(new Other)->run($callable); // prints 'OtherBase::bar called', not 'Base::bar called'
?>
Literal Examples
- Use of “parent” in callables is deprecated
Alternatives
- Replace ‘parent::method’ with parent::class . ‘::method’ so the callable is no longer context-dependent.
- For array callables, use [parent::class, ‘method’] instead of [‘parent’, ‘method’].
- Use first-class callable syntax (PHP 8.1+), e.g. parent::method(…), when the callable is created and used in the same place.
Related error messages
- use-of–“self-”-in-callables-is-deprecated
- use-of–“static-”-in-callables-is-deprecated
- [callables-of-the-form--“%s
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Use of "self" in callables is deprecated
Description
The relative class names self, parent and static only have a meaning inside a class body, resolved against the scope currently active. Nothing stops a string or array callable from containing one of them, e.g. 'self::method' or ['self', 'method'], but such a callable has no fixed target: PHP resolves self against whatever class scope happens to be active where the callable is finally invoked (through call_user_func(), is_callable(), etc.), which can be a completely different class than the one where the string was built.
As of PHP 8.2, resolving a callable that uses self this way emits Use of "self" in callables is deprecated. The callable still works for now – and keeps resolving against the invocation-time scope – but this implicit, moving-target behaviour is expected to be removed in a future version.
Example
<?php
class Foo {
public static function bar() {
return 'Foo::bar called';
}
public static function make() {
// The string is built here, inside Foo, but 'self' is NOT
// resolved against Foo -- see where it is actually invoked below.
return 'self::bar';
}
}
class Other {
public static function bar() {
return 'Other::bar called';
}
public function run($callable) {
// 'self' resolves against THIS scope (Other), the one active
// where the callable is invoked, not where the string was built.
var_dump(call_user_func($callable));
}
}
$callable = Foo::make(); // the string 'self::bar'
(new Other)->run($callable); // prints 'Other::bar called', not 'Foo::bar called'
?>
Literal Examples
- Use of “self” in callables is deprecated
Alternatives
- Replace ‘self::method’ with self::class . ‘::method’ (or the target class’s own name) so the callable is no longer context-dependent.
- For array callables, use [self::class, ‘method’] instead of [‘self’, ‘method’].
- Use first-class callable syntax (PHP 8.1+), e.g. self::method(…), when the callable is created and used in the same place.
Related error messages
- use-of–“parent-”-in-callables-is-deprecated
- use-of–“static-”-in-callables-is-deprecated
- [callables-of-the-form--“%s
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Use of "static" in callables is deprecated
Description
The relative class names self, parent and static only have a meaning inside a class body, resolved against the scope currently active. Nothing stops a string or array callable from containing static, e.g. 'static::method' or ['static', 'method'], but such a callable has no fixed target: PHP resolves static using late static binding against whatever called scope happens to be active where the callable is finally invoked (through call_user_func(), is_callable(), etc.), which can be a completely different class than the one where the string was built.
As of PHP 8.2, resolving a callable that uses static this way emits Use of "static" in callables is deprecated. The callable still works for now – and keeps resolving against the invocation-time called scope – but this implicit, moving-target behaviour is expected to be removed in a future version.
Example
<?php
class Foo {
public static function bar() {
return 'Foo::bar called';
}
public static function make() {
// The string is built here, inside Foo, but 'static' is NOT
// resolved against Foo -- see where it is actually invoked below.
return 'static::bar';
}
}
class Base {
public static function bar() {
return 'Base::bar called';
}
public static function run($callable) {
// 'static' resolves against the called scope active HERE
// (Sub, since run() was invoked as Sub::run()), not against Foo.
var_dump(call_user_func($callable));
}
}
class Sub extends Base {
public static function bar() {
return 'Sub::bar called';
}
}
$callable = Foo::make(); // the string 'static::bar'
Sub::run($callable); // prints 'Sub::bar called', not 'Foo::bar called'
?>
Literal Examples
- Use of “static” in callables is deprecated
Alternatives
- Replace ‘static::method’ with static::class . ‘::method’ so the callable is no longer context-dependent.
- For array callables, use [static::class, ‘method’] instead of [‘static’, ‘method’].
- Use first-class callable syntax (PHP 8.1+), e.g. static::method(…), when the callable is created and used in the same place.
Related error messages
- use-of–“self-”-in-callables-is-deprecated
- use-of–“parent-”-in-callables-is-deprecated
- [callables-of-the-form--“%s
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Use of iconv.input_encoding is deprecated
Description
iconv.input_encoding used to tell PHP which encoding incoming request data ($_GET, $_POST, etc.) was assumed to be in, for the iconv extension’s own encoding-conversion pass over external input. Having several overlapping encoding-related INI settings, each affecting only part of the request, was a frequent source of mismatched-encoding bugs.
As of PHP 5.6, setting iconv.input_encoding (whether in php.ini or via ini_set()/iconv_set_encoding()) emits this deprecation notice; the single, extension-agnostic default_charset setting should be used instead.
Example
<?php
ini_set('iconv.input_encoding', 'UTF-8');
?>
Literal Examples
- ini_set(): Use of iconv.input_encoding is deprecated
- iconv_set_encoding(): Use of iconv.input_encoding is deprecated
Alternatives
- Leave iconv.input_encoding unset and rely on default_charset instead.
- Convert incoming input explicitly with iconv() where a specific encoding must be assumed.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Use of iconv.internal_encoding is deprecated
Description
iconv.internal_encoding used to control the encoding the iconv_*() functions assumed for strings when no encoding was given explicitly, alongside the separate, more general mbstring.internal_encoding/mbstring.language and the character encoding used when generating output. Having several overlapping encoding-related INI settings, each affecting only part of the request, was a frequent source of mismatched-encoding bugs.
As of PHP 5.6, setting iconv.internal_encoding (whether in php.ini or via ini_set()/iconv_set_encoding()) emits this deprecation notice; the single, extension-agnostic default_charset setting should be used instead.
Example
<?php
ini_set('iconv.internal_encoding', 'UTF-8');
?>
Literal Examples
- ini_set(): Use of iconv.internal_encoding is deprecated
- iconv_set_encoding(): Use of iconv.internal_encoding is deprecated
Alternatives
- Leave iconv.internal_encoding unset and rely on default_charset instead.
- Pass the encoding explicitly to each iconv_*() call rather than relying on any implicit internal encoding.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Use of iconv.output_encoding is deprecated
Description
iconv.output_encoding used to tell PHP which encoding to convert output into, via the iconv extension’s own output handler. Having several overlapping encoding-related INI settings, each affecting only part of the request, was a frequent source of mismatched-encoding bugs.
As of PHP 5.6, setting iconv.output_encoding (whether in php.ini or via ini_set()/iconv_set_encoding()) emits this deprecation notice; the single, extension-agnostic default_charset setting should be used instead.
Example
<?php
ini_set('iconv.output_encoding', 'UTF-8');
?>
Literal Examples
- ini_set(): Use of iconv.output_encoding is deprecated
- iconv_set_encoding(): Use of iconv.output_encoding is deprecated
Alternatives
- Leave iconv.output_encoding unset and rely on default_charset instead.
- Convert generated output explicitly with iconv() where a specific output encoding must be guaranteed.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Use of mbstring.http_input is deprecated
Description
mbstring.http_input used to tell the mbstring extension which encoding(s) to assume for incoming HTTP request data, so it could transparently convert it (in combination with mbstring.encoding_translation).
This mechanism predates, and overlaps with, the language-level input_encoding directive, and having two separate configuration surfaces for the same concern is a frequent source of confusion. mbstring.http_input has been deprecated since PHP 5.6.0, though the deprecation notice is only emitted when the directive is actually set.
Example
<?php
ini_set('mbstring.http_input', 'UTF-8');
?>
Alternatives
- Use the
input_encodingINI directive instead ofmbstring.http_input.
Related error messages
In more recent PHP versions, this error message is now :ref:use-of-mbstring.http_output-is-deprecated.
Use of mbstring.http_output is deprecated
Description
mbstring.http_output used to tell the mbstring extension which encoding to convert outgoing HTTP response data to, so it could transparently re-encode output (in combination with mbstring.encoding_translation and the mb_output_handler output buffer handler).
This mechanism predates, and overlaps with, the language-level output_encoding directive, and having two separate configuration surfaces for the same concern is a frequent source of confusion. mbstring.http_output has been deprecated since PHP 5.6.0, though the deprecation notice is only emitted when the directive is actually set.
Example
<?php
ini_set('mbstring.http_output', 'UTF-8');
?>
Alternatives
- Use the
output_encodingINI directive instead ofmbstring.http_output.
Related error messages
In previous PHP versions, this error message used to be :ref:use-of-mbstring.http_input-is-deprecated.
In more recent PHP versions, this error message is now :ref:use-of-mbstring.internal_encoding-is-deprecated.
Use of mbstring.internal_encoding is deprecated
Description
mbstring.internal_encoding used to set the default encoding assumed by mbstring functions when no explicit encoding argument is given (e.g. mb_strlen($str)).
This mechanism predates, and overlaps with, the language-level default_charset directive, which mbstring functions now fall back to when their own internal encoding has not been set explicitly at runtime via mb_internal_encoding(). Having two separate configuration surfaces for the same concern is a frequent source of confusion. mbstring.internal_encoding has been deprecated since PHP 5.6.0, though the deprecation notice is only emitted when the directive is actually set.
Example
<?php
ini_set('mbstring.internal_encoding', 'UTF-8');
?>
Alternatives
- Use the
default_charsetINI directive instead ofmbstring.internal_encoding. - Call
mb_internal_encoding()at runtime if a specific encoding must be set programmatically.
Related error messages
In previous PHP versions, this error message used to be :ref:use-of-mbstring.http_output-is-deprecated.
Use of warnings for SQLite3 is deprecated
Description
The SQLite3 extension historically reported errors (such as a failed query) by emitting an E_WARNING and returning false, which is inconsistent with the exception-based error handling used elsewhere in PHP, and requires manual checking of every return value. SQLite3::enableExceptions(true) switches to throwing SQLite3Exception instead, and has been available for a long time as an opt-in.
As of PHP 8.3.0, the legacy warning-based mode is deprecated: calling SQLite3::enableExceptions() with false (or not calling it at all, since false is the default) raises a deprecation notice.
Example
<?php
$db = new SQLite3(':memory:');
// Explicitly keeps the legacy, warning-based error mode.
$db->enableExceptions(false);
?>
Alternatives
- Call
$db->enableExceptions(true)right after opening the connection, and handleSQLite3Exceptioninstead of checking return values forfalse.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See SQLite3::enableExceptions
Using “_” as %s is deprecated since 8.4
Description
_ (underscore) is a valid class name, although it has become a reserved PHP word in PHP 8.4. In the future, it may be used for pattern matching, and by anticipation, it is not allowed for other usage that may ultimately conflict with it.
This applies to classes, traits, interfaces and enumerations. There is already an extension function called _, which is an alias of gettext, from the eponymous extension.
This applies in every name spaces.
Example
<?php
class _ {}
?>
Alternatives
- Use another name.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See ClassUnderscore
Using $this when not in object context
Description
A static method is also called a class method: it may be executed without a dedicated object. That object is usually made available in the method, via the pseudo variable $this.
Hence, when a method is marked as static, the variable $this is not made available, and cannot be used.
In the error message, the ‘object context’ refers to a class, enum or trait. $this must be localised inside such structures; even more, it is only used in the body of a method of such structure.
Inside a class, trait or enum, static methods, static closures and static arrow functions shall not use $this. The two last ones are marked also with the static keyword.
Example
<?php
class X {
static function foo() { print $this; }
}
var_dump(x::foo());
?>
Alternatives
- Make the method non-static, and use $this.
- Keep the method static, and remove calls to $this.
- Make the closure non-static.
- Make the arrow function non-static.
Related error messages
Using ${expr} (variable variables) in strings is deprecated, use {${expr}} instead
Description
The interpolation syntax ${expression} is deprecated. It takes an expression (here, a concatenation) to build the name of the variable that is used in the end. It is recommended to update the syntax with a compatible one or use concatenation, before the syntax is removed.
Example
<?php
$foo = 'bar';
$bar = 'xyz';
var_dump("foo is $\{$foo}");
?>
Alternatives
- Use
{}instead. - Use concatenation instead.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See dollar_curly_expression
Using in strings is deprecated, use {$var} instead
Description
For variable interpolation, the double quote strings used two variants: ${var} ($ is outside the brackets), and {$var} ($ is inside the brackets).
The first one has been deprecated, and it should be removed in PHP 9.0.
Example
<?php
$var = 'abc';
echo ;
?>
Alternatives
- Replace
${var}with$varinside the string. It should work most of the time. - Replace
${var}with{$var}inside the string. It works every time.
Using an object as a backing array for %s is deprecated, as it allows violating class constraints and invariants
Description
It is not allowed anymore to create an ArrayObject based on an object. This leads to many unexpected behaviors, that are not supported anymore by PHP.
Example
<?php
$object = new stdClass;
$object->a = 1;
new ArrayObject($object);
?>
Literal Examples
- Using an object as a backing array for
ArrayObjectis deprecated, as it allows violating class constraints and invariants
Alternatives
- Cast the object to array before using it with
ArrayObject. - Do not use
ArrayObject.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Using array_key_exists() on objects is deprecated.
Description
array_key_exists() used to accept both arrays and objects. In array cases, it looks for an index in the array keys, and in the object case, it looks for a property in the public properties.
array_key_exists() only works with array: it doesn’t work with ArrayAccess object, and yields the same error.
In PHP 7.4, this feature was deprecated, with the eponymous message. In PHP 8.0, it is now turned into a type error: the second argument must be an array.
Example
<?php
class X {
public string $property = '';
}
$object = new X();
array_key_exists($object, 'index');
?>
Alternatives
- Check if the variable is actually an object before using it with array_key_exists().
- Check if the variable is actually an object before using it with array_key_exists().
Related error messages
In more recent PHP versions, this error message is now :ref:argument-#%d-($%s)-must-be-of-type-%s,-%s-given.
Using empty file as ZipArchive is deprecated
Description
ZipArchive::open() accepts an existing, empty (0-byte) file together with the ZipArchive::CREATE flag, in order to turn it into a fresh archive. This relied on treating a 0-byte file as an implicit, valid, empty archive.
Since libzip 1.6.0, the library underlying the zip extension no longer considers an empty file a valid archive on its own, and PHP has to work around that internally. As of PHP 8.0.0, doing so is deprecated. This is commonly triggered by patterns using tempnam() (which creates an empty placeholder file) before opening it as an archive.
Example
<?php
$path = tempnam(sys_get_temp_dir(), 'zip');
// tempnam() leaves an empty (0-byte) file behind.
$zip = new ZipArchive();
$zip->open($path, ZipArchive::CREATE);
?>
Alternatives
- Delete the empty file before calling
$zip->open($path, ZipArchive::CREATE), so it does not exist yet. - Use the
ZipArchive::OVERWRITEflag (optionally combined withZipArchive::CREATE) instead of relying on an existing empty file.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See ZipArchive::open
Using more than “ ZEND_LONG_FMT “ filters in a php://filter URL is deprecated
Description
A php://filter/... URL can chain any number of stream filters with |. To bound the cost of building very long chains, PHP now caps the number of filters read from a single URL at 16 (ZEND_LONG_FMT is a printf-style placeholder for a platform-independent long integer, substituted with 16 in the actual message) unless a higher limit is configured explicitly. Exceeding that default without configuring it emits this deprecation; a future version will make the limit a hard error instead.
Example
<?php
$filters = str_repeat('string.toupper|', 17) . 'string.toupper';
echo file_get_contents("php://filter/$filters/resource=data:text/plain,hello");
?>
Literal Examples
- Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append
Alternatives
- Set the stream context option
filter=>max_filter_countto the number of filters you actually need, e.g. viastream_context_create(['filter' => ['max_filter_count' => 32]]). - Build the chain with repeated stream_filter_append() calls instead of a long php://filter URL; it is not subject to this limit.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Using more than %d filters in a php://filter URL is deprecated
Description
The php://filter stream wrapper lets several conversion filters be chained in a single URL, separated by |. By default, PHP now limits the number of filters that can be chained this way to 16; exceeding that limit triggers this deprecation, and a future version is expected to turn it into a hard failure.
The limit only applies to filters listed directly in a php://filter URL. It does not affect filters added programmatically with stream_filter_append(), nor is it lowered unless a smaller max_filter_count is explicitly configured on the stream context (in which case exceeding it already fails immediately, without this deprecation).
Restricting the default chain length also mitigates a known exploitation technique (“PHP filter chains”) that abuses very long filter chains to convert an arbitrary-read vulnerability into code execution by repeatedly transcoding a string in memory.
Example
<?php
$filters = implode('|', array_fill(0, 17, 'string.toupper'));
// deprecated: more than 16 filters chained directly in the URL
$data = file_get_contents("php://filter/read=$filters/resource=php://memory");
?>
Literal Examples
- Using more than 16 filters in a php://filter URL is deprecated
Alternatives
- Raise or override the default limit by setting the
filter.max_filter_countstream context option, e.g.stream_context_create(['filter' => ['max_filter_count' => 100]]). - Use
stream_filter_append()to add filters programmatically instead of chaining a long list of them in the URL. - Reduce the number of chained filters if the default of 16 is sufficient.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Using null as an array offset is deprecated, use an empty string instead
Description
Avoid using null as an array index. PHP converts it silently to an empty string anyway.
Example
<?php
$array = ['a' => 2];
$array[null] = 3;
?>
Alternatives
- Replace the
nullwith an empty string. - Check the value before using it as an array index.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See NullAsArrayOffset
Using null as the key parameter for array_key_exists() is deprecated, use an empty string instead
Description
null cannot be used as an array index anymore, since PHP 8.5. It is deprecated. As such, there is no point anymore to in passing such values to the first argument of array_key_exists(), and this is also deprecated.
Example
<?php
$array = [null => 1];
var_dump(array_key_exists(null, $array));
?>
Alternatives
- Use the coalesce operator
??to turn thenullinto another value, such as empty string. - Replace the
nullvalue by the empty string.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See NullAsArrayOffset, NullWithArrayKeyExists
Using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated,
Description
spl_autoload_unregister() normally removes one specific autoload function that was previously registered with spl_autoload_register(). As an undocumented side effect, passing the engine’s own spl_autoload_call() function as the callback acted as a magic value that unregistered all autoloaders at once, regardless of how many were registered or by which part of the code.
This implicit, all-or-nothing shortcut is deprecated as of PHP 8.5 because it is easy to trigger by accident (any code that unregisters its own autoloader using the wrong callable name) and because it silently affects autoloaders registered by unrelated libraries. Use spl_autoload_functions() to list every registered autoloader and unregister them individually instead.
Example
<?php
spl_autoload_register(function ($class) {
// custom autoloading logic
});
// Passing the internal spl_autoload_call() as a callback is a
// magic value that unregisters every registered autoloader at once.
spl_autoload_unregister('spl_autoload_call');
?>
Literal Examples
- Using spl_autoload_call() as a callback for spl_autoload_unregister() is deprecated, use spl_autoload_functions() and spl_autoload_unregister() on each entry instead
Alternatives
- Iterate over spl_autoload_functions() and call spl_autoload_unregister() on each entry to unregister every autoloader explicitly.
- Keep a reference to the specific autoloader callable your own code registered, and unregister only that one instead of relying on the magic shortcut.
Related error messages
- spl_autoload_unregister
- spl_autoload_register
- spl_autoload_functions
- PHP RFC: Deprecations for PHP 8.5
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Using the $num_points parameter is deprecated
Description
imagepolygon() and imagefilledpolygon() take an array of point coordinates and a $num_points argument stating how many vertices that array describes. In practice, $num_points is almost always equal to count($points) / 2, since the array must contain the x/y pairs for exactly that many points.
Because the value is redundant with the actual size of $points, and mismatches between the two used to be a common source of bugs (or of manual, brittle count() / 2 computations at every call site), the $num_points argument is deprecated as of PHP 8.1.0 in favor of omitting it and letting PHP derive the point count from the array itself.
Example
<?php
$im = imagecreatetruecolor(100, 100);
$color = imagecolorallocate($im, 255, 0, 0);
$points = [10, 10, 50, 90, 90, 10];
imagepolygon($im, $points, 3, $color);
?>
Alternatives
- Omit
$num_pointsentirely, e.g.imagepolygon($im, $points, $color);$pointsmust then contain an even number of elements.
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See imagepolygon, imagefilledpolygon
Value for class is not a string
Description
Exception::getTraceAsString() (and the trace formatting used when an uncaught exception is printed) rebuilds a readable string from the exception’s internal trace array, one frame at a time. Each frame is expected to store its class entry, when present, as a string.
The trace array is normally built by the engine and always well-formed, but it can be replaced or altered by user code, typically through ReflectionProperty::setValue() on the trace property. If a frame’s class entry is present but is not a string, this warning is raised while the frame is rendered as [unknown] instead of the real class name.
Example
<?php
$e = new Exception();
$ref = new ReflectionProperty($e, 'trace');
$ref->setValue($e, [
['class' => null, 'type' => '::', 'function' => 'foo'],
]);
echo $e->getTraceAsString();
?>
Literal Examples
- Value for class is not a string
Alternatives
- Do not overwrite the trace property of an exception with malformed frame data; if you need custom trace-like data, use a separate property.
- When constructing trace frames manually, make sure class, function and type are always strings.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
value must be between 0 and %d
Description
imagefilter() with IMG_FILTER_SCATTER accepts an optional 5th argument: an array of color indexes to scatter, each of which is converted to a C int and must be a non-negative color index.
Starting in PHP 8.5, GD validates every element of that array and rejects negative or out-of-range values with a ValueError naming the offending argument, instead of passing a meaningless value through to the underlying library.
Example
<?php
$im = imagecreatetruecolor(100, 100);
imagefilter($im, IMG_FILTER_SCATTER, 4, 4, [-1]);
?>
Literal Examples
- imagefilter(): Argument #5 value must be between 0 and 2147483647
Alternatives
- Only pass non-negative color indexes, between
0and2147483647, in the color array given toimagefilter(IMG_FILTER_SCATTER).
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Value of type %s is not callable
Description
There was an attempt to call a function whose name was provided in a variable, but that value could not be related to a callable code.
null: not a callabletrue,false: booleans are not callableint: integers are not callablefloat: float are not callablearray: arrays are callable when they have two elements, with keys 0 and 1. First one is a class or an object of that class, the second is a string with a visible method name on that class. Otherwise, they are not valid callables.string: strings are callable when they represent a function, with the leading backslash,\strlen, or a method, with a class name, a double colon::, and a visible method name. Otherwise, they are not valid callables.object: object are callable when their class has a__invokemethod. This might be through a parent, likeClosure. Otherwise, objects are not callable, although their method are.
All of these may be checked with a call to is_callable() on the variable, before using it.
Example
<?php
$method = null;
$method();
?>
Literal Examples
- Value of type int is not callable
- Value of type bool is not callable
- Value of type string is not callable
- Value of type float is not callable
Alternatives
- Check the variable with
is_callable(), before using it with the call syntax. - Use one of the available format.
Related error messages
Variadic parameter cannot have a default value
Description
A variadic parameter, marked with ..., already collects zero or more arguments into an array: when no argument is passed for it, it is simply an empty array. There is no meaning in giving it a default value, since the parameter itself can never be missing from the call, only empty.
This is a compile time check.
Example
<?php
function foo(...$a = []) {}
?>
Alternatives
- Remove the default value from the variadic parameter.
- Check inside the function body whether the collected array is empty, instead of relying on a default value.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Variadic placeholder may only appear once
Description
The … placeholder used for partial function application (PHP 8.5) stands for all of the function’s remaining, not-yet-supplied parameters, which become the parameters of the resulting Closure. Using it more than once in the same call is ambiguous, since there is only one set of “remaining parameters” to represent, so PHP allows at most one placeholder per call.
Example
<?php
function add($a, $b, $c) {
return $a + $b + $c;
}
$curried = add(..., ...);
?>
Alternatives
- Use a single … placeholder per call; wrap the result in an extra closure for any additional free parameters.
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Variadic placeholder must be last
Description
The … placeholder used for partial function application (PHP 8.5) introduces the parameters of the resulting Closure, made of every parameter of the original function that was not already given a fixed value. Because everything before it is treated as a fixed, bound argument, the placeholder itself must come last in the call; PHP has no way to bind arguments positioned after it.
Example
<?php
function add($a, $b, $c) {
return $a + $b + $c;
}
$curried = add(..., 2, 3);
?>
Alternatives
- Put every fixed argument before …, and keep … as the final argument: add(1, 2, …).
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Visibility of property %s::$%s must not be weaker than set visibility
Description
When using asymmetric visibility, it is not allowed to have a weaker public visibility for writing than for reading (private). This would be akin to a variable which can be written from the public scope, which is accessible to the class, but not read from that scope. As such, the set visibility must be at most the same than the get one.
Using the same level of visibility with both options is possible, although useless.
Example
<?php
class X {
private public(set) string $p;
// valid but useless
//protected protected(set) string $p;
// valid
public public(set) string $p;
}
?>
Literal Examples
- Visibility of property
x::$pmust not be weaker than set visibility
Alternatives
- Make the property private, and set up an accessor method.
- Use the magic methods
__get()and__set()to set up that kind of feature.
Void can only be used as a standalone type
Description
void is a special return type, indicating that a function or method returns no useful value. Since it represents the absence of a value, it cannot be combined with other types in a union, nor made nullable: it can only be used on its own, as the sole return type of a function or method.
Example
<?php
function foo(): int|void {}
?>
Alternatives
- Remove the other types, and use
voidalone. - Remove
void, and keep the other type(s) alone.
Related error messages
- never-can-only-be-used-as-a-standalone-type
- type-mixed-can-only-be-used-as-a-standalone-type
- a-void-%s-must-not-return-a-value
- void-cannot-be-used-as-a-parameter-type
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
void cannot be used as a parameter type
Description
Void is a type, that can only be used with return type, on methods or functions. Here, void represents the absence of value: this is not possible for a property or an argument. The null value is then the closest possible type that can be assigned to a property, yet representing no value.
Example
<?php
function foo(void $p) { }
?>
Alternatives
- Use another type for the argument.
- Remove the argument.
- Use the null type.
Related error messages
Related error messages
WeakMap key must be an object
Description
WeakMap associates data with objects, and it holds its keys weakly: when a key object is destroyed, its entry is removed automatically. Because of this, only objects can be used as keys. Any other value, such as a string, an integer, an array or null, triggers a TypeError.
The check applies to every access to a WeakMap through array syntax: assignment, reading, isset(), empty() and unset().
If you need to index data by a scalar value, use a regular array instead.
Example
<?php
$map = new WeakMap();
// WeakMap keys are held weakly, so they must be objects
$map['name'] = 'Damien';
?>
Literal Examples
- WeakMap key must be an object
Alternatives
- Use an object as the key, such as the instance the data relates to.
- Use a regular array when the keys are strings or integers, as arrays do not need weak references.
- Check the key with is_object() before accessing the WeakMap.
Related error messages
Related error messages
Changed Behavior
This error may appear following an evolution in behavior, in previous versions. See
Write of %zu bytes failed with errno=%d %s
Description
The errno=22 happens when the path is an invalid path. It may hold forbidden characters, such as colon : or space ' '.
Example
<?php
file_put_contents($path, $content);
?>
Literal Examples
- Write of 200 bytes failed with
errno=22
Alternatives
- Check the path of the file.
Wrong encoding, conversion from “%s” to “%s” is not allowed
Description
This message reports that the origin or the destination encoding when calling iconv() is not supported on this server. It might be a typo in the encoding name, or an uninstalled encoding on the system. Note that lower case and uppercase do not matter.
Example
<?php
$string = iconv('utf-8', 'not-an-encoding', $source);
?>
Literal Examples
- Wrong encoding, conversion from “utf-8” to “utf-9” is not allowed
- Wrong encoding, conversion from “bag5” to “utf-8” is not allowed
Alternatives
- Check the names of the encodings for typos.
- Check the installed encodings on the system.
- Check the encodings actually exist.