Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:124946 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 ECE981A00B7 for ; Thu, 15 Aug 2024 15:42:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1723736646; bh=U6/Krx3tUIp5TcE6lezIDEcWsRulHheFwgtZubR2Bp4=; h=From:Date:Subject:To:From; b=I+VSEzq/NTGQu54YE0w3MXBVn+PoCx+L34mcYWaJ5MzgFiyaZMZ/mMTClKhdyA/Ky cNyXWEEUprw2Kv7PMK290nA4F4s35QulQcnQyYldDEdjh/vfnK146KChzFuPJ3jYP5 jf1yp1rYdNYFtm8gbrDqRTdhaCcjepoMSexrSE7zZAewYkloHqW0nobF5syQ0zMAlw oKMlY3CAuRxOKO+EohWIhI3C0io4TK3/vYBLq5x0gvybCcfUS4FmQBQmhJMgGjN3de 3GlPUbVd4NIbxRS5bLf48Ts0EriHxItQSPBD7wGxKqNfvzK49jyT/AfXL7RWHrOm5Y ZS1UvpbJQfSPg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 7B27A180078 for ; Thu, 15 Aug 2024 15:44:05 +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=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-pf1-f172.google.com (mail-pf1-f172.google.com [209.85.210.172]) (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 ; Thu, 15 Aug 2024 15:44:02 +0000 (UTC) Received: by mail-pf1-f172.google.com with SMTP id d2e1a72fcca58-70d1d6369acso1409480b3a.0 for ; Thu, 15 Aug 2024 08:42:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1723736534; x=1724341334; darn=lists.php.net; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=3+r9ftuIjq9vowbU4s4EDW/B5qhBmK9I+jVmz2Vw5Dc=; b=Wzf3iOJodsItFeFW++Shwa/vnywdhvdGHQRNEiKGpYbBZ0IyOIRHdkWxLT9gqPSVik I/6ba7PMpKztj4f+8YlsRicqMHnY495YhFm7+1qp3X7pdYfiprp2/8rTFIUky8NMMfHj uL4tZ2DOyCuZ5ELDEU3cqB7kJA0zOD01qPudWzhj48RP4dwIBmepY8+4LSKgwhIisTbq XqlWRG8xRgpZ6FD9Xrc0cBIGjyQUWAAhoe8fYXnOu6G6On8q4Drk84NIgCuALBqeVkfo uZ8Xl0QF/96jZezs+8tLVIMDdzcnwPK4tcJodM1CiZXFWTgck98iVbVunqvH88FlubzQ 9B/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1723736534; x=1724341334; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=3+r9ftuIjq9vowbU4s4EDW/B5qhBmK9I+jVmz2Vw5Dc=; b=qoi0daaXhgM8Jr21PbeGp4QVe+l2dkmIz0sDHxfMBj2kUxJD3LbLonzFrxzBJnk0vE bNkywPllvaeNisdKNWG5d8iEEBxQ/JxKp+egAmSgoCcf738HYO/PprQg8OU/SFXBAHIX kv6ky0n/DlNa8kb/CVNSYcHKKHBpKIGu5s6Zh8SE4BO04pyrs3PYGhis4kw3sv43U5Kl UuAar9MLASUrHxGiVgQh1Uh7pxKXzV8ieTO1XqMjlyCX+3Dz9KSk9yncU/tz/PL2Birn gxZDRPyJDnw2AsNTQMABjffJ0MHEe+kbjXCbNtw5SWRe7r67DnbAfXezokuZ9dOVkGGu iYrw== X-Gm-Message-State: AOJu0YzWnbGVJsukpBRE/71BjMs4UbRs1/TBJcI9paOMRbKgPdBzq8Y1 BD6rsDh0Rw6z6EKoCu+TCcH28gxfxrtJ4m+zr4xBqpTv5TGnZoDJ50C9gNA0KwJCjp1lRpBsoLI duBPWHv22CqvfjLayjtrC3Ek0dRtpVRg5i24= X-Google-Smtp-Source: AGHT+IE5W54dTrtRg1w+bYk4FJRxqdGeMo9hUdZ+53hroYwXQdFmwKp2WiG9njN+uppoBZ4xOpPRqM0nsl4xHRn7VtA= X-Received: by 2002:a05:6a20:1b03:b0:1c6:ed5e:24e with SMTP id adf61e73a8af0-1c8f859e5bdmr4995628637.7.1723736534276; Thu, 15 Aug 2024 08:42:14 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Date: Thu, 15 Aug 2024 17:42:02 +0200 Message-ID: Subject: [PHP-DEV] [RFC] On the need of a `is_int_string` ? To: PHP Internals List Content-Type: multipart/alternative; boundary="000000000000cfe27c061fbaaf66" From: misterdeviling@gmail.com (Vincent Langlet) --000000000000cfe27c061fbaaf66 Content-Type: text/plain; charset="UTF-8" Hi, When string is used as an array key, it's sometimes casted to an int. As explained in https://www.php.net/manual/en/language.types.array.php: "Strings containing valid decimal ints, unless the number is preceded by a + sign, will be cast to the int type. E.g the key "8" will actually be stored under 8. On the other 08 will not be cast as it isn't a valid decimal integer." This behavior cause some issues, especially for static analysis. As an example https://phpstan.org/r/5a387113-de45-4bef-89af-b6c52adc5f69 vs real life https://3v4l.org/pDkoB Currently most of static analysis rely on one/many native php functions to describe types. PHPStan/Psalm supports a `numeric-string` thanks to the `is_numeric` method. I don't think there is a native function to know if the key will be casted to an int. The implementation would be something similar (but certainly better and in C) to ``` function is_int_string(string $s): bool { if (!is_numeric($s)) { return false; } $a[$s] = $s; return array_keys($a) !== array_values($a); } ``` Which gives: is_numeric('08') => true ctype_digit('08') => true is_int_string('08') => false is_numeric('8') => true ctype_digit('8') => true is_int_string('8') => true is_numeric('+8') => true ctype_digit('+8') => false is_int_string('+8') => false is_numeric('8.4') => true ctype_digit('8.4') => false is_int_string('8.4') => false Such method would allow to easily introduce a `int-string` type in static analysis and the opposite, a `non-int-string` one (cf https://github.com/phpstan/phpstan/issues/10239#issuecomment-1837571316). WDYT about adding a `is_int_string` method then ? Thanks --000000000000cfe27c061fbaaf66 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi,

When string is used as an array key, it's s= ometimes casted to an int.
As explained in=C2=A0https://www.php.net/manual/en/la= nguage.types.array.php:
"Strings containing valid decimal ints,= unless the number is preceded by a=C2=A0+ sign, will be cast to the int ty= pe. E.g the key "8" will actually be stored under 8. On the other= 08 will not be cast as it isn't a valid decimal integer."

= This behavior cause some issues, especially for static analysis. As an exam= ple=C2=A0https://phpstan.org/r/5a387113-de45-4bef-89af-b6c52adc5f69
vs r= eal life=C2=A0https://3v4l.org/pDkoB=

Currently most of static analysis rely on one/many native php funct= ions to describe types.
PHPStan/Psalm supports a `numeric-string` thanks= to the `is_numeric` method.

I don't think there is a native fun= ction to know if the key will be casted to an int. The implementation would= be something similar (but certainly better and in C) to=C2=A0
```
fu= nction is_int_string(string $s): bool
{
if (!is_numeric($s)) {
= return false;
}

$a[$s] =3D $s;

return array_keys($a)= !=3D=3D array_values($a);
}
```

Which gives:
is_numeric(&#= 39;08') =3D> true
ctype_digit('08') =3D> true
is_in= t_string('08') =3D> false

is_numeric('8') =3D>= true
ctype_digit('8') =3D> true
is_int_string('8'= ) =3D> true

is_numeric('+8') =3D> true
ctype_digit(= '+8') =3D> false
is_int_string('+8') =3D> false
is_numeric('8.4') =3D> true
ctype_digit('8.4') = =3D> false
is_int_string('8.4') =3D> false

Such met= hod would allow to easily introduce a `int-string` type in static analysis = and the opposite, a `non-int-string` one (cf=C2=A0https://github.c= om/phpstan/phpstan/issues/10239#issuecomment-1837571316).

WDYT a= bout adding a `is_int_string` method then ?

Thanks
--000000000000cfe27c061fbaaf66--