Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:127060 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by qa.php.net (Postfix) with ESMTPS id 3CA4B1A00BC for ; Sun, 6 Apr 2025 08:28:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1743927960; bh=EJFrOVR3QrxeZuzRqnRnPl1BAXVcFnM/OBtLZ8f2m+k=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=ix2TIGPko+JCRhbPqkR1A9P8zUFelyUcK0bsy4BdNDIYlPghEd3d+hXGL78vd+dDA B7EpBK7n34BGpTk32PqVMzxINdBvPMFcfsc9B5eOTDDFUrjBTVKxhIE69JD2s1+3m0 Ucwnz8Xqwi0eOhw4RR/peU4xB+u/6MfyssxOwLfTZU2wKX0158IBIRu//ElxNuXdjj WVC/XEHDe6OQDmKOZp1/KRMtw3jIP+aNUN5lEARgU5pjCuIxbTp3dg7csTnbrk4jC6 qeFUbjcc1KSPo63c0vM6f53EkPvVzt6Mpoc+MqKJrTDcOgMzjIU/KUDZhEkv8ckTkD OqnyCSYjwjP0A== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id C804218005B for ; Sun, 6 Apr 2025 08:25:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Sun, 6 Apr 2025 08:25:59 +0000 (UTC) Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-ac2bdea5a38so545877766b.0 for ; Sun, 06 Apr 2025 01:28:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1743928103; x=1744532903; darn=lists.php.net; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=B3gVFlUZB/xzNL2XH79asCu9aRgc5julsfPrja6TfuQ=; b=a1ATDJCZM4zHxP3uEO7w9dGp+SVsqru+/R2PrDryIOBtKIg4/EYwZRjCsjK+W5KPVY KlQoYnU/aDYBXPc08aBvt6aaTcw5M7zSuYFELlhWB0U5odtArFcDSrwjOmIrM4BH9Pb9 1R0b9z0InDvuFs4OblgwH4BoPFtRiyEb0GsR9AWLo1en+GIB6+9QK1AoocYnACOIfbKw UCY7+I3yF54DL98eACse7E/daYTrLiBrT34ouU2ETLLtXsbZD2pTlZ8BuVXr8+rccPOZ DPR17GAuvMTbH4pPMWF/iX7n7oKq6QTqv8gEziMuZbT6pAzx/4dIqWfn2e/emSGV9QL8 fQlg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1743928103; x=1744532903; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=B3gVFlUZB/xzNL2XH79asCu9aRgc5julsfPrja6TfuQ=; b=s8j0lC3aKJsepUICc5PJ9W57iDM/ccvdRZ1T0RRRjjZZBvelXg9zR3qpJk+B+lBPAi CKreNWKP2nsH97WxVnNj+tcOEQCPALobAO9jGyaS2MOTNE8wJrXn+Ps6M1MW65n+3Yy1 469ScLTg0a0BdG4AC7zHds/af8abSAOhYrnoCblnxfyDFr+Zfye8D0dL6oiTfE8U+1P2 LSxBQtFUPK83bf13xcHaIjzd2cidoMK/UrSuv/ZyiVeF8wN+0TwUbsKJM672PiiN5QuM vbVOniVeEhMrA3k70oo+0lHPuaW89LZHRnOGL7iqUoQoLT0Gb+NGyu0my80GUsS8A8bd XjwQ== X-Forwarded-Encrypted: i=1; AJvYcCVlhdRdEKAkxg7iftlbi+5MaCIgm/dFNQHJx4CkvviGxPcdgU76rL23AxDOnaSOZYbMb+dXrfNj+EQ=@lists.php.net X-Gm-Message-State: AOJu0YyacK1L5r58UOdoeQViNuPOkn9XXQB1dlC6K/sw3UrP9FQWvLEF C2Sraj98scEHht00Tr9u8yphwvoZ+KYSXYDnwQKF9qiBkB5+kvkpm76Cftk1M8rN6axEuwtbmeu tJLIvuhfeUy3XP0j4WwpdGZ+lJza3aOziO1Y= X-Gm-Gg: ASbGncukUMJfd+pooWZLnOES+HihuYlx6PQUToPKJ7BYh0daEVxywkj7cWpNfzJQMLG +pr6FMveEte29q73S80DNRkqbHlKhiJmAfkXeUf17X/xXvpes2kiWHbIs1Tpn9UaU9S/i2ezEpA /hGlyET1ZVvC6zqkgNoTc1MZ8Yhg== X-Google-Smtp-Source: AGHT+IFsr4UWxr//KNtsOK2t8Apn4OKPyXLfwvb+y1llljEvBVzH71oijX1449L4Wjx403w2yVBCWUasxFmDLYzfFFU= X-Received: by 2002:a17:907:9301:b0:ac1:ea29:4e63 with SMTP id a640c23a62f3a-ac7d6d53ea2mr649022566b.26.1743928103052; Sun, 06 Apr 2025 01:28:23 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <17aa0250-ee1f-477a-a255-303281d7a833@app.fastmail.com> In-Reply-To: Date: Sun, 6 Apr 2025 11:28:11 +0300 X-Gm-Features: ATxdqUGMbbNmGqOYuX0tSZulntxvb2KtQEXyXbOoQ2hvL1DndfmJRij8MChGU7E Message-ID: Subject: Re: [PHP-DEV] RFC: blank() Function as a Complement to empty() To: Hans Henrik Bergan Cc: Rob Landers , internals@lists.php.net Content-Type: multipart/alternative; boundary="00000000000018ae62063217e7f0" From: i.miroslavov@gmail.com (Iliya Miroslavov Iliev) --00000000000018ae62063217e7f0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Sun, Apr 6, 2025 at 9:52=E2=80=AFAM Hans Henrik Bergan 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 warni= ng > or not, idk how hard that would be. > > On Sat, Apr 5, 2025, 22:27 Iliya Miroslavov Iliev > wrote: > >> >> >> On Sat, Apr 5, 2025 at 11:04=E2=80=AFPM Rob Landers = 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=E2=80=99s core, intended to provide a more intuitive and context-se= nsitive 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 =E2= =80=94 >>> 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 =E2=80=94 specific= ally 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=E2=80=99s current toolse= t for >>> handling =E2=80=9Cblank=E2=80=9D values in a more semantic and intentio= n-aligned way. >>> >>> >>> I would personally advocate that empty() NEVER be used on strings. Ther= e >>> 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 =3D=3D "" -- not= e 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 =3D=3D=3D $value || >>> (empty($value) && '0' !=3D $value) || >>> (\is_string($value) && '' =3D=3D=3D \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 =E2=98=95 >>> >>> >>> =E2=80=94 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 --=20 Iliya Miroslavov Iliev i.miroslavov@gmail.com --00000000000018ae62063217e7f0 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


On Sun, Apr 6, = 2025 at 9:52=E2=80=AFAM Hans Henrik Bergan <divinity76@gmail.com> wrote:

Maybe a
#[\SuppressUndefinedWarning]

Parameter attribute could work, then everyone could implemen= t their own blank() function with their own preferred logic

Not sure if it's technically feasible tho, now the php e= ngine would need to inspect the parameter attributes before deciding on gen= erating 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:
<= /div>


On Sat, Apr 5, 2025 at 11:04=E2=80=AFPM Rob Landers <r= ob@bottled.codes> wrote:
On Sat, Apr 5, 2025, at 14:15, Kayck Mati= as wrote:
INTRODUCTION
This RFC proposes the addition of= a new global function=C2=A0blank()=C2=A0to PHP=E2=80=99s core= , intended to provide a more intuitive and context-sensitive way of checkin= g for "blank" values. This function is=C2=A0not a replacement<= /b>=C2=A0for=C2=A0empty(), but a=C2=A0complementary tool=C2= =A0to help developers more accurately evaluate user input, query parame= ters, and form values =E2=80=94 particularly in situations where=C2=A0empty()=C2=A0may behave in unintuitive ways.


MOTIVATION
The motivation for this RFC aros= e from a real-world issue I encountered at work involving query string filt= ering =E2=80=94 specifically when using the string=C2=A0"0"= =C2=A0as a filter value. Because=C2=A0empty("0")=C2=A0evaluates to=C2=A0true, the logic skipped this valid = input, causing incorrect behavior in the application. This highlighted a ga= p in PHP=E2=80=99s current toolset for handling =E2=80=9Cblank=E2=80=9D val= ues 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 mes= sage on the thread, if you want to know if a string is empty, just do $stri= ng =3D=3D "" -- note the double equals, not triple equals. This m= atches null, an actual empty string, and false, but won't match anythin= g else.

<= div dir=3D"ltr">
PROPOSAL
The proposed=C2=A0= blank()=C2=A0function will behave similarly to=C2=A0empty(), but with semantics better suited for filtering, validation, and user = input. Its primary goals are:
  • To treat whitespace-only strings as blank (e.g.,=C2=A0" &= quot;).

  • To treat=C2=A0= "0"=C2=A0(string zero) and=C2=A00=C2=A0= (int zero) as=C2=A0not blank, unlike=C2=A0empty().
    <= /p>

  • To support clearer, intention-dri= ven logic when working with dynamic input, especially in query strings and = HTTP forms.

Function Si= gnature

function blank(mixed = $value): bool;

Logic (PH= P version)
function blank(mixed $value): bool
{
if (
false =3D=3D=3D = $value ||
(empty($value) &&= ; '0'= ; !=3D $value) ||
(\is_str= ing($value) &&= '' =3D=3D=3D \trim($value))
) {
return true;
}

return false;
}
<= /div>
Examples
e= cho=C2=A0blank(null);=C2=A0// true
echo=C2=A0blank(<= span style=3D"color:rgb(189,147,249)">false);=C2=A0// true
echo=C2=A0blank<= /span>("");=C2=A0// true
echo=C2=A0blank("<= span style=3D"color:rgb(241,250,140)">=C2=A0");=C2=A0/= / true
echo=C2=A0blank([]);=C2=A0// true

echo=C2=A0blank(0<= /span>);=C2=A0// false
echo=C2=A0blank("0");=C2=A0// false
echo=C2=A0blank(<= span style=3D"color:rgb(233,242,132)">"test");=C2=A0// false
<= div>echo=C2=A0blank([0]);=C2=A0// 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 a= n empty string is usually all you need, not empty().

Best Regards,
Kayck Matias=C2=A0=E2= =98=95

<= div id=3D"m_2170042669567627025m_-449414616074438654m_-1637272977242180560s= ig121229152">=E2=80=94 Rob
Just something that came into my mind. A "no= rmal space"=C2=A0character is 32, "non-breaking space" is 16= 0 and a "zero width space" is=C2=A08203. These are all characters= so they are not blank and cannot be ignored
--
Iliya Miroslavov Iliev

>=C2=A0 then everyo= ne could implement their own blank() function with their own preferred logi= c
If this can still be implemented in userland you don't need logic = integrated at low level
--
Iliya Mi= roslavov Iliev
--00000000000018ae62063217e7f0--