RFC: blank() Function as a Complement to empty()

php.internals

Kayck Matias

1 year ago
*INTRODUCTION* This RFC proposes the addition of a new global function blank() to PHP’s core, intended to provide a more intuitive and context-sensitive way of checking for "blank" values. This function is *not a replacement* for empty(), but a *complementary tool *to help developers more accurately evaluate user input, query parameters, and form values — particularly in situations where empty() may behave in unintuitive ways. *MOTIVATION*The motivation for this RFC arose from a real-world issue I encountered at work involving query string filtering — specifically when using the string "0" as a filter value. Because empty("0") evaluates to true, the logic skipped this valid input, causing incorrect behavior in the application. This highlighted a gap in PHP’s current toolset for handling “blank” values in a more semantic and intention-aligned way. *PROPOSAL* The proposed blank() function will behave similarly to empty(), but with semantics better suited for filtering, validation, and user input. Its primary goals are: - To treat whitespace-only strings as blank (e.g., " "). - To treat "0" (string zero) and 0 (int zero) as *not blank*, unlike empty(). - To support clearer, intention-driven logic when working with dynamic input, especially in query strings and HTTP forms. Function Signature function blank(mixed $value): bool; Logic (PHP version) function blank(mixed $value): bool { if ( false === $value || (empty($value) && '0' != $value) || (\is_string($value) && '' === \trim($value)) ) { return true; } return false; } Examples echo blank(null); // true echo blank(false); // true echo blank(""); // true echo blank(" "); // true echo blank([]); // true echo blank(0); // false echo blank("0"); // false echo blank("test"); // false echo blank([0]); // false *BACKWARDS INCOMPATIBLE CHANGES* This feature is fully backward-compatible. It does not alter existing behavior of any function or construct, nor does it redefine empty(). It introduces a new global function and does not break any existing code. *RFC IMPACT* - *CLI & Web usage*: This function will be available globally, in both CLI and Web SAPI contexts. - *Core behavior*: The function is small, simple, and does not interfere with any existing language behavior or constructs. - *php.ini*: No changes required. - *New constants*: None introduced. This function is expected to improve *code clarity and correctness* in real-world applications, without burdening the language with complexity. *COMMUNITY FEEDBACK*Multiple developers have voiced concerns regarding empty() in real-world scenarios. A key example is PHP Issue #9845 <https://github.com/php/php-src/issues/9845> on GitHub, where it's reported that: "empty("0") returns true when it should return false." This discussion highlights a recurring problem: developers often expect '0' to be treated as a valid, non-empty input (e.g., in filtering query strings), but empty() evaluates it as false. This leads to conditional logic silently skipping valid inputs. The blank() function is designed to directly address this gap, offering a more semantic and human-friendly approach to "blankness" that aligns better with what developers actually expect in these cases. *NEXT STEPS*This is my first RFC proposal, If there are any issues with the approach, naming, scope, or anything I may have overlooked, I’d greatly appreciate your guidance. If there’s interest in moving forward, I will prepare the full RFC documentation on the wiki along with an implementation patch and appropriate tests. *Thanks in advance for your time and input!* Best Regards, Kayck Matias ☕

Kamil Tekiela

1 year ago
Hi Kayck, Thanks for your proposal. Here are some points from me: empty() is not a function, it's a language construct that's a shorthand for !isset($var) || $var == false. While it has its uses empty() should be avoided whenever possible. It's generally a sign of the programmer being lazy not doing proper data validation/type checking. The zero-string being considered falsey isn't limited to empty(). It's just how PHP types work. Introducing a new function with slightly different semantics would create tons of confusion. On top of that, your new function proposes rules that are unintuitive and very likely applicable only to your project. Getting everyone to agree to these rules would be near impossible. You can very easily create this function in global scope in your project but introducing this at the language level would potentially break a lot of existing code. It's not inconceivable that people have defined such a function in global scope in their projects already. My stance is that I am categorically against it even if the semantics would have been more ironed out. Unless PHP is about to phase out loose comparison, we don't need a new function that is just an opinionated variation of it. Thank you for the proposal and please don't be disheartened by my strong opinion. Regards, Kamil On Sat, Apr 5, 2025, 14:16 Kayck Matias <kayckmatias04@gmail.com> wrote:

Bilge

1 year ago
On 05/04/2025 15:32, Kamil Tekiela wrote:
> > While it has its uses empty() should be avoided whenever possible. >
Agree. A better RFC would be to just deprecate `empty()`. Cheers, Bilge

Rob Landers

1 year ago
On Sat, Apr 5, 2025, at 20:25, Bilge wrote:
> On 05/04/2025 15:32, Kamil Tekiela wrote: > > > > While it has its uses empty() should be avoided whenever possible. > > > Agree. A better RFC would be to just deprecate `empty()`. > > Cheers, > Bilge >
empty() has very many uses. Once you understand what it is shorthand for, it makes a lot of sense to use it how it was meant to be used. For example: empty($var) ?: foo($var); which is just shorter than: if (isset($var) && $varl != false) { foo($bool); } Generally, you don't use empty() on strings though, just arrays, in my style guides anyway. For strings, you use `$string == ""` or to be more proper, maybe trim($value ?? '') == '' ... but these days, trim doesn't accept `null`, so that makes it a bit more wordy than it really should be. However, it is just a deprecation notice, so it is easy to ignore. For now. — Rob

Iliya Miroslavov Iliev

1 year ago
> echo blank(" "); // true
This case is not blank `empty` checks if a variable is set and contains something so basically what your blank function does. In this example it contains character 32. If you want to remove the "\0" (null terminator) from the language, that's a different story. On Sat, Apr 5, 2025 at 9:45 PM Rob Landers <rob@bottled.codes> wrote:
> On Sat, Apr 5, 2025, at 20:25, Bilge wrote: > > On 05/04/2025 15:32, Kamil Tekiela wrote: > > > > While it has its uses empty() should be avoided whenever possible. > > > Agree. A better RFC would be to just deprecate `empty()`. > > Cheers, > Bilge > > > empty() has very many uses. Once you understand what it is shorthand for, > it makes a lot of sense to use it how it was meant to be used. For example: > > empty($var) ?: foo($var); > > which is just shorter than: > > if (isset($var) && $varl != false) { > foo($bool); > } > > Generally, you don't use empty() on strings though, just arrays, in my > style guides anyway. For strings, you use `$string == ""` or to be more > proper, maybe > > trim($value ?? '') == '' > > ... but these days, trim doesn't accept `null`, so that makes it a bit > more wordy than it really should be. However, it is just a deprecation > notice, so it is easy to ignore. For now. > > — Rob >
-- Iliya Miroslavov Iliev i.miroslavov@gmail.com

Bilge

1 year ago
On 05/04/2025 19:41, Rob Landers wrote:
> empty() has very many uses.
That is exactly the same as saying `==` has many uses. It does. So many uses that it's useless. Its semantics are nonsense.
> > if (isset($var) && $varl != false) { >   foo($bool); > } > >$varl != false
You should never be doing this. Cheers, Bilge

Rob Landers

1 year ago
On Sat, Apr 5, 2025, at 21:10, Bilge wrote:
> On 05/04/2025 19:41, Rob Landers wrote: >> empty() has very many uses. > That is exactly the same as saying `==` has many uses. It does. So many uses that it's useless. Its semantics are nonsense. >> >> if (isset($var) && $varl != false) { >> foo($bool); >> } >> > >$varl != false > > You should never be doing this. > > > Cheers, > Bilge >
Heh, to quote a great movie: That's just like, your opinion, man. In all seriousness, there are quite a number of uses for ==, especially because we don't have operators on objects, nor do we have value objects. Sometimes, equality isn't based on identity, but on value: https://3v4l.org/rRMNR — Rob

Bilge

1 year ago
On 05/04/2025 20:18, Rob Landers wrote:
> On Sat, Apr 5, 2025, at 21:10, Bilge wrote: >> On 05/04/2025 19:41, Rob Landers wrote: >>> empty() has very many uses. >> That is exactly the same as saying `==` has many uses. It does. So >> many uses that it's useless. Its semantics are nonsense. >>> >>> if (isset($var) && $varl != false) { >>>   foo($bool); >>> } >>> >> >$varl != false >> >> You should never be doing this. >> >> Cheers, >> Bilge > > Heh, to quote a great movie: That's just like, your opinion, man. In > all seriousness, there are quite a number of uses for ==, especially > because we don't have operators on objects, nor do we have value > objects. Sometimes, equality isn't based on identity, but on value: > > https://3v4l.org/rRMNR > > — Rob
You don't use empty() on objects.

Rob Landers

1 year ago
On Sat, Apr 5, 2025, at 21:23, Bilge wrote:
> On 05/04/2025 20:18, Rob Landers wrote: >> On Sat, Apr 5, 2025, at 21:10, Bilge wrote: >>> On 05/04/2025 19:41, Rob Landers wrote: >>>> empty() has very many uses. >>> That is exactly the same as saying `==` has many uses. It does. So many uses that it's useless. Its semantics are nonsense. >>>> >>>> if (isset($var) && $varl != false) { >>>> foo($bool); >>>> } >>>> >>> >$varl != false >>> >>> You should never be doing this. >>> >>> Cheers, >>> Bilge >> >> Heh, to quote a great movie: That's just like, your opinion, man. In all seriousness, there are quite a number of uses for ==, especially because we don't have operators on objects, nor do we have value objects. Sometimes, equality isn't based on identity, but on value: >> >> https://3v4l.org/rRMNR >> >> — Rob > You don't use empty() on objects. >
I initially thought your comment was focused specifically on the use of ==, rather than "== false" or "!= false." That said, I think all of these have valid use cases, as does empty(). I'm not entirely clear on the point you're trying to make, though — if the argument is simply "you should never be doing this," it would be helpful to understand the reasoning behind that perspective. Without context or elaboration, it comes across more as a personal preference than a technical guideline. — Rob

Rob Landers

1 year ago
On Sat, Apr 5, 2025, at 14:15, Kayck Matias wrote:
> *INTRODUCTION* > This RFC proposes the addition of a new global function `blank()` to PHP’s core, intended to provide a more intuitive and context-sensitive way of checking for "blank" values. This function is *not a replacement* for `empty()`, but a *complementary tool *to help developers more accurately evaluate user input, query parameters, and form values — particularly in situations where `empty()` may behave in unintuitive ways. > > > *MOTIVATION
*The motivation for this RFC arose from a real-world issue I encountered at work involving query string filtering — specifically when using the string `"0"` as a filter value. Because `empty("0")` evaluates to `true`, the logic skipped this valid input, causing incorrect behavior in the application. This highlighted a gap in PHP’s current toolset for handling “blank” values in a more semantic and intention-aligned way. I would personally advocate that empty() NEVER be used on strings. There are too many edge cases. As I said in an earlier message on the thread, if you want to know if a string is empty, just do $string == "" -- note the double equals, not triple equals. This matches null, an actual empty string, and false, but won't match anything else.
> *PROPOSAL* > The proposed `blank()` function will behave similarly to `empty()`, but with semantics better suited for filtering, validation, and user input. Its primary goals are: > • To treat whitespace-only strings as blank (e.g., `" "`). > > • To treat `"0"` (string zero) and `0` (int zero) as *not blank*, unlike `empty()`. > > • To support clearer, intention-driven logic when working with dynamic input, especially in query strings and HTTP forms. > > Function Signature > > function blank(mixed $value): bool; > ** > Logic (PHP version) > function blank(mixed $value): bool > { > if ( > false === $value || > (empty($value) && '0' != $value) || > (\is_string($value) && '' === \trim($value)) > ) { > return true; > } > > return false; > } > Examples > echo blank(null); // true > echo blank(false); // true > echo blank(""); // true > echo blank(" "); // true > echo blank([]); // true > > echo blank(0); // false > echo blank("0"); // false > echo blank("test"); // false > echo blank([0]); // false
I agree with most of these. I do not agree that " " (a space) is blank though. For people without last names, this is often their last name to pass validation on forms. As I said earlier, a simple loose check with an empty string is usually all you need, not empty().
> Best Regards, > Kayck Matias ☕
— Rob

Iliya Miroslavov Iliev

1 year ago
On Sat, Apr 5, 2025 at 11:04 PM Rob Landers <rob@bottled.codes> wrote:
> On Sat, Apr 5, 2025, at 14:15, Kayck Matias wrote: > > *INTRODUCTION* > This RFC proposes the addition of a new global function blank() to PHP’s > core, intended to provide a more intuitive and context-sensitive way of > checking for "blank" values. This function is *not a replacement* for > empty(), but a *complementary tool *to help developers more accurately > evaluate user input, query parameters, and form values — particularly in > situations where empty() may behave in unintuitive ways. > > > > *MOTIVATION*The motivation for this RFC arose from a real-world issue I > encountered at work involving query string filtering — specifically when > using the string "0" as a filter value. Because empty("0") evaluates to > true, the logic skipped this valid input, causing incorrect behavior in > the application. This highlighted a gap in PHP’s current toolset for > handling “blank” values in a more semantic and intention-aligned way. > > > I would personally advocate that empty() NEVER be used on strings. There > are too many edge cases. As I said in an earlier message on the thread, if > you want to know if a string is empty, just do $string == "" -- note the > double equals, not triple equals. This matches null, an actual empty > string, and false, but won't match anything else. > > *PROPOSAL* > The proposed blank() function will behave similarly to empty(), but with > semantics better suited for filtering, validation, and user input. Its > primary goals are: > > - > > To treat whitespace-only strings as blank (e.g., " "). > - > > To treat "0" (string zero) and 0 (int zero) as *not blank*, unlike > empty(). > - > > To support clearer, intention-driven logic when working with dynamic > input, especially in query strings and HTTP forms. > > Function Signature > > function blank(mixed $value): bool; > > Logic (PHP version) > > function blank(mixed $value): bool > { > if ( > false === $value || > (empty($value) && '0' != $value) || > (\is_string($value) && '' === \trim($value)) > ) { > return true; > } > > return false; > } > > Examples > echo blank(null); // true > echo blank(false); // true > echo blank(""); // true > echo blank(" "); // true > echo blank([]); // true > > echo blank(0); // false > echo blank("0"); // false > echo blank("test"); // false > echo blank([0]); // false > > > I agree with most of these. I do not agree that " " (a space) is blank > though. For people without last names, this is often their last name to > pass validation on forms. As I said earlier, a simple loose check with an > empty string is usually all you need, not empty(). > > Best Regards, > Kayck Matias ☕ > > > — Rob >
Just something that came into my mind. A "normal space" character is 32, "non-breaking space" is 160 and a "zero width space" is 8203. These are all characters so they are not blank and cannot be ignored
-- Iliya Miroslavov Iliev i.miroslavov@gmail.com

Hans Henrik Bergan

1 year ago
Maybe a #[\SuppressUndefinedWarning] Parameter attribute could work, then everyone could implement their own blank() function with their own preferred logic Not sure if it's technically feasible tho, now the php engine would need to inspect the parameter attributes before deciding on generating a warning or not, idk how hard that would be. On Sat, Apr 5, 2025, 22:27 Iliya Miroslavov Iliev <i.miroslavov@gmail.com> wrote:

Iliya Miroslavov Iliev

1 year ago
On Sun, Apr 6, 2025 at 9:52 AM Hans Henrik Bergan <divinity76@gmail.com> wrote:
> Maybe a > #[\SuppressUndefinedWarning] > > Parameter attribute could work, then everyone could implement their own > blank() function with their own preferred logic > > Not sure if it's technically feasible tho, now the php engine would need > to inspect the parameter attributes before deciding on generating a warning > or not, idk how hard that would be. > > On Sat, Apr 5, 2025, 22:27 Iliya Miroslavov Iliev <i.miroslavov@gmail.com> > wrote: > >> >> >> On Sat, Apr 5, 2025 at 11:04 PM Rob Landers <rob@bottled.codes> wrote: >> >>> On Sat, Apr 5, 2025, at 14:15, Kayck Matias wrote: >>> >>> *INTRODUCTION* >>> This RFC proposes the addition of a new global function blank() to >>> PHP’s core, intended to provide a more intuitive and context-sensitive way >>> of checking for "blank" values. This function is *not a replacement* >>> for empty(), but a *complementary tool *to help developers more >>> accurately evaluate user input, query parameters, and form values — >>> particularly in situations where empty() may behave in unintuitive ways. >>> >>> >>> >>> *MOTIVATION*The motivation for this RFC arose from a real-world issue I >>> encountered at work involving query string filtering — specifically when >>> using the string "0" as a filter value. Because empty("0") evaluates to >>> true, the logic skipped this valid input, causing incorrect behavior in >>> the application. This highlighted a gap in PHP’s current toolset for >>> handling “blank” values in a more semantic and intention-aligned way. >>> >>> >>> I would personally advocate that empty() NEVER be used on strings. There >>> are too many edge cases. As I said in an earlier message on the thread, if >>> you want to know if a string is empty, just do $string == "" -- note the >>> double equals, not triple equals. This matches null, an actual empty >>> string, and false, but won't match anything else. >>> >>> *PROPOSAL* >>> The proposed blank() function will behave similarly to empty(), but >>> with semantics better suited for filtering, validation, and user input. Its >>> primary goals are: >>> >>> - >>> >>> To treat whitespace-only strings as blank (e.g., " "). >>> - >>> >>> To treat "0" (string zero) and 0 (int zero) as *not blank*, unlike >>> empty(). >>> - >>> >>> To support clearer, intention-driven logic when working with dynamic >>> input, especially in query strings and HTTP forms. >>> >>> Function Signature >>> >>> function blank(mixed $value): bool; >>> >>> Logic (PHP version) >>> >>> function blank(mixed $value): bool >>> { >>> if ( >>> false === $value || >>> (empty($value) && '0' != $value) || >>> (\is_string($value) && '' === \trim($value)) >>> ) { >>> return true; >>> } >>> >>> return false; >>> } >>> >>> Examples >>> echo blank(null); // true >>> echo blank(false); // true >>> echo blank(""); // true >>> echo blank(" "); // true >>> echo blank([]); // true >>> >>> echo blank(0); // false >>> echo blank("0"); // false >>> echo blank("test"); // false >>> echo blank([0]); // false >>> >>> >>> I agree with most of these. I do not agree that " " (a space) is blank >>> though. For people without last names, this is often their last name to >>> pass validation on forms. As I said earlier, a simple loose check with an >>> empty string is usually all you need, not empty(). >>> >>> Best Regards, >>> Kayck Matias ☕ >>> >>> >>> — Rob >>> >> >> Just something that came into my mind. A "normal space" character is 32, >> "non-breaking space" is 160 and a "zero width space" is 8203. These are all >> characters so they are not blank and cannot be ignored >> -- >> Iliya Miroslavov Iliev >> i.miroslavov@gmail.com >> > > then everyone could implement their own blank() function with their own
preferred logic If this can still be implemented in userland you don't need logic integrated at low level
-- Iliya Miroslavov Iliev i.miroslavov@gmail.com

Hans Henrik Bergan

1 year ago
>If this can still be implemented in userland you don't need logic integrated at low level
Afaik it cannot be implemented in userland today. The closest you can get today is to use reference hacks, which introduce side-effects, like if you do function blank(&$value){...} blank($_POST['foo']) and foo doesn't exist, the & ref will *create* foo with null, like var_dump($_POST); // array(0) {} blank($_POST['foo']); var_dump($_POST); // array(1) {["foo"]=>NULL} But maybe we could make it possible like function blank(#[\AllowUndeclared] $value){...} var_dump($_POST); // array(0) {} blank($_POST['foo']); var_dump($_POST); // array(0) {}

Rowan Tommins [IMSoP]

1 year ago
On 5 April 2025 21:00:15 BST, Rob Landers <rob@bottled.codes> wrote:
>I agree with most of these. I do not agree that " " (a space) is blank though. For people without last names, this is often their last name to pass validation on forms.
This is firmly into "space-bar heating" [https://xkcd.com/1172/] territory - failure to trim whitespace before validation is a common bug, and requiring a name in exactly two boxes is a common design/localisation failure, but neither justifies the other. I think a function for "string is zero length or contains only whitespace" would potentially be useful, but am not convinced it needs to accept any other type, or have the error-suppression power of isset/empty - adding ??'' inside a function call is not a big burden for new code. That said, I just realised there is a ctype_space function, and I've never used it or seen it used; normally, trim($foo)==='' (or trim($foo??'')==='') seems to be good enough. Rowan Tommins [IMSoP]

Tim Düsterhus

1 year ago
Hi Am 2025-04-07 09:14, schrieb Rowan Tommins [IMSoP]:
> I think a function for "string is zero length or contains only > whitespace" would potentially be useful
And for that one it would need to be defined what whitespace is. Is it just the ASCII whitespace characters? Is it Unicode whitespace? Is it also Unicode non-whitespace that renders as blank? To give an example of the complexity here, this is a `trim()` function that I implemented to handle all kinds of “blank input abuse”, while trying not to break legitimate use-cases of non-Latin languages: https://github.com/WoltLab/WCF/blob/5c6568807aa22ce337e7527f75c7a8fb2047bf67/wcfsetup/install/files/lib/util/StringUtil.class.php#L90-L141 Best regards Tim Düsterhus