Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:110335 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 76071 invoked from network); 2 Jun 2020 17:05:08 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 2 Jun 2020 17:05:08 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 71128180559 for ; Tue, 2 Jun 2020 08:47:05 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.7 required=5.0 tests=BAYES_05,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-ASN: AS15169 209.85.128.0/17 X-Spam-Virus: No X-Envelope-From: Received: from mail-io1-f43.google.com (mail-io1-f43.google.com [209.85.166.43]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Tue, 2 Jun 2020 08:47:04 -0700 (PDT) Received: by mail-io1-f43.google.com with SMTP id k18so11379676ion.0 for ; Tue, 02 Jun 2020 08:47:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to; bh=khiXSK7tpH18fUlhzE9sJiWz+c9dLw88b+Nxia7fLck=; b=ZJKjWu96cQDeLFgH959aaUJpVAc9+wyBWHtp0cawKqDV8UeF+W1nF3E/zievu6ssTQ jpFBfsCQraItn82D5UO6au2NdCBmrq0/JHxRRIuNB/BnEUa6Hn3NgoDJJ+p18lcoF7Kb aVGb3eNE0xEfKcBA7ZDVsttErLTctaJeRLBsEwJMYlVLfTcZ33PF6JQOAt0lSgB4TEYL fxSCZUF19iNFDiDjNYM+T1LZvuv7CmWsBAGPMiObMnoI0c2zD79Jf7OIwDrMwdYe2Op5 3f/4gzjpINgdoOQmIWX1AsyFkSAydjiIXlOgXosdQO9f/eAp3zwPyCitbyB//jFKl8XX DrBQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to; bh=khiXSK7tpH18fUlhzE9sJiWz+c9dLw88b+Nxia7fLck=; b=EBcVoVZnVf/LENF63FuwbU7bbxUXwsLqp+HGxu6Qwkk9X+a1zMBijy298ATEOWCrt/ ncHbtYF1BJTxJe33N6tKRStCDBavYSBznD4ynt4y9c58GEtnS/lK5eQhnmIwT0ouCgyB DtDe6lUaqMpg/WHwQDY9QqOi+AJ1C+HCrh0hejoAzYVgoGrPhm/RKL3t3ETPC/hRrFpy oW0nmLlUgf3HgkDK1b+9xJbVluoqo3rCu9VCjvtllvK3EpCuOYUvykLMzU7U5dn1slcg tuDJVmVMPFnr8D/xgGhtC7zPywhdqrxQkvVG2mDkc6urVPb+vpNkirJtrDt7INhAY7EF oLqg== X-Gm-Message-State: AOAM533m8CUbIwiRsnHHIduMEJ4NCN6rv4DuVDRtyYlkxY6mTdMt1Y4P QzmhHBkuDs4xcFEZSuikBwM1nBE2t4W/CZj7qubUaXWj X-Google-Smtp-Source: ABdhPJwumzTtGEHqRo1uWokKNyajsyVIA2kilUbokOnwNoJu86ARtOGiwCtqF/w36hSq8Os/8fmPJoar+JbNxANwCdc= X-Received: by 2002:a05:6602:2437:: with SMTP id g23mr51521iob.5.1591112822403; Tue, 02 Jun 2020 08:47:02 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Date: Tue, 2 Jun 2020 16:46:50 +0100 Message-ID: To: PHP internals Content-Type: multipart/alternative; boundary="00000000000093b74705a71bd27a" Subject: Re: [PHP-DEV] Numeric Type From: rowan.collins@gmail.com (Rowan Tommins) --00000000000093b74705a71bd27a Content-Type: text/plain; charset="UTF-8" Hi Marco, On Tue, 2 Jun 2020 at 16:10, Deleu wrote: > > The primary intent would be to safely pass around input that usually comes > from HTTP, CI or Database. Whenever interacting with these data providers, > string is a common format. `is_int` will not return true for integer values > that are string, instead we need to rely on `is_numeric`. > The problem with is_numeric() is that it uses an extremely broad definition of "numeric", which is not often what you actually want - for instance, is_numeric("-2.56E-90") returns true. The case I frequently see is much stricter: the variable should either be an integer, or a string representation of an integer. Whenever this comes up, I struggle for what the correct check actually is: * is_int($x) won't accept any strings * is_numeric($x) will accept far too much * an int type annotation with strict_types=0 is similar to is_numeric; in strict_types=1 it's the same as is_int * (int)$x will never give an error (meaning it's oddly easy to accidentally _suppress_ errors by trying to make code run under strict_types=1) * (int)$x != 0 is sometimes good enough, as long as zero is not a valid value (if you use this when accepting Unix timestamps, for instance, Jan 1st 1970 is going to be rejected!) * ctype_digit( (string)$x ) is confusing to read (the cast is required to accept actual integers, and the name is odd out of its intended context); it will also reject any negative numbers, which may or may not be desirable The only suitable built-in function I'm aware of is filter_var, which has a pretty horrible API: if ( filter_var($x, FILTER_VALIDATE_INT) !== false ) ... In the common case that you want to cast the variable to int on success (to pass to a strictly typed function), you would need to do something like this: $x = filter_var($x, FILTER_VALIDATE_INT); if ( $x === false ) { throw new TypeError; } I would love to see the language have a built-in short-hand for that, in the form of some kind of "strict cast", e.g.: $x = (int!)$x; or: $x = (strict int)$x; Once converted in that way, you could safely pass to a parameter marked int in strict mode, so wouldn't need a new pseudo-type. Regards, -- Rowan Tommins [IMSoP] --00000000000093b74705a71bd27a--