# RFC: Deprecations for PHP 8.5

- Status: Implemented (PHP 8.5)
- Authors: Gina Peter Banyard girgias@php.net Christoph M. Becker cmb@php.net Daniel Scherzer daniel.e.scherzer@gmail.com Tim Düsterhus timwolla@php.net Theodore Brown theodorejb@php.net Jorg Sowa jorg.sowa@gmail.com David Carlier devnexen@gmail.com Jakub Zelenka bu
- Date: 2024-09-26
- Implementation: 8.5 Deprecate semicolon after case in switch statement Deprecate non-standard cast names Deprecate backticks as an alias for shell_exec Deprecate the __sleep() and __wakeup() magic methods (__sleep(), __wakeup()) Deprecate using values null as an array of
- Original: https://wiki.php.net/rfc/deprecations_php_8_5
- Page: https://externals.io/rfc/deprecations_php_8_5
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

## Votes

### Deprecate semicolon-terminated case statements? (closed)

Yes: 22 · No: 10

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (No), bwoebi (No), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), derick (No), dharman (Yes), enorris (Yes), ericmann (No), galvao (No), girgias (Yes), josh (Yes), kalle (No), kocsismate (Yes), lufei (Yes), mbeccati (Yes), nicolasgrekas (No), nielsdos (No), nikic (Yes), ocramius (Yes), petk (Yes), santiagolizardo (Yes), sergey (Yes), shivam (No), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate non-standard cast names? (closed)

Yes: 32 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), ayesh (Yes), brzuchal (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), devnexen (Yes), dharman (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), ilutov (Yes), josh (Yes), kalle (Yes), kocsismate (Yes), lufei (Yes), mbeccati (Yes), nicolasgrekas (Yes), nikic (Yes), ocramius (Yes), petk (Yes), santiagolizardo (Yes), sergey (Yes), shivam (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate attributes applying to multiple class properties/constants (closed)

Yes: 5 · No: 19

Voters: alcaeus (No), asgrim (Yes), ashnazg (No), brzuchal (No), bukka (No), bwoebi (No), cmb (No), daniels (Yes), dharman (No), ericmann (No), galvao (No), ilutov (No), josh (No), kalle (No), mbeccati (No), nicolasgrekas (No), nielsdos (No), nikic (No), ocramius (Yes), petk (Yes), santiagolizardo (No), shivam (No), theodorejb (Yes), thorstenr (No)

### Deprecate backticks as an alias for shell_exec? (closed)

Yes: 21 · No: 8

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (No), bukka (No), bwoebi (Yes), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), derick (No), dharman (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (No), girgias (Yes), josh (Yes), kalle (No), lufei (Yes), mbeccati (No), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), santiagolizardo (No), shivam (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate the __sleep() and __wakeup() magic methods? (closed)

Yes: 18 · No: 9

Voters: alcaeus (No), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (No), bwoebi (No), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), derick (No), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), lufei (Yes), mbeccati (Yes), nicolasgrekas (No), nielsdos (No), ocramius (No), petk (Yes), santiagolizardo (Yes), shivam (No), theodorejb (Yes), thorstenr (Yes)

### Deprecate using values null as an array offset and when calling array_key_exists()? (closed)

Yes: 25 · No: 3

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (No), bwoebi (Yes), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), josh (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nielsdos (No), nikic (Yes), ocramius (Yes), petk (Yes), shivam (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate __debugInfo() returning null? (closed)

Yes: 22 · No: 5

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (No), bwoebi (No), cmb (No), cpriest (Yes), daniels (Yes), dharman (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), josh (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nielsdos (No), nikic (Yes), ocramius (Yes), petk (Yes), santiagolizardo (Yes), shivam (No), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate constant redeclaration? (closed)

Yes: 31 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (Yes), bwoebi (Yes), cmb (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), ilutov (Yes), josh (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), nikic (Yes), ocramius (Yes), petk (Yes), shivam (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate closure binding issues? (closed)

Yes: 29 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (Yes), bwoebi (Yes), cmb (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), ilutov (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), nikic (Yes), ocramius (Yes), petk (Yes), shivam (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Enact follow-up phase of the Path to Saner Increment/Decrement operators RFC? (closed)

Yes: 23 · No: 4

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (No), bwoebi (No), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), derick (No), dharman (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), ilutov (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), ocramius (Yes), petk (Yes), shivam (Yes), theodorejb (Yes), thorstenr (Yes)

### Deprecate the report_memleaks INI directive? (closed)

Yes: 23 · No: 2

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), ayesh (Yes), brzuchal (Yes), bukka (No), bwoebi (No), cpriest (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), shivam (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate the register_argc_argv INI directive and make in default to Off in PHP 8.5, then hardcode it to Off for all non-CLI-related SAPIs on PHP 9 (while keeping it hardcoded to On for CLI-related ones)? (closed)

Yes: 27 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), ilutov (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nikic (Yes), ocramius (Yes), petk (Yes), shivam (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Remove disable_classes INI setting? (closed)

Yes: 26 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (Yes), cmb (Yes), cpriest (Yes), crell (Yes), daniels (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), ilutov (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), nikic (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate Reflection*::setAccessible()? (closed)

Yes: 24 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nikic (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate ReflectionParameter::allowsNull()? (closed)

Yes: 9 · No: 10

Voters: alcaeus (No), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (No), bwoebi (No), crell (Yes), daniels (Yes), ericmann (No), galvao (No), ilutov (No), kalle (No), nicolasgrekas (No), nielsdos (No), ocramius (Yes), petk (Yes), shivam (No), theodorejb (Yes), timwolla (Yes)

### Deprecate ReflectionClass::getConstant() for missing constants? (closed)

Yes: 25 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), josh (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate ReflectionProperty::getDefaultValue() for properties without default values? (closed)

Yes: 22 · No: 2

Voters: alcaeus (Yes), asgrim (Yes), ashnazg (Yes), brzuchal (Yes), bukka (No), bwoebi (Yes), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate ArrayObject and ArrayIterator with objects? (closed)

Yes: 26 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (Yes), bwoebi (Yes), cmb (Yes), cpriest (Yes), crell (Yes), daniels (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), ilutov (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), nikic (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate SplObjectStorage::contains(), SplObjectStorage::attach(), and SplObjectStorage::detach()? (closed)

Yes: 17 · No: 2

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), dharman (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (No), ocramius (Yes), petk (Yes), theodorejb (Yes), timwolla (No)

### Deprecate passing spl_autoload_call() to spl_autoload_unregister()? (closed)

Yes: 23 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nikic (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate non-canonical type names for settype()? (closed)

Yes: 8 · No: 10

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (No), cmb (No), cpriest (Yes), crell (No), derick (No), dharman (No), ericmann (No), galvao (Yes), kalle (No), mbeccati (Yes), nicolasgrekas (No), ocramius (Yes), petk (Yes), theodorejb (No)

### Deprecate the $exclude_disabled parameter of get_defined_functions()? (closed)

Yes: 23 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bwoebi (Yes), cpriest (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), ilutov (Yes), josh (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), timwolla (Yes)

### Deprecate passing null to readdir(), rewinddir(), and closedir()? (closed)

Yes: 24 · No: 3

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), dharman (Yes), edorian (Yes), enorris (Yes), ericmann (No), galvao (Yes), girgias (Yes), ilutov (Yes), josh (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (No), nikic (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate passing string which are not one byte long to ord()? (closed)

Yes: 20 · No: 4

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (No), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), ericmann (No), galvao (Yes), girgias (Yes), ilutov (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (No), ocramius (Yes), petk (Yes), shivam (Yes), theodorejb (Yes), timwolla (Yes)

### Deprecate passing integers outside the interval [0, 255] to chr()? (closed)

Yes: 21 · No: 1

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), ericmann (No), galvao (Yes), girgias (Yes), ilutov (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), timwolla (Yes)

### Formally deprecate socket_set_timeout? (closed)

Yes: 22 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nikic (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), timwolla (Yes)

### Deprecate the $http_response_header predefined variable? (closed)

Yes: 22 · No: 2

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (Yes), cmb (Yes), cpriest (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), lufei (Yes), mbeccati (Yes), nicolasgrekas (No), nielsdos (Yes), ocramius (Yes), petk (Yes), shivam (Yes), theodorejb (Yes)

### Deprecate FILTER_DEFAULT constant? (closed)

Yes: 12 · No: 10

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (No), cmb (No), cpriest (No), daniels (Yes), derick (No), dharman (No), ericmann (No), galvao (Yes), girgias (Yes), josh (Yes), kalle (No), nielsdos (No), nikic (Yes), ocramius (Yes), petk (Yes), shivam (No), theodorejb (Yes), thorstenr (Yes)

### Emit a deprecation notice when using the default value for the $filter argument of the filter_*() functions? (closed)

Yes: 9 · No: 10

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (No), cmb (No), cpriest (No), daniels (Yes), derick (No), dharman (No), ericmann (No), galvao (Yes), girgias (Yes), kalle (No), nielsdos (No), ocramius (Yes), petk (Yes), shivam (No), theodorejb (Yes)

### Deprecate special build system support for drivers without a driver manager? (closed)

Yes: 16 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), cmb (Yes), crell (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes)

### Deprecate ODBCVER checks? (closed)

Yes: 15 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), cmb (Yes), crell (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes)

### Deprecate PDO’s uri: scheme? (closed)

Yes: 22 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nikic (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate PDO::ERRMODE_WARNING constant? (closed)

Yes: 8 · No: 12

Voters: asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (No), cmb (No), cpriest (No), derick (No), dharman (Yes), ericmann (No), galvao (No), girgias (Yes), kalle (No), mbeccati (No), nielsdos (No), ocramius (Yes), petk (Yes), shivam (No), theodorejb (Yes), thorstenr (No), timwolla (Yes)

### Deprecate driver specific PDO constants and methods? (closed)

Yes: 17 · No: 6

Voters: asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (Yes), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), derick (No), ericmann (Yes), galvao (Yes), girgias (Yes), josh (Yes), kalle (Yes), kocsismate (Yes), mbeccati (No), nielsdos (No), ocramius (Yes), petk (Yes), shivam (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (No)

### Deprecate statement transaction state specific PDO constants? (closed)

Yes: 17 · No: 0

Voters: asgrim (Yes), brzuchal (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes)

### Deprecate finfo_close()? (closed)

Yes: 24 · No: 2

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (Yes), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate xml_parser_free()? (closed)

Yes: 22 · No: 2

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (Yes), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), timwolla (Yes)

### Deprecate curl_close()? (closed)

Yes: 23 · No: 3

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (Yes), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), dharman (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), ocramius (Yes), petk (Yes), shivam (No), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate curl_share_close()? (closed)

Yes: 23 · No: 3

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (Yes), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), dharman (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), ocramius (Yes), petk (Yes), shivam (No), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate imagedestroy()? (closed)

Yes: 23 · No: 2

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (No), bwoebi (Yes), cmb (No), cpriest (Yes), crell (Yes), daniels (Yes), dharman (Yes), edorian (Yes), enorris (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate key_length parameter of openssl_pkey_derive()? (closed)

Yes: 24 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (Yes), bwoebi (Yes), cmb (Yes), crell (Yes), daniels (Yes), derick (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), nikic (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate intl.error_level INI setting? (closed)

Yes: 22 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), cmb (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), ilutov (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Formally deprecate mysqli_execute? (closed)

Yes: 22 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate building ext/ldap against Oracle LDAP? (closed)

Yes: 19 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bukka (Yes), cmb (Yes), daniels (Yes), derick (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes)

### Deprecate the $context parameter for finfo_buffer()? (closed)

Yes: 24 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bwoebi (Yes), cmb (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), nielsdos (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

### Deprecate DATE_RFC7231 and DateTimeInterface::RFC7231? (closed)

Yes: 22 · No: 0

Voters: alcaeus (Yes), asgrim (Yes), brzuchal (Yes), bwoebi (Yes), cpriest (Yes), crell (Yes), daniels (Yes), derick (Yes), dharman (Yes), edorian (Yes), ericmann (Yes), galvao (Yes), girgias (Yes), kalle (Yes), kocsismate (Yes), mbeccati (Yes), nicolasgrekas (Yes), ocramius (Yes), petk (Yes), theodorejb (Yes), thorstenr (Yes), timwolla (Yes)

## Discussions on the mailing list

- [semicolon terminator for switch cases](https://externals.io/message/109350.md) — started on 2020-03-26, 10 messages
- [Deprecate filter_input() or not?](https://externals.io/message/126296.md) — started on 2025-02-05, 5 messages
- [\[RFC\] Deprecations for PHP 8.5](https://externals.io/message/127849.md) — started on 2025-07-02, 73 messages
- [\[RFC\] \[VOTE\] Deprecations for PHP 8.5](https://externals.io/message/128226.md) — started on 2025-07-25, 17 messages
- [Inconsistency in PHP 8.5 deprecation of terminating case with semicolon](https://externals.io/message/128839.md) — started on 2025-10-15, 3 messages
- [Was deprecation of DATE_RFC7231 and DateTimeInterface::RFC7231 a mistake?](https://externals.io/message/129801.md) — started on 2026-01-21, 8 messages
- [Deprecate b-prefix for strings](https://externals.io/message/132634.md) — started on 2026-09-25, 7 messages

---

## Introduction

The RFC proposes to deprecate the listed functionality in PHP 8.5 and remove it in PHP 9 (except where otherwise noted).

The following list provides a short overview of the functionality targeted for deprecation, while more detailed explanation is provided in the Proposal section:

- Language/syntax deprecations: 
    - Deprecate semicolon after `case` in switch statement
    - Deprecate non-standard cast names
    - Deprecate attributes applying to multiple class properties/constants
    - Deprecate backticks `` ` `` as an alias for shell\_exec
    - Deprecate the `__sleep()` and `__wakeup()` magic methods
    - Deprecate using values `null` as an array offset and when calling `array_key_exists()`
    - Deprecate `__debugInfo()` returning `null`
    - Deprecate constant redeclaration
    - Deprecate `Closure` binding issues
    - Enact follow-up phase of the “[Path to Saner Increment/Decrement operators](https://externals.io/rfc/saner-inc-dec-operators)” RFC
- Core INI directive deprecations: 
    - Deprecate the `report_memleaks` INI directive
    - Deprecate the `register_argc_argv` INI directive
    - Remove the `disable_classes` INI setting
- ext/reflection deprecations: 
    - Deprecate `Reflection*::setAccessible()`
    - Deprecate `ReflectionParameter::allowsNull()`
    - Deprecate `ReflectionClass::getConstant()` for missing constants
    - Deprecate `ReflectionProperty::getDefaultValue()` for properties without default values
- ext/spl deprecations: 
    - Deprecate `ArrayObject` and `ArrayIterator` with objects
    - Deprecate `SplObjectStorage::contains()`, `SplObjectStorage::attach()`, and `SplObjectStorage::detach()`
    - Deprecate passing `spl_autoload_call()` to `spl_autoload_unregister()`
- ext/standard deprecations: 
    - Deprecate non-canonical type names for `settype()`
    - Deprecate the `$exclude_disabled` parameter of `get_defined_functions()`
    - Deprecate passing `null` to `readdir()`, `rewinddir()`, and `closedir()`
    - Deprecate passing string which are not one byte long to `ord()`
    - Deprecate passing integers outside the interval `[0, 255]` to `chr()`
    - Formally deprecate `socket_set_timeout()`
    - Deprecate the `$http_response_header` predefined variable
- ext/filter deprecations: 
    - Deprecate `FILTER_DEFAULT` constant
    - Make `$filter` parameter mandatory for `filter_*()` functions
- ext/odbc deprecations: 
    - Remove flags for building against specific drivers directly
    - Remove support for older ODBC versions
- ext/pdo deprecations: 
    - Deprecate PDO's 'uri:' scheme
    - Deprecate `PDO::ERRMODE_WARNING` error mode
    - Deprecate driver specific `PDO` constants and methods
    - Deprecate `Pdo\Pgsql` constants related to statement transaction state
- Deprecate no-op functions from the resource to object conversion: 
    - Deprecate `finfo_close()`
    - Deprecate `xml_parser_free()`
    - Deprecate `curl_close()`
    - Deprecate `curl_share_close()`
    - Deprecate `imagedestroy()`
- Deprecate `$key_length` parameter of `openssl_pkey_derive()`
- Deprecate `intl.error_level` INI setting
- Formally deprecate `mysqli_execute()`
- Deprecate building ext/ldap against Oracle LDAP
- Deprecate the `$context` parameter for `finfo_buffer()`
- Deprecate `DATE_RFC7231` and `DateTimeInterface::RFC7231`

## Proposal

Each feature proposed for deprecation is voted separately and requires a 2/3 majority. All votes refer to deprecation in PHP 8.5 and removal in PHP 9 (except where otherwise noted).

### Language/syntax deprecations

#### Deprecate semicolon after case in switch statement

- Author: Theodore Brown <theodorejb@php.net>
- Implementation: <https://github.com/php/php-src/pull/19215>

It is possible to terminate `case` statements with a semicolon instead of the standard colon:

```php
switch ($value) {
    case 'foo';
    case 'bar':
    case 'baz';
        echo 'foo, bar, or baz';
        break;
    default;
        echo 'Other';
}
```

This syntax is a leftover from PHP/FI 2, where nearly all lines including if conditions and case statements were terminated by a semicolon. [1](https://externals.io/message/109350#109363) [2](https://www.php.net/manual/phpfi2.php#lang)

There isn't a need for this syntax to exist anymore, and very few PHP developers are even aware of its existence. In the top 1000 Composer packages, zero out of 35,777 total case statements are using the alternate syntax (as of 2024-11-27). Edit: as of 2025-07-07 there are still zero usages of the alternate syntax even in the top 1500 packages (out of 45,771 total case statements).

Case statements followed by a semicolon can cause confusion, as a developer may think they behave differently in some way from regular case statements (e.g. preventing fallthrough), when they do not.

Therefore, we propose to deprecate terminating case statements with a semicolon. If accepted, the following deprecation message would be encountered:

> Deprecated: Case statements followed by a semicolon (;) are deprecated, use a colon (:) instead

##### Migration

This deprecation can be automatically fixed by PHP-CS-Fixer:

```bash
composer require friendsofphp/php-cs-fixer --dev
vendor/bin/php-cs-fixer fix . --rules=switch_case_semicolon_to_colon
```

**Vote: Deprecate semicolon-terminated case statements?** — Yes: 22 · No: 10 (closed)

#### Deprecate non-standard cast names

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

This supersedes the following inactive RFC [Deprecate Inconsistent Cast Names](https://externals.io/rfc/deprecate-inconsistent-cast-keywords).

We propose to deprecate the following non-standard cast names:

- `(integer)`
- `(boolean)`
- `(double)`
- `(binary)`

This is inline how using non-standard names for built-in types emits a “confusable” warning at compile time, for example:

```php
<?php
 
function foo(integer $x) {
 
}
```

Causes the following warning to be emitted:

> Warning: “integer” will be interpreted as a class name. Did you mean “int”? Write “\\integer” to suppress this warning

For consistency reasons with the rest of the language we propose to deprecate such casts and recommend using the standard ones.

If accepted the following deprecation message would be encountered:

> Deprecated: Non canonical cast (integer\|boolean\|double\|binary) is deprecated, use the (int\|bool\|float\|string) cast instead

**Vote: Deprecate non-standard cast names?** — Yes: 32 · No: 0 (closed)

#### Deprecate attributes applying to multiple class properties/constants

- Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>

Multiple class properties or constants can be declared in a single declaration, e.g.

```php
<?php
 
#[Attribute]
class Test {}
 
class Foo {
    #[Test]
    public $bar, $baz;
 
    #[Test]
    public const BAR = 1, BAZ = 2;
}
```

This can be confusing, because the attributes are added to all of the properties/constants in the declaration, not just the first.

Because of the potential for confusion, when attributes were added to compile-time constants in [attributes-on-constants](https://externals.io/rfc/attributes-on-constants), adding attributes to multiple non-class constants at once was not allowed.

We now propose to deprecate the same confusing behavior for the existing cases of class properties/constants. If accepted the following deprecation message would be encountered:

> Deprecated: Adding attributes to multiple (properties\|class constants) at once is deprecated, apply the attributes to the (properties\|class constants) individually instead

**Vote: Deprecate attributes applying to multiple class properties/constants** — Yes: 5 · No: 19 (closed)

#### Deprecate backticks as an alias for shell\_exec

- Author: Volker Dusch <edorian@php.net>
- Implementation: <https://github.com/php/php-src/pull/19443>

Backticks are a rarely used and somewhat unknown feature of PHP that can cause confusion and hide the need for error handling by not allowing access to exit codes.

- In code review, it's hard to spot the difference between `` ` `` and `'` at a glance.
- JavaScript uses it for template strings, causing confusion between the syntax, even for more senior developers switching between the languages.
- It's not trivial to look up what the operator does.
- Refactoring efforts, even for complex calls, are minimal thanks to `<<<'NOWDOC'`.
- It would eventually free up the backtick operator for future use.
- Simplifies the languages for humans, static analysis and other tooling.
- Hides the need for `escapeshellarg` more than other ways of executing shell code.

Therefore, we propose to deprecate the backtick operator. If accepted, the following deprecation message would be encountered:

> Deprecated: The backtick (&#96;) operator is deprecated, use shell\_exec() instead

**Vote: Deprecate backticks as an alias for shell\_exec?** — Yes: 21 · No: 8 (closed)

#### Deprecate the \_\_sleep() and \_\_wakeup() magic methods

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

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()`.

The last mechanism of `__serialize()` and `__unserialize()` was introduced in PHP 7.4 with the [New custom object serialization mechanism RFC](https://externals.io/rfc/custom_object_serialization) to fix deep issues with the way the `Serializable` interface worked and improve on the usability of the custom serialisation mechanism. The [Serializable interface is in the process of being phased out](https://externals.io/rfc/phase_out_serializable), however no such thing is being done for the initial serialization mechanism of `__sleep()` and `__wakeup()`.

Having multiple serializations methods which can be superseded by newer methods is somewhat confusing and add unnecessary complexity to the language. Because the `__serialize()`/`__unserialize()` mechanism is a straight up improvement over `__sleep()`/`__wakeup()` we propose to deprecate the latter in favour of the former.

If accepted the following compile time deprecation message would be encountered:

```php
Deprecated: Serialization hooks __sleep() and __wakeup() are deprecated, implement __serialize() and __unserialize() in addition
```

**Vote: Deprecate the \_\_sleep() and \_\_wakeup() magic methods?** — Yes: 18 · No: 9 (closed)

#### Deprecate using values null as an array offset and when calling array\_key\_exists()

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

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

How offsets are handled in PHP is rather unintuitive and not consistent with many other areas of the language. Notably, an offset of `null` is type juggled to the empty string `""` rather than the integer `0`. This is in stark contrast with every other type being coerced to an integer when used as an offset, which can be a source of confusion.

This behaviour is also inconsistent with string offsets, where any invalid offset type warns or throws an error instead of being silently coerced.

Finally, this behaviour is also inconsistent with the function type juggling context, where a parameter type of `int|string` would reject values of type `null`. We believe that aligning the behaviour of array offsets with the behaviour of function parameters is important, as objects that implement `ArrayAccess` follow those semantics when overloading the behaviour of `$arrayAccess[$offset]`.

As such we propose deprecating using values of type `null` as array offsets and when calling `array_key_exists()`.

If accepted the following deprecation message would be encountered:

For `null`:

> Deprecated: Using null as an array offset is deprecated, use an empty string instead

**Vote: Deprecate using values null as an array offset and when calling array\_key\_exists()?** — Yes: 25 · No: 3 (closed)

#### Deprecate \_\_debugInfo() returning null

- Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>

Since the `__debugInfo()` magic method was added, it has been documented as needing to return an array (see [original implementation](https://github.com/php/php-src/commit/1e752ce9c57310cced0a5ba8399778c1f500f2b4)) in the error message if you return a non-array and non-null value.

However, `null` has been silently treated the same as an empty array.

This can result in confusion about if null means something different. Accordingly, we propose to deprecate returning null from `__debugInfo()` magic methods.

If accepted the following deprecation message would be encountered:

> Deprecated: Returning null from `__debugInfo()` is deprecated, return an empty array instead

**Vote: Deprecate \_\_debugInfo() returning null?** — Yes: 22 · No: 5 (closed)

#### Deprecate constant redeclaration

- Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>

In PHP 8, attempting to declare a constant that already exists was changed to emit a warning rather than just a notice. Since a warning is considered stronger than a deprecation, the error code should not change, but we propose that

- The behavior trigger an error in PHP 9
- The warning messages in 8.5+ indicate that the behavior will trigger an error in PHP 9

Redeclaring a constant can lead to invalid assumptions, specifically if a developer assumes that the declaration will succeed they may assume a constant has one value when it actually has a different value.

**Vote: Deprecate constant redeclaration?** — Yes: 31 · No: 0 (closed)

#### Deprecate closure binding issues

- Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>

When trying to bind a `Closure` object, multiple issues can potentially be raised, but only as warnings:

- “Cannot bind an instance to a static closure”
- “Cannot bind method %s::%s() to object of class %s” - for trying to change the type of object bound to
- “Cannot unbind $this of method”
- “Cannot unbind $this of closure using $this”
- “Cannot bind closure to scope of internal class %s”
- “Cannot rebind scope of closure created from function”
- “Cannot rebind scope of closure created from method”

Since a warning is considered stronger than a deprecation, the error code should not change, but we propose that

- The behavior trigger errors in PHP 9
- The warning messages in 8.5+ indicate that the behavior will trigger errors in PHP 9

**Vote: Deprecate closure binding issues?** — Yes: 29 · No: 0 (closed)

#### Enact follow-up phase of the "Path to Saner Increment/Decrement operators" RFC

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

The [Path to Saner Increment/Decrement operators](https://externals.io/rfc/saner-inc-dec-operators) RFC delayed the deprecation of the PERL string increment feature so that users could have time to migrate to the new `str_increment()` function introduced in PHP 8.3.

As there have been two minor versions to allow this migration we now proposed to enact the following delayed deprecation from the RFC:

> Deprecate using the increment operator with non-numeric strings.

If accepted the following deprecation message would be encountered:

> Deprecated: Incrementing non-numeric strings is deprecated, use str\_increment() instead

**Vote: Enact follow-up phase of the Path to Saner Increment/Decrement operators RFC?** — Yes: 23 · No: 4 (closed)

### Core INI directive deprecations

#### Deprecate the report\_memleaks INI directive

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

This INI directive allows to suppress ZendMM memory leaks in debug builds of PHP. This “feature” is highly questionable, as memory leaks should be fixed the moment they are made aware of. Because this cannot affect production builds of PHP we propose deprecating this INI setting.

**Vote: Deprecate the report\_memleaks INI directive?** — Yes: 23 · No: 2 (closed)

#### Deprecate the register\_argc\_argv INI directive

- Author: Nicolas Grekas <nicolas.grekas@php.net>
- Implementation: <https://github.com/php/php-src/pull/19473>, <https://github.com/php/php-src/pull/19606>

This INI directive tells PHP whether to declare the argv &amp; argc variables. On the CLI, phpdbg and embed SAPIs it is forced to On. On other SAPIs, it defaults to On in the C code but is set to Off in the default php.ini files. This setting is dangerous on HTTP SAPIs because it allows defining the value of the argv/argc variables from the query string. This is almost always unwanted and certainly unexpected. It can lead to security issues if one reads argv/argc from an HTTP app while not being aware of this behavior.

We propose to deprecate this INI setting and make in default to Off in PHP 8.5, then to hardcode it to Off for all non-CLI-related SAPIs on PHP 9 (while keeping it hardcoded to On for CLI-related ones).

**Vote: Deprecate the register\_argc\_argv INI directive and make in default to Off in PHP 8.5, then hardcode it to Off for all non-CLI-related SAPIs on PHP 9 (while keeping it hardcoded to On for CLI-related ones)?** — Yes: 27 · No: 0 (closed)

#### Remove disable\_classes INI setting

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

This supersedes the following inactive RFC [Remove disable\_classes INI setting](https://externals.io/rfc/remove_disable_classes).

The `disable_classes` INI setting is fundamentally useless and causes various issues in the engine, as using it will result in unexpected states for the engine to deal with.

Only internal classes can be disabled, which brings the following observation. On a minimal build of PHP, with only the mandatory extensions enabled, there are 148 classes/interfaces/traits defined. \[2\]

Other than a specific subset of classes defined in the SPL extension, disabling any of these classes will cause issues within the engine. Moreover, the subset of SPL classes that could be disabled are not a security concern.

Therefore, any other class that can be disabled must come from an extension that can be disabled altogether. And “disabling” a class from an extension without disabling said extension will, other than rendering it useless, cause various issues that the extension is not prepared to handle as they expect the classes they defined to exist.

If a hosting provider is concerned about an extension, then it should not enable it in the first place. Not break it ad hoc.

Considering the above, the usefulness of this feature has always been dubious.

This is in stark contrast to the `disable_functions` INI setting, which can be used to selectively remove functionality of an extension without breaking it overall.

What makes this setting particularly broken is that it does not unregister the class, it only overwrites the create CE handler to emit a warning and purge the properties and function hash tables. This leads to various use after free, segfaults, and broken expectations for the engine and extensions which define said classes. On top of that, it is possible to actually instantiate such a class (and even classes which actually disallow this like `ext/imap`) in userland, and pass it to functions that are typed against said class without raising a TypeError. However, when trying to do anything with said object, stuff is going to explode in countless ways.

The only usage we can find is within the Fuzzer SAPI to block instantiation of the `InfiniteIterator` class so that it does not try to fuzz this class. This can be fixed by manually changing the create handler of the `InfiniteIterator` CE to throw in the fuzzer initiation code.

As such we propose removing the `disable_classes` INI setting.

**Vote: Remove disable\_classes INI setting?** — Yes: 26 · No: 0 (closed)

### ext/reflection deprecations

#### Deprecate Reflection\*::setAccessible()

- Author: Tim Düsterhus <timwolla@php.net>
- Implementation: <https://github.com/php/php-src/pull/19273>

The [“Make reflection setAccessible() no-op” RFC](https://externals.io/rfc/make-reflection-setaccessible-no-op) in PHP 8.1 made the `Reflection*::setAccessible()` methods a noop. However it did not deprecate the methods to simplify cross-version compatibility.

Since PHP 8.0, which is the last version where the methods did anything, is already EOL and PHP 8.1, which introduced the change will be EOL shortly after the release of PHP 8.5, it seems reasonable to deprecate the methods to make users aware that they have no effect (especially for calls to `->setAccessible(false)`) and to encourage users to remove them.

If compatibility with PHP 8.0 or earlier is desired, the deprecation can be suppressed with `@` or alternatively the call to `->setAccessible()` can be guarded by an `if (\PHP_VERSION_ID < 80100)` check.

We therefore propose to add:

```php
#[\Deprecated(since: '8.5', message: "as it has no effect")]
```

to the signature.

**Vote: Deprecate Reflection\*::setAccessible()?** — Yes: 24 · No: 0 (closed)

#### Deprecate ReflectionParameter::allowsNull()

- Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>

With the introduction of `ReflectionParameter::getType()` in PHP 7.0, the preferred way to analyze the type of a parameter is by calling that method and then examining it, e.g. using `ReflectionType::allowsNull()`. However, while most of the methods for examining a parameter type directly from `ReflectionParameter` have been deprecated (`::isArray()`, `::isCallable()`, and `::getClass()`), the `::allowsNull()` method was not.

We propose to deprecate `ReflectionParameter::allowsNull()` in favor of using `ReflectionType::allowsNull()` by adding

```php
#[\Deprecated(since: '8.5', message: "use ReflectionParameter::getType() instead")]
```

to the signature.

**Vote: Deprecate ReflectionParameter::allowsNull()?** — Yes: 9 · No: 10 (closed)

#### Deprecate ReflectionClass::getConstant() for missing constants

- Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>

`ReflectionClass:getConstant()` returns the value of the class constant with a given name, or `false` if no such class constant exists. This behavior is confusing because it makes no distinction between a class constant with the value `false` and one that does not exist:

```php
<?php
 
class Demo {
    public const EXISTS = false;
}
 
$r = new ReflectionClass( Demo::class );
echo "EXISTS: ";
var_dump( $r->getConstant( 'EXISTS' ) ); // false
echo "MISSING: ";
var_dump( $r->getConstant( 'MISSING' ) ); // false
```

Unlike with `ReflectionClass::getReflectionConstant()` (which returns either a `ReflectionClassConstant` or `false` for missing constants) the return value of `ReflectionClass:getConstant()` for a missing constant is also valid for an existing constant with the value `false`. This can result in confusion, and if the value is `false`, a call to `ReflectionClass::hasConstant()` to check if the constant exists or not. We propose that, if a constant with the given name does not exist, deprecation warnings be emitted (in PHP 8.5, becoming an exception in PHP 9.0).

If accepted the following deprecation message would be encountered:

> Deprecated: ReflectionClass::getConstant() for a non-existent constant is deprecated, use ReflectionClass::hasConstant() to check if the constant exists

**Vote: Deprecate ReflectionClass::getConstant() for missing constants?** — Yes: 25 · No: 0 (closed)

#### Deprecate ReflectionProperty::getDefaultValue() for properties without default values

- Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>

`ReflectionProperty::getDefaultValue()` returns the default value of a property, or `null` if the property has no default. This behavior is confusing because it makes no distinction between a property with the default value `null` and one that has no default value:

```php
<?php
 
class Demo {
    public $hasDefault = null;
    public $noDefault;
}
 
$r1 = new ReflectionProperty( Demo::class, 'hasDefault' );
echo "HAS DEFAULT: ";
var_dump( $r1->getDefaultValue() ); // null
 
$r2 = new ReflectionProperty( Demo::class, 'noDefault' );
echo "NO DEFAULT: ";
var_dump( $r2->getDefaultValue() ); // null
```

The return value of `ReflectionProperty::getDefaultValue()` for a property without a default is also valid for a property with the default value of `null`. This can result in confusion, and if the value is `null`, a call to `ReflectionProperty::hasDefaultValue()` to check if the default exists or not. We propose that, if a property does not have a default value, deprecation warnings be emitted (in PHP 8.5, becoming an exception in PHP 9.0).

If accepted the following deprecation message would be encountered:

> Deprecated: ReflectionProperty::getDefaultValue() for a property without a default value is deprecated, use ReflectionProperty::hasDefaultValue() to check if the default value exists

**Vote: Deprecate ReflectionProperty::getDefaultValue() for properties without default values?** — Yes: 22 · No: 2 (closed)

### ext/spl deprecations

#### Deprecate ArrayObject and ArrayIterator with objects

- Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>
- Author: Gina Peter Banyard <girgias@php.net>

`ArrayObject` allows using an instance of a class as a “backing array” rather than the more typical behaviour of using a standard PHP array.

However the way this feature was designed breaks nearly every single expectation and invariant around objects not just for users, but also the engine.

It allows accessing private and protected properties from the global scope, writing multiple times to `readonly` properties, writing values of invalid types to typed properties, mishandles `isset()` and `empty()`, allows writing dynamic properties without issuing any warning , can even add dynamic properties to internal classes that ban dynamic properties, doesn't call the magic `__get()` and `__set()` methods, and probably some other hidden issues.

One example to showcase some of the issues is the following:

```php
<?php
class T {
    private readonly int $p;
    public string $p2;
 
    public function getP() {
        return $this->p;
    }
}
 
$o = new T();
$a = new ArrayObject($o);
$a["\0T\0p"] = 'str';
var_dump($o->getP());
$a["\0T\0p"] = 'modified';
var_dump($o->getP());
var_dump(isset($a["p2"]));
var_dump($o->p2);
```

which outputs the following:

```php
string(3) "str"
string(8) "modified"
bool(true)
 
Fatal error: Uncaught Error: Typed property T::$p2 must not be accessed before initialization in php-wasm run script:%d
Stack trace:
#0 {main}
  thrown in php-wasm run script on line %d
```

This feature can change `readonly` properties of internal classes, some which the engine does not expect to ever change.

For example, `Enum::$name` and `Enum::$value`. This can break internal logic assumptions (e.g. hard-coded switch cases to handle internal enums by name) and cause memory corruption. The same goes for non-readonly properties guarded with the internal equivalent of `__set()`.

As such we recommend deprecating passing an object to the constructor of `ArrayObject`. Because `ArrayIterator` shares a lot of the implementation details with `ArrayObject`we also recommend deprecating passing objects to it.

If accepted the following deprecation message would be encountered:

> Deprecated: Using an object as a backing array for ArrayObject is deprecated, as it allows violating class constraints and invariants

**Vote: Deprecate ArrayObject and ArrayIterator with objects?** — Yes: 26 · No: 0 (closed)

#### Deprecate SplObjectStorage::contains(), SplObjectStorage::attach(), and SplObjectStorage::detach()

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

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

The following three methods are aliases for methods defined by `ArrayAccess`, namely:

- `SplObjectStorage::contains()` is an alias for `SplObjectStorage::offsetExists()`
- `SplObjectStorage::attach()` is an alias for `SplObjectStorage::offsetSet()`
- `SplObjectStorage::detach()` is an alias for `SplObjectStorage::offsetUnset()`

However, extending `SplObjectStorage` and overwriting one of the alias methods does *not* modify the behaviour of using the offset access operators. Meaning that it is possible to have an asymmetry between using methods calls and the overloaded offset access operators.

As such we propose deprecating the method aliases in favour of using the `ArrayAccess` methods.

If accepted the following attributes will be added to the respective methods:

```php
#[\Deprecated(since: '8.5', message: "use method SplObjectStorage::offset{Exists|Set|Unset}() instead")]
```

**Vote: Deprecate SplObjectStorage::contains(), SplObjectStorage::attach(), and SplObjectStorage::detach()?** — Yes: 17 · No: 2 (closed)

#### Deprecate passing spl\_autoload\_call() to spl\_autoload\_unregister()

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

The `spl_autoload_register()` function allows registering a callable to find classes during autoloading. Naturally it prevents passing the `spl_autoload_call()` as a callback, as this would be nonsensical.

However, the `spl_autoload_unregister()` function, which is used to remove a callback from the autoloading sequence does permit passing the `spl_autoload_call()` function as a callback, in which case ***all*** autoloading callbacks are removed.

This behaviour is undocumented and frankly baffling, as such we propose to deprecate passing `spl_autoload_call()` to `spl_autoload_unregister()`.

If there is a need to remove all autoloading functions it is possible to do so via the following obvious method:

```php
foreach (spl_autoload_functions() as $fn) {
    spl_autoload_unregister($fn);
}
```

If accepted the following deprecation message would be encountered:

> Deprecated: Using spl\_autoload\_call() as a callback for spl\_autoload\_unregister() is deprecated, to remove all registered autoloaders, call spl\_autoload\_unregister() for all values returned from spl\_autoload\_functions()

**Vote: Deprecate passing spl\_autoload\_call() to spl\_autoload\_unregister()?** — Yes: 23 · No: 0 (closed)

### ext/standard deprecations

#### Deprecate non-canonical type names for settype()

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

The `settype()` function allows doing an “in-place” type cast of a variable by taking the name of the type to convert the variable to as the second parameter. It accepts the following non-canonical type names

- `integer` for `int`
- `boolean` for `bool`
- `double` for `float`

Similarly to the proposal to deprecate non standard cast names, we propose to deprecate those in favour of the canonical names.

If accepted the following deprecation message would be encountered:

> Deprecated: Non canonical type name “integer\|boolean\|double” is deprecated, use “int\|bool\|float” instead

**Vote: Deprecate non-canonical type names for settype()?** — Yes: 8 · No: 10 (closed)

#### Deprecate the $exclude\_disabled parameter of get\_defined\_functions()

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

As of PHP 8.0.0, functions that are disabled via the `disable_functions` INI setting are simply removed from the function table. As such, this parameter no longer has any effect and is pointless. Therefore, we propose to deprecate it.

If accepted the following deprecation message would be encountered:

> Deprecated: The $exclude\_disabled parameter has no effect since PHP 8.0

**Vote: Deprecate the $exclude\_disabled parameter of get\_defined\_functions()?** — Yes: 23 · No: 0 (closed)

#### Deprecate passing null to readdir(), rewinddir(), and closedir()

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

The `readdir()`, `rewinddir()`, and `closedir()` functions accept `null` as the value for the `$dir_handle`, in which case it will used the previously opened directory stream opened with `opendir()`.

This is global state that can change if another call to `opendir()` is made, which could happen by calling a library function, leading to spooky action at a distance. Prior extensions and functions that behaved this way have been deprecated, most notably the original ext/mysql extension and more recently [the ext/pgsql functions that were overloaded were deprecated in PHP 8.1](https://externals.io/rfc/deprecations_php_8_1#calling_overloaded_pgsql_functions_without_the_connection_argument)

As such, we propose deprecating passing `null` to `readdir()`, `rewinddir()`, and `closedir()`.

If accepted the following deprecation message would be encountered:

> Deprecated: Passing null to {read\|rewind\|close}dir() is deprecated, instead the last opened directory stream should be provided

**Vote: Deprecate passing null to readdir(), rewinddir(), and closedir()?** — Yes: 24 · No: 3 (closed)

#### Deprecate passing string which are not one byte long to ord()

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

The `ord()` function accepts the empty string (in which case it uses the null byte that terminates the C string and returns 0) and strings longer than one byte (in which case it returns the value of the first byte).

Both of these cases indicate some sort of programming bug, as such we propose deprecating this behaviour.

If accepted the following deprecation message would be encountered:

> Deprecated: Providing a string which is not one byte long is deprecated, use $str\[0\] instead

**Vote: Deprecate passing string which are not one byte long to ord()?** — Yes: 20 · No: 4 (closed)

#### Deprecate passing integers outside the interval \[0, 255\] to chr()

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

The `chr()` function accepts any possible integer value and for values outside the range \[0, 255\] it will take the value of the integer mod 256.

As this case indicate some sort of programming bug, we propose deprecating this behaviour.

If accepted the following deprecation message would be encountered:

> Deprecated: Providing a value not in-between 0 and 255 is deprecated, use value % 256 to constrain it to the correct interval

**Vote: Deprecate passing integers outside the interval \[0, 255\] to chr()?** — Yes: 21 · No: 1 (closed)

#### Formally deprecate socket\_set\_timeout

- Author: Tim Düsterhus <timwolla@php.net>
- Implementation: <https://github.com/php/php-src/pull/19285>

`socket_set_timeout()` is an alias of `stream_set_timeout()` and already marked as deprecated in the documentation (“This function was previously called as set\_socket\_timeout() and later socket\_set\_timeout() but this usage is deprecated.”). Its name is misleading since it not part of the ext/sockets extension, which uses the `socket_x()` prefix.

We therefore propose to add:

```php
#[\Deprecated(since: '8.5', message: "use stream_set_timeout() instead")]
```

to the signature.

**Vote: Formally deprecate socket\_set\_timeout?** — Yes: 22 · No: 0 (closed)

#### Deprecate the $http\_response\_header predefined variable

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

This was initially slated for [deprecation in PHP 8.1](https://externals.io/rfc/deprecations_php_8_1#predefined_variable_http_response_header), however it was removed from the proposal as there were no practical alternatives for this functionality.

This was addressed in PHP 8.4 by adding the [http\_get\_last\_response\_headers() function](https://externals.io/rfc/http-last-response-headers). As the usage of this predefined variable is small, at the time of the RFC introducing the new functions, 65 times. And it is possible to write cross version compatible code in the following way:

```php
$content = file_get_contents('http://example.com/');
if (function_exists('http_get_last_response_headers')) {
    $http_response_header = http_get_last_response_headers();
}
// Use $http_response_header as before
```

We propose deprecating using the `$http_response_header` without having previously called `http_get_last_response_headers()`

If accepted the following deprecation message would be encountered:

> Deprecated: The predefined locally scoped $http\_response\_header variable is deprecated, call http\_get\_last\_response\_headers() instead

**Vote: Deprecate the $http\_response\_header predefined variable?** — Yes: 22 · No: 2 (closed)

### ext/filter deprecations

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

#### Deprecate FILTER\_DEFAULT constant

The `FILTER_DEFAULT` constant is an alias for the `FILTER_UNSAFE_RAW` constant. This has been the case since at least PHP 5.3. This is confusing and seems to indicate that it corresponds to the filter set by the `filter.default` INI setting. Moreover, this INI setting was deprecated in [PHP 8.1](https://externals.io/rfc/deprecations_php_8_1#filterdefault_ini_setting).

As this constant is confusing and misleading, we propose to deprecate it.

If accepted we propose to add:

```php
#[\Deprecated(since: '8.5', message: "use FILTER_UNSAFE_RAW instead")]
```

to the constant declaration.

**Vote: Deprecate FILTER\_DEFAULT constant?** — Yes: 12 · No: 10 (closed)

#### Make $filter parameter mandatory for filter\_\*() functions

The `filter_*()` functions do not require passing the `$filter` parameter, the default value of it is `FILTER_DEFAULT` which is an alias for the `FILTER_UNSAFE_RAW` filter. This filter does **nothing** if no flags are provided. This behaviour is indicative of a bug, therefore, we propose to make the `$filter` argument mandatory and emit a deprecation notice if the default value is used.

If accepted the following deprecation message would be encountered:

> Deprecated: Relying on the default filter is deprecated, explicitly provide a filter to be used

**Vote: Emit a deprecation notice when using the default value for the $filter argument of the filter\_\*() functions?** — Yes: 9 · No: 10 (closed)

### ext/odbc deprecations

\* Author: Calvin Buckley <calvinb@php.net>

#### Remove flags for building against specific drivers directly

On Unix, procedural ODBC supports building against drivers directly, instead of using a driver manager like iODBC or unixODBC. (On Windows, the system driver manager is always used.) While the linker and compiler flags to use one (or some other driver manager, since the ODBC interface is identical) manually can be specified, the build system supports many drivers built-in. However, I suspect many of these drivers are not in use anymore, or very popular. In addition, even if they are, it would be better to encourage using them through a driver manager instead of linking directly to them. The driver manager can handle things like ODBC version expectation mismatches or compatibility issues. If a driver must be used directly (i.e. some niche embedded case), it isn't hard to pass the flags directly.

I have a [GitHub issue tracking this](https://github.com/php/php-src/issues/15630), looking into each driver. I believe the only special case is DB2; Zend historically shipped the ODBC extensions linked against the DB2 SQL/CLI library for their IBM i version of Zend Server. However, in my experience working with IBM i Zend Sever users, I suspect most IBM i users are using the ibm\_db2 extension or unixODBC with the newer DB2 ODBC driver, so I don't think this would have much impact.

If accepted, PHP 8.5 would no longer have the build system flags or ifdefs in extension code for these drivers specifically; as previously mentioned, users can still build against them directly by passing the build flags for a driver manually. This should drastically cut down the size of the build system for the extension. If DB2 is included, this can also affect PDO\_ODBC as well. Doing so would drastically simplify the build system for ext/odbc. I also have a [draft PR](https://github.com/php/php-src/pull/15727) for this.

**Vote: Deprecate special build system support for drivers without a driver manager?** — Yes: 16 · No: 0 (closed)

#### Remove support for older ODBC versions

It may be prudent to discontinue support for old ODBC versions. The latest unixODBC and iODBC are at 3.5.1, and latest Windows at 3.8. ODBC 3.5 itself is from 1997, and 3.8 from 2009. If a driver is stuck at an older ODBC version, the driver manager can handle bridging the gap between them; see the above RFC on encouraging use of driver managers instead.

This is inspired by [Christoph's PR](https://github.com/php/php-src/pull/17556) to use newer ODBC functions instead of deprecated ones; this would go a step further and remove the ifdefs, as well as many ODBCVER checks. Assuming a modern ODBC would allow us to use those replacements without worry.

If accepted, PHP 8.5 would assume a modern version of ODBC, removing the build system --with-odbcver flag, and most of the ifdefs with it.

**Vote: Deprecate ODBCVER checks?** — Yes: 15 · No: 0 (closed)

### ext/pdo deprecations

#### Deprecate PDO's 'uri:' scheme

- Author: Tim Düsterhus <timwolla@php.net>
- Implementation: <https://github.com/php/php-src/pull/19274>

PDO supports a `uri:` DSN scheme that does not refer to a database driver named “uri” but instead is an indication to read the actual DSN from the specified URI, including remote stream wrappers, such as HTTP URIs.

While this feature might appear to be useful to make it easier for environment-specific configuration of an application, the username and password notably are not part of the DSN, which would require a separate configuration mechanism and which point the actual DSN could use it as well. Similarly authentication via TLS certificates with the MySQL driver would require specifying the certificate and private key as the `$options`.

In case of remote stream wrappers, the feature can be actively dangerous, unless the URL referenced is 100% trustworthy, since the username and password for the database might be sent to an untrusted database servers. In case of the SQLite PDO driver, a remote URL might enable access to arbitrary SQLite files on the server. Furthermore remote stream wrappers might result in performance-bottlenecks, since the file is requested for every single connection.

If this feature is somehow exactly what is desired, it can easily replicated in userland as follows (while preserving the main semantics of only looking at the first line):

```php
$dsn = '…';
if (str_starts_with($uri, 'uri:')) {
    if (($f = fopen(substr($uri, strlen('uri:')), 'rb'))) {
        $dsn = fgets($f, 512);
        fclose($f);
    } else {
        // Emit error message
    }
}
```

If accepted the following deprecation message would be encountered:

> Deprecated: Looking up the DSN from a URI is deprecated due to possible security concerns with DSNs coming from remote URIs

**Vote: Deprecate PDO’s uri: scheme?** — Yes: 22 · No: 0 (closed)

#### Deprecate PDO::ERRMODE\_WARNING error mode

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

PDO can be set to report errors in 3 different ways:

- `PDO::ERRMODE_SILENT`
- `PDO::ERRMODE_WARNING`
- `PDO::ERRMODE_EXCEPTION`

In silent mode, PDO will proceed if an error has occured within a PDO statement or PDO instance, and set the error code and info so that it can be queried manually. This allows for a more hands on approach to error handling.

In exception mode, PDO will instead throw a `PDOException` whenever an error occurs, and unwind the stack unless it the exception is caught via a `catch` block. This is a more of a hands off approach as error handling doesn't need to be done after each method call of a PDO or PDO statement instance. This mode has been the default since PHP 8.0.

In warning mode, PDO will behave similarly as if set in silent mode, but also raise an `E_WARNING` similarly to how the exception mode behaves. As such this mode is a bit non-sensical as it is both a hands on and hands off approach to error handling. Moreover, an `E_WARNING` may be promoted to an exception via an error handler set via `set_error_handler()`, something that might not be expected by code written with `PDO::ERRMODE_SILENT` in mind.

As such we propose to deprecate the `PDO::ERRMODE_WARNING` constant and recommend users either use the silent or exception mode.

If accepted we propose to add:

```php
#[\Deprecated(since: '8.5', message: "use PDO::ERRMODE_SILENT or PDO::ERRMODE_EXCEPTION instead")]
```

to the constant declaration.

**Vote: Deprecate PDO::ERRMODE\_WARNING constant?** — Yes: 8 · No: 12 (closed)

#### Deprecate driver specific PDO constants and methods

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

With the acceptance and merging of the [PDO driver specific sub-classes](https://externals.io/rfc/pdo_driver_specific_subclasses) RFC, the recommended way to provide driver specific functionality is by creating a subclass of PDO with said functionality. As such we propose deprecating the overloaded PDO constants which are declared using the `REGISTER_PDO_CLASS_CONST_LONG` macros and the overloaded PDO methods which are defined in the `pgsql_driver.stub.php` and `sqlite_driver.stub.php` files.

This means the following PDO constants would be deprecated in favour of:

- `PDO::DBLIB_ATTR_CONNECTION_TIMEOUT` =&gt; `Pdo\Dblib::ATTR_CONNECTION_TIMEOUT`
- `PDO::DBLIB_ATTR_QUERY_TIMEOUT` =&gt; `Pdo\Dblib::ATTR_QUERY_TIMEOUT`
- `PDO::DBLIB_ATTR_STRINGIFY_UNIQUEIDENTIFIER` =&gt; `Pdo\Dblib::ATTR_STRINGIFY_UNIQUEIDENTIFIER`
- `PDO::DBLIB_ATTR_VERSION` =&gt; `Pdo\Dblib::ATTR_VERSION`
- `PDO::DBLIB_ATTR_TDS_VERSION` =&gt; `Pdo\Dblib::ATTR_TDS_VERSION`
- `PDO::DBLIB_ATTR_SKIP_EMPTY_ROWSETS` =&gt; `Pdo\Dblib::ATTR_SKIP_EMPTY_ROWSETS`
- `PDO::DBLIB_ATTR_DATETIME_CONVERT` =&gt; `Pdo\Dblib::ATTR_DATETIME_CONVERT`
- `PDO::FB_ATTR_DATE_FORMAT` =&gt; `Pdo\Firebird::ATTR_DATE_FORMAT`
- `PDO::FB_ATTR_TIME_FORMAT` =&gt; `Pdo\Firebird::ATTR_TIME_FORMAT`
- `PDO::FB_ATTR_TIMESTAMP_FORMAT` =&gt; `Pdo\Firebird::ATTR_TIMESTAMP_FORMAT`
- `PDO::MYSQL_ATTR_USE_BUFFERED_QUERY` =&gt; `Pdo\Mysql::ATTR_USE_BUFFERED_QUERY`
- `PDO::MYSQL_ATTR_LOCAL_INFILE` =&gt; `Pdo\Mysql::ATTR_LOCAL_INFILE`
- `PDO::MYSQL_ATTR_LOCAL_INFILE_DIRECTORY` =&gt; `Pdo\Mysql::ATTR_LOCAL_INFILE_DIRECTORY`
- `PDO::MYSQL_ATTR_INIT_COMMAND` =&gt; `Pdo\Mysql::ATTR_INIT_COMMAND`
- `PDO::MYSQL_ATTR_MAX_BUFFER_SIZE` =&gt; `Pdo\Mysql::ATTR_MAX_BUFFER_SIZE`
- `PDO::MYSQL_ATTR_READ_DEFAULT_FILE` =&gt; `Pdo\Mysql::ATTR_READ_DEFAULT_FILE`
- `PDO::MYSQL_ATTR_READ_DEFAULT_GROUP` =&gt; `Pdo\Mysql::ATTR_READ_DEFAULT_GROUP`
- `PDO::MYSQL_ATTR_COMPRESS` =&gt; `Pdo\Mysql::ATTR_COMPRESS`
- `PDO::MYSQL_ATTR_DIRECT_QUERY` =&gt; `Pdo\Mysql::ATTR_DIRECT_QUERY`
- `PDO::MYSQL_ATTR_FOUND_ROWS` =&gt; `Pdo\Mysql::ATTR_FOUND_ROWS`
- `PDO::MYSQL_ATTR_IGNORE_SPACE` =&gt; `Pdo\Mysql::ATTR_IGNORE_SPACE`
- `PDO::MYSQL_ATTR_SSL_KEY` =&gt; `Pdo\Mysql::ATTR_SSL_KEY`
- `PDO::MYSQL_ATTR_SSL_CERT` =&gt; `Pdo\Mysql::ATTR_SSL_CERT`
- `PDO::MYSQL_ATTR_SSL_CA` =&gt; `Pdo\Mysql::ATTR_SSL_CA`
- `PDO::MYSQL_ATTR_SSL_CAPATH` =&gt; `Pdo\Mysql::ATTR_SSL_CAPATH`
- `PDO::MYSQL_ATTR_SSL_CIPHER` =&gt; `Pdo\Mysql::ATTR_SSL_CIPHER`
- `PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT` =&gt; `Pdo\Mysql::ATTR_SSL_VERIFY_SERVER_CERT`
- `PDO::MYSQL_ATTR_SERVER_PUBLIC_KEY` =&gt; `Pdo\Mysql::ATTR_SERVER_PUBLIC_KEY`
- `PDO::MYSQL_ATTR_MULTI_STATEMENTS` =&gt; `Pdo\Mysql::ATTR_MULTI_STATEMENTS`
- `PDO::ODBC_ATTR_USE_CURSOR_LIBRARY` =&gt; `Pdo\Odbc::ATTR_USE_CURSOR_LIBRARY`
- `PDO::ODBC_ATTR_ASSUME_UTF8` =&gt; `Pdo\Odbc::ATTR_ASSUME_UTF8`
- `PDO::ODBC_SQL_USE_IF_NEEDED` =&gt; `Pdo\Odbc::SQL_USE_IF_NEEDED`
- `PDO::ODBC_SQL_USE_DRIVER` =&gt; `Pdo\Odbc::SQL_USE_DRIVER`
- `PDO::ODBC_SQL_USE_ODBC` =&gt; `Pdo\Odbc::SQL_USE_ODBC`
- `PDO::PGSQL_ATTR_DISABLE_PREPARES` =&gt; `Pdo\Pgsql::ATTR_DISABLE_PREPARES`
- `PDO::SQLITE_ATTR_EXTENDED_RESULT_CODES` =&gt; `Pdo\Sqlite::ATTR_EXTENDED_RESULT_CODES`
- `PDO::SQLITE_ATTR_OPEN_FLAGS` =&gt; `Pdo\Sqlite::OPEN_FLAGS`
- `PDO::SQLITE_ATTR_READONLY_STATEMENT` =&gt; `Pdo\Sqlite::ATTR_READONLY_STATEMENT`
- `PDO::SQLITE_DETERMINISTIC` =&gt; `Pdo\Sqlite::DETERMINISTIC`
- `PDO::SQLITE_OPEN_READONLY` =&gt; `Pdo\Sqlite::OPEN_READONLY`
- `PDO::SQLITE_OPEN_READWRITE` =&gt; `Pdo\Sqlite::OPEN_READWRITE`
- `PDO::SQLITE_OPEN_CREATE` =&gt; `Pdo\Sqlite::OPEN_CREATE`

And the following overloaded PDO methods would be deprecated:

- `PDO::pgsqlCopyFromArray()` =&gt; `Pdo\Pgsql::copyFromArray()`
- `PDO::pgsqlCopyFromFile()` =&gt; `Pdo\Pgsql::copyFromFile()`
- `PDO::pgsqlCopyToArray()` =&gt; `Pdo\Pgsql::copyToArray()`
- `PDO::pgsqlCopyToFile()` =&gt; `Pdo\Pgsql::copyToFile()`
- `PDO::pgsqlGetNotify()` =&gt; `Pdo\Pgsql::getNotify()`
- `PDO::pgsqlGetPid()` =&gt; `Pdo\Pgsql::getPid()`
- `PDO::pgsqlLOBCreate()` =&gt; `Pdo\Pgsql::lobCreate()`
- `PDO::pgsqlLOBOpen()` =&gt; `Pdo\Pgsql::lobOpen()`
- `PDO::pgsqlLOBUnlink()` =&gt; `Pdo\Pgsql::lobUnlink()`
- `PDO::sqliteCreateAggregate()` =&gt; `Pdo\Sqlite::createAggregate()`
- `PDO::sqliteCreateCollation()` =&gt; `Pdo\Sqlite::createCollation()`
- `PDO::sqliteCreateFunction()` =&gt; `Pdo\Sqlite::createFunction()`

If accepted we propose to add:

```php
#[\Deprecated(since: '8.5', message: "use X instead")]
```

to each of the above symbols where `X` corresponds to the relevant PDO subclass constant/method.

**Vote: Deprecate driver specific PDO constants and methods?** — Yes: 17 · No: 6 (closed)

#### Deprecate Pdo\\Pgsql constants related to statement transaction state

- Author: David Carlier <devnexen@gmail.com>

The following constants

- `PDO::PGSQL_TRANSACTION_IDLE`
- `PDO::PGSQL_TRANSACTION_ACTIVE`
- `PDO::PGSQL_TRANSACTION_INTRANS`
- `PDO::PGSQL_TRANSACTION_INERROR`
- `PDO::PGSQL_TRANSACTION_UNKNOWN`
- `Pdo\Pgsql::TRANSACTION_IDLE`
- `Pdo\Pgsql::TRANSACTION_ACTIVE`
- `Pdo\Pgsql::TRANSACTION_INTRANS`
- `Pdo\Pgsql::TRANSACTION_INERROR`
- `Pdo\Pgsql::TRANSACTION_UNKNOWN`

seem to have been an attempt to equalize, feature-wise, the pgsql and pdo/pgsql extensions. While it makes perfect sense for the former, it can't be usable in the latter in any way since it never returns the precise statement transaction state to the user code. Internally, the extension only checks if the transaction is stale or not but those constants are completely irrelevant in this context. Therefore, we propose to start deprecating them starting from 8.5 then remove them in the next major release.

If accepted we propose to add:

```php
#[\Deprecated(since: '8.5', message: "as it has no effect")]
```

to each of the above constant declarations.

**Vote: Deprecate statement transaction state specific PDO constants?** — Yes: 17 · No: 0 (closed)

### Deprecate no-op functions from the resource to object conversion

- Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>

In the migration of various extensions from resources to objects, a number of functions to close or free the resources became no-ops. Specifically:

- `finfo_close()` since the ext/fileinfo migration in PHP 8.1
- `xml_parser_free()` since the ext/xml migration in PHP 8.0
- `curl_close()` since the ext/curl migration in PHP 8.0
- `curl_share_close()` since the ext/curl migration in PHP 8.0
- `imagedestroy()` since the ext/gd migration in PHP 8.0

Since these functions are not needed anymore, they should be deprecated. We therefore propose to add

```php
#[\Deprecated(since: '8.5', message: "as it has no effect since PHP 8.{0|1}")]
```

to the signatures.

#### Deprecate finfo\_close()

- Implementation: <https://github.com/php/php-src/pull/18396>

**Vote: Deprecate finfo\_close()?** — Yes: 24 · No: 2 (closed)

#### Deprecate xml\_parser\_free()

**Vote: Deprecate xml\_parser\_free()?** — Yes: 22 · No: 2 (closed)

#### Deprecate curl\_close()

**Vote: Deprecate curl\_close()?** — Yes: 23 · No: 3 (closed)

#### Deprecate curl\_share\_close()

**Vote: Deprecate curl\_share\_close()?** — Yes: 23 · No: 3 (closed)

#### Deprecate imagedestroy()

**Vote: Deprecate imagedestroy()?** — Yes: 23 · No: 2 (closed)

### Deprecate key\_length parameter of openssl\_pkey\_derive()

- Author: Jakub Zelenka <bukka@php.net>

The key\_length parameter is supposed to attempt to set the length of derived secret. However in reality it is completely ignored if the size is higher than the size of key prime. It has effect only if the size is lower that the size of the prime. In such case, the key is truncated for ECDH and the derivation fails for DH.

The idea is to deprecate this parameter so users do not get false sense of security when providing higher number than the size of prime.

This issue was raised during the security audit.

The caution notes has been added in <https://github.com/php/doc-en/pull/3789> .

**Vote: Deprecate key\_length parameter of openssl\_pkey\_derive()?** — Yes: 24 · No: 0 (closed)

### Deprecate intl.error\_level INI setting

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

Error handling within the Intl extension is handled by two ini settings:

- The `intl.use_exceptions` INI setting determines if errors are reported by throwing an `IntlException`
- The `intl.error_level` INI setting allows to set which type of error level should be used, typically one of the `E_*` error constants.

Moreover, it is possible to enable both exceptions and use a non-zero error level, in which case the error is emitted first. This means that it can be “caught” via an error handler set with `set_error_handler()` first and be promoted to an exception different than `IntlException`.

More concerningly, the error level could be set to `E_ERROR` which would trigger a bailout of the PHP VM. PHP's bailout mechanism is generaly reserved for severe engine failures, such as being unable to allocate memory.

There are multiple issues with bailouts which are described in detail in the ["Issues with fatal errors" section of the Exceptions in the engine (for PHP 7)](https://externals.io/rfc/engine_exceptions_for_php7#issues_with_fatal_errors) RFC. Some of them are:

- `finally` blocks are not executed
- Destructors are not executed
- Memory may not be freed

As this INI setting has some of the same pitfalls as the `PDO::ERRMODE_WARNING` constant and can cause bailouts, we propose deprecating this INI setting, meaning setting it to any value different than `0` will raise an `E_DEPRECATED` diagnostic.

If accepted the following deprecation message would be encountered:

> Deprecated: The intl.error\_level INI setting is deprecated, instead the intl.use\_exceptions INI setting should be enabled to throw exceptions on errors or the intl\_get\_error\_code()/intl\_get\_error\_message() should be used to manually deal with errors

**Vote: Deprecate intl.error\_level INI setting?** — Yes: 22 · No: 0 (closed)

### Formally deprecate mysqli\_execute()

- Author: Tim Düsterhus <timwolla@php.net>
- Implementation: <https://github.com/php/php-src/pull/19286>

`mysqli_execute()` is an alias of `mysqli_stmt_execute()` and already marked as deprecated in the documentation (“mysqli\_execute() is deprecated and will be removed.”). Its name is misleading since it operates on an `mysqli_stmt` object, rather than an `mysqli` object, leading to possible confusion with the `mysqli_execute_query()` function added in PHP 8.2 that *does* operate on an `mysqli` object.

We therefore propose to add:

```php
#[\Deprecated(since: '8.5', message: "use mysqli_stmt_execute() instead")]
```

to the signature.

**Vote: Formally deprecate mysqli\_execute?** — Yes: 22 · No: 0 (closed)

### Deprecate building ext/ldap against Oracle LDAP

- Author: Christoph M. Becker <cmb@php.net>

Building ext/ldap against Oracle LDAP had been supported, and is theoretically still supported, but is apparently [broken for a while](https://github.com/php/php-src/issues/15051). The Oracle LDAP implementation is part of Oracle Instant Client, and uses an older LDAP API; apparently, there are no plans for updating this. So users are almost certainly better off to build against OpenLDAP (and if they need OCI8, to build that as shared library, and load after ext/ldap).

Therefore we supposed to deprecate building ext/ldap against Oracle LDAP.

It should be noted that the `ldap_connect_wallet()` function, [available only as of PHP 8.3](https://externals.io/rfc/deprecate_functions_with_overloaded_signatures#ldap_connect), would also be part of the deprecation, as well as other existing Oracle LDAP specific features.

**Vote: Deprecate building ext/ldap against Oracle LDAP?** — Yes: 19 · No: 0 (closed)

### Deprecate the $context parameter for finfo\_buffer()

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

This parameter is unused, and the only reason it exists in the first place is because the implementation of it was delegated to a “god” C function that also was handling `finfo_file()` which does use the provided context.

As this parameter is not useful for this function it should be deprecated.

If accepted the following deprecation message would be encountered:

> Deprecated: The $context parameter has no effect for finfo\_buffer()

**Vote: Deprecate the $context parameter for finfo\_buffer()?** — Yes: 24 · No: 0 (closed)

### Deprecate DATE\_RFC7231 and DateTimeInterface::RFC7231

- Author: Jorg Sowa <jorg.sowa@gmail.com>

Because the implementation of the constant contains the timezone `GMT` designation, the format of date will always show the `GMT` timezone, despite the real timezone of the instance of `DateTimeInterface`. This may lead to unwanted results.

The implementation of this constant was a mistake, as this was described as bug. This wasn't bug, but a feature request: <https://github.com/php/php-src/pull/2450>

Implementation: <https://github.com/php/php-src/pull/12989>

**Vote: Deprecate DATE\_RFC7231 and DateTimeInterface::RFC7231?** — Yes: 22 · No: 0 (closed)

## Backward Incompatible Changes

For PHP 8.5 additional deprecation notices will be emitted. The actual removal of the affected functionality will happen no earlier than PHP 9.

## Removed from this proposal

The following entries were originally added to this proposal and then dropped.

### Deprecate \_\_construct() and \_\_destruct() in interfaces

- Authors: 
    - Gina Peter Banyard <girgias@php.net>
    - Tim Düsterhus <timwolla@php.net>

In PHP the `__construct()` magic methods is exempt from LSP compatibility obligations, unless the class implements an interface that declares a `__construct()` method.

However, the `__construct()` should never be called manually unless when calling `parent::__construct()`as it is tied to the the `new` keyword when instantiating a new class. As the instantiation of a class is *dependent* on which class is being instantiated, restricting how it can be done by enforcing a specific signature for `__construct()` is ill-advised.

Similarly, requiring a class to implement a `__destruct()` is nonsensical as this should never be called manually and a class might not even need one.

As such we propose deprecating specifying the `__construct()` and `__destruct()` in interfaces.

### Deprecate the docref\_root and docref\_ext INI directives

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

Both of these INI settings allow overriding the output of HTML diagnostic errors (warning, notice, deprecations, etc.) to change the base URL and file extension for the clickable links pointing to functions and/or INI settings in error messages generated by calls to `php_error_docref()`.

This is a debug feature and had some value when the php.net documentation had mirrors, considering those have been retired, their use is now limited.

As such, we propose deprecating those two INI settings.

### Deprecate the error\_prepend\_string and error\_append\_string INI directives

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

Both of these INI settings allow overriding the output of HTML diagnostic errors (warning, notice, deprecations, etc.) to prepend or append HTML before the generated HTML of these diagnostic errors.

This is a development and debugging feature which seems somewhat questionable and of limited use.

As such, we propose deprecating those two INI settings.

### Deprecate FILTER\_CALLBACK filter

The `FILTER_CALLBACK` filter allows providing a function to call on the value to filter. This makes little sense as one can pass the value to filter directly to the function instead of passing by the filter extension.

Similarly, to filter an array of values, it is easier and more intuitive to use the `array_map()` function rather than the filter extension.

As such, we propose to deprecate this filter.

### Deprecate filter\_input(), filter\_input\_array(), and filter\_has\_var()

The `filter_input()` and `filter_input_array()` functions operate on the **original** values provided by the SAPI that populate the superglobals for `$_GET`, `$_POST`, `$_SERVER`, `$_ENV`, and `$_COOKIE`.

This means that modification to any entry of the superglobal will not be used when calling these functions. This is showcased by the following PHPT test:

```php
--TEST--
filter_input() filter with superglobal modified
--EXTENSIONS--
filter
--GET--
a=hello
--FILE--
<?php
 
var_dump($_GET);
$f1 = filter_input(INPUT_GET, "a", FILTER_CALLBACK, ['options' => fn (string $s) => $s === "world"]);
var_dump($f1);
 
$_GET['a'] = "world";
var_dump($_GET);
$f2 =filter_input(INPUT_GET, "a", FILTER_CALLBACK, ['options' => fn (string $s) => $s === "world"]);
var_dump($f2);
var_dump($_GET);
 
?>
--EXPECT--
array(1) {
  ["a"]=>
  string(5) "hello"
}
bool(false)
array(1) {
  ["a"]=>
  string(5) "world"
}
bool(false)
array(1) {
  ["a"]=>
  string(5) "world"
}
```

As it is easy and straight forward to have the same behaviour by using `filter_var($_GET['a'], /* other params */)`and `filter_var_array($_GET, /* other params */)`, we propose to deprecate `filter_input()` and `filter_input_array()`.

As `filter_has_var()` is effectively equivalent to `array_key_exists()`, but has the same caveat as the two previous functions, we propose to also deprecate this function.
