It is a well-known feature that you can work with such data without
previously converting it explicitly to some number type.
I'm not requesting to change this: if you're doing string("3.5") + int(7),
you should still get float(10.5). What I'm suggesting we change, is
comparison of numbers and decimal strings.
Thinking about this a bit more, what about following JavaScript semantics?
I find them really good in this respect:
- when comparing two strings, always use
strcmp()
:
var_dump("42" == "42.0"); // false
var_dump("3" < "23"); // false
- when comparing a number with a string, cast the string to a number, then
compare:
var_dump(3 < "23"); // true
var_dump("3" < 23); // true
var_dump(42 == "42"); // true
var_dump(42.0 == "42"); // true
var_dump(42.5 == "42.5"); // true
var_dump(42 == "42.0"); // true
- if the string does not represent a valid number, always return false:
var_dump(42 == "42x"); // false
var_dump(42 == "x42"); // false
var_dump(1 >= "abc"); // false
var_dump(1 < "abc"); // false
Note: JavaScript actually allows leading & trailing whitespace around the
number:
var_dump(42 == " 42 "); // true
On this last point, I'm not sure whether we should allow both leading &
trailing whitespace, or disallow both of them.
Other than that, I love the way they handle implicit conversions here. It's
so much more understandable, easy to remember, and less prone to errors IMO.
Ben
Le 27 mars 2019 à 00:09, Benjamin Morel benjamin.morel@gmail.com a
écrit :
- I would also strongly suggest that 2 strings are always compared
byte-by-byte; IMO it does (somehow) make sense that 42 == "42.0", but
it
DOES NOT make sense that "42" == "42.0". (...)
There are many ways to obtain numeric data in the form of a string from
external sources (HTML form, database, CSV, ...) and even internal sources
(bcmath, ...)—and note that, even when such numerical data may have a
decimal part, it does not mean that they are imprecise. It is a
well-known feature that you can work with such data without previously
converting it explicitly to some number type. That works pretty well in PHP
(well, except that you get intermittent obscure bugs when some third-party
code in the same thread plays with setlocale()
, but that's another
story...) If we cease to compare numeric strings numerically, I expect that
much code will begin to break more or less subtly, and will need to be
thoroughly reviewed in order to be corrected. We must not change that.
The core issue is that “==” is fundamentally ambiguous: should it compare
as number, as string, as reference, ...? If we were to redesign PHP from
scratch, we may decide other semantics than the current one (e.g., use
distinct operators for comparing numerically and textually, as does Perl).
But where we are now, the best thing to do is to follow the common wisdom:
If you want to compare strings as strings, just use “===”. Or strcmp.
—Claude