rfc:inconsistent-behaviors
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
rfc:inconsistent-behaviors [2014/02/05 03:14] – yohgaki | rfc:inconsistent-behaviors [2014/02/16 07:26] – yohgaki | ||
---|---|---|---|
Line 25: | Line 25: | ||
Type juggling only works for INTEGER or HEX like strings. | Type juggling only works for INTEGER or HEX like strings. | ||
+ | |||
+ | Most problematic is HEX like strings being auto-coerced during | ||
+ | comparison, but using //different rules// from manual casting. That | ||
+ | is, ( 0x0A == " | ||
+ | although " | ||
+ | |||
+ | This despite http:// | ||
+ | states clearly that for number-string comparison, we " | ||
+ | strings and resources to numbers." | ||
+ | string patterns cannot be " | ||
+ | a " | ||
+ | casting for the same string. It is hard to view it is anything but a | ||
+ | bug that it does not. | ||
=== HEX === | === HEX === | ||
Line 157: | Line 170: | ||
https:// | https:// | ||
+ | |||
+ | Not only is this not a bug, it isn't even exceptional behavior on the | ||
+ | modern web. Users who find this behavior surprising are likely | ||
+ | inexperienced with MySQL -- clearly PHP's partner in server-side | ||
+ | ubiquity as part of the dominant *AMP stack -- which has the exact | ||
+ | same rules for auto-coercion of " | ||
+ | comparison context. | ||
+ | |||
+ | In MySQL (all supported versions): | ||
+ | |||
+ | <code sql> | ||
+ | SELECT CASE WHEN ' | ||
+ | </ | ||
+ | |||
+ | prints ' | ||
+ | |||
+ | There are other popular languages that follow the same | ||
+ | casting/ | ||
+ | coercion during comparison. For example, JavaScript | ||
+ | parseInt(' | ||
+ | SQLite, the ubiquitous embedded SQL database, also CAST( | ||
+ | ' | ||
+ | |||
+ | The SQLite documentation explains the logic well: | ||
+ | |||
+ | > When casting a TEXT value to INTEGER, the longest possible prefix of | ||
+ | > the value that can be interpreted as an integer number is extracted | ||
+ | > from the TEXT value and the remainder ignored. Any leading spaces in | ||
+ | > the TEXT value when converting from TEXT to INTEGER are ignored. If | ||
+ | > there is no prefix that can be interpreted as an integer number, the | ||
+ | > result of the conversion is 0. (http:// | ||
+ | |||
+ | And this behavior is not considered particularly " | ||
+ | |||
+ | Since the ubiquity of MySQL has been used to support the expectations | ||
+ | users should have of PHP, it's fair to note Oracle, SQL Server, and | ||
+ | PostgreSQL will not allow the above comparison to be performed: the | ||
+ | statement produces a fatal error. It's a runtime casting error: these | ||
+ | languages do not prohibit comparing values of different datatypes, as | ||
+ | long as the engine can cast the runtime contents of the value. Yet | ||
+ | such implementations, | ||
+ | concept, since a errant letter modifier like ' | ||
+ | error where the expectation might be to either have a ' | ||
+ | equal to 1 (as in MySQL) or fail gracefully (as in SQLite). In this | ||
+ | respect, the SQLite behavior is more balanced than that of | ||
+ | Oracle/ | ||
+ | generous, and reasonable. | ||
+ | |||
+ | With PHP and MySQL agreeing on this behavior, it is clear that | ||
+ | automatically coercing a " | ||
+ | better term) to a number via truncation is common practice on the web, | ||
+ | even if it is news to the inexperienced user. | ||
==== String decrements ==== | ==== String decrements ==== | ||
Line 233: | Line 298: | ||
https:// | https:// | ||
+ | |||
+ | |||
+ | |||
+ | ==== filter_var ==== | ||
+ | |||
+ | https:// | ||
+ | |||
+ | <code php> | ||
+ | var_dump(filter_var(' | ||
+ | var_dump(filter_var(' | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | bool(false) | ||
+ | double(1) | ||
+ | </ | ||
Line 241: | Line 322: | ||
- | ==== min() function | + | ==== min ==== |
https:// | https:// | ||
This is not a bug. If one of operand is BOOL(or NULL), both operands are converted to BOOL and evaluated as BOOL. It may be good idea that document this behavior in min() manual. | This is not a bug. If one of operand is BOOL(or NULL), both operands are converted to BOOL and evaluated as BOOL. It may be good idea that document this behavior in min() manual. | ||
+ | |||
+ | **Status** | ||
+ | Documented. | ||
+ | |||
+ | http:// | ||
+ | |||
+ | |||
+ | |||
==== Return value of wrong internal function/ | ==== Return value of wrong internal function/ |
rfc/inconsistent-behaviors.txt · Last modified: 2021/03/27 14:31 by ilutov