On Thu, Mar 29, 2012 at 12:19 PM, Stuart Dallas <stuart@xxxxxxxx> wrote: > On 29 Mar 2012, at 17:57, Arno Kuhl wrote: > >> I found automatic typecasting can be a bit of a gotcha. >> >> >> >> $sText = "this.is.a.test.text"; >> >> if ( $pos = strpos($sText, "test") !== FALSE) { >> >> echo substr($sText, 0, $pos)."<".substr($sText, $pos, >> strlen("test")).">".substr($sText, $pos+strlen("test")); >> >> } >> >> >> >> The code seems logical enough, and the expected result would be: >> >> this.is.a.<test>.text >> >> >> >> In fact it ends up being: >> >> t<his.>is.a.test.text >> >> >> >> The reason is $pos is typecast as TRUE, not int 10, presumably because it's >> in the same scope as the boolean test. >> >> Then when $pos is later used as an int it's converted from TRUE to 1. >> >> >> >> You have to bracket the $pos setting to move it into its own scope to >> prevent it being typecast: >> >> if ( ($pos = strpos($sText, "test")) !== FALSE) { >> >> >> >> No doubt it's mentioned somewhere in the php manual, I just never came >> across it. >> >> Just thought I'd highlight one of the gotchas of auto typecasting for any >> other simpletons like me. > > This is not due to typecasting, it's due to operator precedence. > > In PHP (and many other languages) the !== comparison operator will get done first, so the result of that comparison will be assigned to $pos. By introducing the brackets you're explicitly specifying the order. > > Details here: http://php.net/operators.precedence > > -Stuart > > -- > Stuart Dallas > 3ft9 Ltd > http://3ft9.com/ > -- > PHP General Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php > Interestingly enough (again due to precedence + LR processing) if you reverse the order of the test: if (false !== $pos = strpos($sText, "test")) it works! But I'm not sure it's a good idea to rely on that, as the extra bracketing is probably more obvious to the reader. -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php