note 30352 deleted from language.operators.logical by colder

From: Date: Fri, 20 Apr 2007 15:38:53 +0000
Subject: note 30352 deleted from language.operators.logical by colder
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-125696@lists.php.net to get a copy of this message
Note Submitter: shadedecho ---- It appears (after much frustrating but ultimately helpful searching and discussion on forums like tek-tips) that the || and the && are "short-circuited" as has been previously noted BUT the | and & operators (documented by PHP as bitwise operators) behave as their non-short-circuited counter-parts, respectively. ex: function blah() { echo "hello< br>"; return "from blah()< br>"; } function blah2() { echo "world\< br>"; return "from blah2()< br>"; } $a = ""; if ( ($a .= blah()) || ($a .= blah2()) ) { echo $a; } This would result in the following output: hello from blah() Notice the "world" didn't get echo'd and the "from blah2()" didn't get concat'd into the $a variable, because the first assigment to $a was successful, so the "short-circuting" kicks in and the boolean test terminates without evaluating the rest of it. HOWEVER, if you replace || with just | in that "if" statement, you get the output: hello world from blah() from blah2() Eureka! all parts of the boolean test are evaluated, in expected left-to-right fashion, and following all the normal precendence rules, so far as I can see. This makes total sense... Using the bitwise operators, what is occurring is the bitwise-level operation on the result of two non-bitwise operations (the assignments). If a non-bitwise operation returns null (in other words, the value being assigned turns out to be null or 0), the bitwise operator would bind to that (or more appropriately, would "see" it) as a "0", otherwise it would see a non-zero (string of bits with at least one "1" in it). Then a bitwise | is done on the two values, and if either is non-zero (has "1" bits in it) then the result will have those "1" bits in it (non-zero), and the if statement will interpret any non-zero value as true in a boolean test. Likewise, if both operands to the | were null or 0, then the result would be a zero value, which "if" would interpret as false. The if statement above is doing a bitwise | on (in this case) two non-zero values (with "1"s in it at the bit level), so the | operation returns a non-zero value which is then reinterpreted by the if statement as TRUE! So, in this special case where you are trying to string together non-short-circuited boolean tests, these operators work on their operands at the bitwise level, and since they are not comparison operators but mathematical operators, they can't be short-circuited, and the resulting behavior is a non-short-circuited "boolean test". I know, you must think I am crazy for trying to get around a built-in optimization like this, but I assure you there is a very good reason for it, and if you are interested, you can check out this thread as I have a very long post in there which explains what I was trying to do: It is the 9th post down, where you will find my description of my database query'ing which i was wanting to optimize. http://www.tek-tips.com/gviewthread.cfm/lev2 /4/lev3/31/pid/434/qid/500825 (note i had to split that URL for the post, but it should be all together on one line obviously)

« previous php.notes (#125696) next »