rfc:allow_null
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
rfc:allow_null [2021/12/23 22:07] – created craigfrancis | rfc:allow_null [2022/04/05 17:49] (current) – superseded craigfrancis | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== PHP RFC: Allow NULL ====== | ====== PHP RFC: Allow NULL ====== | ||
- | * Version: 1.0 | + | * Version: 1.3 |
* Voting Start: ? | * Voting Start: ? | ||
* Voting End: ? | * Voting End: ? | ||
* RFC Started: 2021-12-23 | * RFC Started: 2021-12-23 | ||
- | * RFC Updated: | + | * RFC Updated: |
* Author: Craig Francis, craig# | * Author: Craig Francis, craig# | ||
- | * Status: | + | * Status: |
* First Published at: https:// | * First Published at: https:// | ||
* GitHub Repo: https:// | * GitHub Repo: https:// | ||
* Implementation: | * Implementation: | ||
+ | |||
+ | ---- | ||
+ | |||
+ | This RFC has been superseded by [[https:// | ||
+ | |||
+ | ---- | ||
===== Introduction ===== | ===== Introduction ===== | ||
- | PHP 8.1 introduced "Passing | + | PHP 8.1 introduced "Deprecate passing |
+ | |||
+ | This has introduced an inconstancy when not using // | ||
- | Often //NULL// is used for undefined | + | In PHP //NULL// is often used to represent something; e.g. when a // |
<code php> | <code php> | ||
Line 27: | Line 35: | ||
</ | </ | ||
- | And //NULL// can be returned from many functions, e.g. | + | And //NULL// can be returned from functions, e.g. |
* // | * // | ||
- | * //error_get_last()// | + | * //filter_input()// |
* // | * // | ||
+ | * // | ||
* // | * // | ||
- | * // | ||
- | Currently this change only affects those using PHP 8.1 with //E_DEPRECATED//, but it implies everyone will need to modify their code in the future. | + | This makes it common for //NULL// to be passed to many internal functions, e.g. |
- | And those modifications are not easy (both in finding them, and quantity). | + | <code php> |
+ | trim($name); | ||
+ | strtoupper($name); | ||
+ | strlen($name); | ||
+ | urlencode($name); | ||
+ | htmlspecialchars($name); | ||
+ | hash(' | ||
+ | preg_match('/ | ||
+ | setcookie(' | ||
+ | socket_write($socket, | ||
+ | xmlwriter_text($writer, $name); | ||
+ | </ | ||
- | Developers | + | Developers |
- | This affects every variable that could be set to //NULL//, when they are passed to any internal function that has deprecated | + | Where //NULL// has always been coerced into an empty string, |
+ | |||
+ | Currently the deprecation notices only affect those using PHP 8.1 with // | ||
+ | |||
+ | Developers using // | ||
+ | |||
+ | And while individual changes are easy, there are many of them (time consuming), difficult to find, and often pointless, e.g. | ||
+ | |||
+ | * urlencode(strval($name)); | ||
+ | * urlencode((string) $name); | ||
+ | * urlencode($name ?? '' | ||
+ | |||
+ | To find these issues, developers need to either - use these deprecation notices, or use very strict Static Analysis (one that can determine when a variable can be //NULL//; e.g. Psalm at [[https:// | ||
+ | |||
+ | It's worth noting that some parameters, like // | ||
===== Proposal ===== | ===== Proposal ===== | ||
- | To make upgrading easier, we could either: | + | There are 3 possible approaches: |
+ | |||
+ | - NULL triggers a Fatal Error with strict_types=1, otherwise allow coercion (like how integers can be coerced to a string). | ||
+ | - NULL triggers a Fatal Error for everyone, but update some parameters to explicitly allow NULL (e.g. //? | ||
+ | - NULL triggers a Fatal Error for everyone (forget about backwards compatibility). | ||
+ | |||
+ | This needs to be done before the eventual end of the deprecation period, and // | ||
+ | |||
+ | If we choose to " | ||
+ | |||
+ | There is also a [[https:// | ||
+ | |||
+ | ===== Decision Process ===== | ||
+ | |||
+ | Does //NULL// for this parameter justify a Fatal Error? e.g. | ||
- | - Allow // | + | - // |
- | - Update some of the internal functions to accept //NULL//. | + | - // |
+ | - // | ||
+ | - //hash()// should **accept** // | ||
+ | - // | ||
+ | - // | ||
===== Backward Incompatible Changes ===== | ===== Backward Incompatible Changes ===== | ||
- | N/A | + | None |
===== Proposed PHP Version(s) ===== | ===== Proposed PHP Version(s) ===== | ||
- | PHP 8.1 | + | PHP 8.2 |
===== RFC Impact ===== | ===== RFC Impact ===== | ||
Line 74: | Line 125: | ||
===== Open Issues ===== | ===== Open Issues ===== | ||
- | TODO | + | Is the [[https:// |
===== Future Scope ===== | ===== Future Scope ===== | ||
- | TODO | + | Some function parameters could be updated to complain when an //NULL// **or** //Empty String// is provided; e.g. //$method// in // |
===== Voting ===== | ===== Voting ===== | ||
Line 86: | Line 137: | ||
TODO | TODO | ||
- | ===== Patches and Tests ===== | + | ===== Tests ===== |
- | TODO | + | To get and **Test** the list of functions, I wrote a script to // |
===== Implementation ===== | ===== Implementation ===== | ||
- | TODO | + | https:// |
- | ===== Rejected Features ===== | + | This patch defines // |
- | TODO | + | It works a bit like // |
+ | It's a fairly easy drop in replacement for // | ||
+ | ===== Rejected Features ===== | ||
- | --- | + | TODO |
- | ====== Notes ====== | + | ===== Notes ===== |
- | Interesting | + | Interesting the example quote from [[http:// |
> PHP is and should remain: | > PHP is and should remain: | ||
Line 110: | Line 163: | ||
> 2) a loosely typed language | > 2) a loosely typed language | ||
> 3) a language which caters to the skill-levels and platforms of a wide range of users | > 3) a language which caters to the skill-levels and platforms of a wide range of users | ||
- | |||
- | |||
- | |||
- | grep -h -r -E ' | ||
- | |||
- | Search | ||
- | ^(\s*(ZEND_FUNCTION|PHP_FUNCTION|static void).*\n)*(ZEND_FUNCTION\(|PHP_FUNCTION\(|static void *)(.+? | ||
- | Replace | ||
- | $4 | ||
rfc/allow_null.txt · Last modified: 2022/04/05 17:49 by craigfrancis