4 ms·
Stupid PHP tricks: (true == false)
- wvenable 18y agoOnly programmers who don't regularly use PHP seem to be bothered to point this out. Why don't PHP programmers care? Because PHP is a weakly typed language that operates in an environment where most of the data comes in as strings. More often than not, the double equals does exactly what you intend it to do. Programmers who use the triple equals in PHP for all comparisons have entirely missed the point.
- ajross 18y agoTo be fair: PHP got the implicit conversion thing from perl, which has saner semantics. A lot of the confusion in the article is with things like: ("string" == true) evaluating to true. (Although your guess is as good as mine as to why the author was surprised by 0 == false). The reason that looks weird isn't because of the dynamic conversions, but because PHP decided it wanted to look like a statically typed language and added junk like boolean constants. In an implicit typing scenario, you don't have separate constants for different types. In this case, the "booleanness" of the thing is a property of the expression (the == operator, being evaluated inside of an if(), etc...), not the data.
- wvenable 18y agoI love boolean constants for assignments, but I think you've got a good point with regards to comparisons. Rarely, in real PHP code, do you see comparisons involving boolean constants. Most of the time, you just do this: if ($var) { dothis(); } if (!$var) { dothis(); } The constants are definitely adding to the confusion. However, only in these contrived examples does one compare numbers and strings with boolean constants. The type conversion is logical, it just looks funny.
- nuclear_eclipse 18y agoYes and no. You will see the boolean keywords (they aren't actually constants) is the case making sure actually is a boolean, not a string/int. $x = ""; if ( $x == false ) {} #yes if ( $x === false ) {} #no Edit: this is very useful for allowing a string search/manipulation function to return an error condition. $str = string_function(...) if ( $str === false ) { #error } else { #continue processing $str }
- ajross 18y agoYeah, but that's a little mixed up, like a lot of PHP. That function returns a string, and something "not a string" to indicate completion. The standard way this is done in sane languages is to declare a nil reference (null pointer, whatever, undefined constant, etc...) that is guaranteed to be distinct from all strings, not to overload a "boolean" on top of a function that returns things that can be implicitly converted to a boolean in the first place. Perl, for example, would write that test as "if(defined $str) {...}". The point being: strings and booleans are an overlapped type space. If you want something outside that space, the proper choice is not a boolean.
- nuclear_eclipse 18y agoWell, if you prefer it that way, there is a 'null' keyword as well that does exactly what you want: $str = string_function(...); if ( is_null( $str ) ) {} if ( null === $str ) {} Just a matter of preference.
- ajross 18y agoTo be clear: it's a matter of correctness, not preference. Using a boolean constant to represent "not a string" when there are legal string values that are equal to that constant is a design bug, that you are working around via the identity operator. I'm happy that PHP has a null; less so that you don't see value in using it where it's required.
- briancooley 18y agoAlthough your guess is as good as mine as to why the author was surprised by 0 == false I don't think he was surprised. Based on the post title, I gathered that he was just using that fact to set up an oddity. The point here seems to be merely that non-empty strings can evaluate to true or false depending on whether they are typecast during the comparison. But that's less of an attention-grabber than true == false, particularly since the latter is patently false in PHP.
- ashu 18y agoWe have used PHP extensively, and have been bitten by the confusing semantics of "==" more than once. By now, we have diffused these problems, but they did trump us quite a bit.
- djo 18y agoPHP's been my primary language since PHP3. The post is meant as a wry observation (and to blow off some steam) rather than an attack. Yes, we all instinctively work round PHP's oddities by now, but you've got to admit, "more often than not the operator does exactly what you intend it to" isn't something you want to hear in relation to a programming language. A bit of rigour is no bad thing.
- ars 18y agoThe rules are confusing, but if you want it loosely typed there isn't much else you can do. I have a few things I would change: empty('0') should be false not true if('0') should be true as well Comparing a string and int should convert the int to a string not the other way around. But mostly the rules are logical.
- nuclear_eclipse 18y ago> Comparing a string and int should convert the int to a string not the other way around. No: '0007' == 7; #true By your logic: '0007' == 7; #false, wtf? And why the hell should `empty('0')` return false?! emtpy() determines if the value contains something. I would most certainly think that a string with even one character is not empty, even if it's a space.
- ars 18y agoI think you got the logic on empty backward :) Right now empty('0') is true - meaning php thinks it's empty (because '0' turns into 0 which turn into false). I think it should be the other way around, and so do you except you read what I wrote backwards. And I understand the problem of '0007' - but 'abc' == 0 is worse. Most of the time things in php are strings. If you know you'll have leading zeros, then you also know it once was a string, and you'll take measures like intVal. You need intVal to avoid SQL injection attacks anyway.