The False String
Article Index
The False String
Solution

Banner


Solution

You might have been wondering about the use of the assignment in the if statement but this is just a red herring.

The problem is caused by the simple fact that not all non-null types are treated as true. In fact the rule is that all values convert to true except for:

  • the boolean FALSE itself
  • the integer 0 (zero)
  • the float 0.0 (zero)
  • the empty string, and the string "0"
  • an array with zero elements
  • an object with zero member variables (PHP 4 only)
  • the special type NULL (including unset variables)
  • SimpleXML objects created from empty tags

Notice that the integer value 0 is equivalent to false. Now consider what happens when the target in our example is "a"

$string="abcdefg";
$target="a";
if ($result=strpos($string,$target)){
echo("found ".$result);
}else{
echo("not found ".$result);
}

In this case the result of strpos is zero which is what is stored in $result but zero is converted to false and so the message "not found" is displayed.

This may be a well known PHP trap waiting for the beginner but it is also a "feature" that comes back to bite many an advanced programmer who has forgotten the basic type juggling rules for false.

Notice the code extract is behaving exactly as it should it is just that in trying to be compact the programmer hasn't expressed the algorithmic idea correctly.

How should you best fix the problem?

The programmer who originated the code wanted to save it at all costs and so came up with the ingenious idea of simply adding one to the result to avoid the zero result! That is:

$string="abcdefg";
$target="a";
if ($result=strpos($string,$target)+1){
echo("found ".$result);
}else{
echo("not found ".$result);
}

This works but... the non-standard position in the string i.e. starting counting from one rather than zero, is another disaster waiting to happen! In addition the resulting code is messy and misleading.

It is much better to write:

$string="abcdefg";
$target="a";
if (($result=strpos($string,$target))!==false){
echo("found ".$result);
}else{
echo("not found ".$result);
}

This shows exactly what the intention is.
Also notice that you can't make the example work using the test for inequality != operator only the exact inequality operator !== will do. The reason is, of course, that the != operator will still perform the type juggling conversion of 0 to false and fail in exactly the same way as the original problem.

Pattern

The pattern to adopt to avoid this particular type of problem is fairly easy - always write exactly what you mean and never try to save typing by writing a compact form that relies on implicit type conversion rules. 

That is if the condition is "function is false" actually write:

if(function()===false){}

and not

if(!(function)){}

or

if(function()==false){}

The only exception to this rule is if function is a predicate and only returns true or false. Then no type conversion rules come into play and you are safe to use the Boolean value directly.

There is a very strong argument that automatic type conversion should never apply to convert to Boolean.

 

Banner

 More Puzzles

C++
Strange initialization

Are you always speaking the same syntax as your compiler? This C++ puzzle looks at how you can put things together thinking they mean one thing when in fact they mean another...


Sharpen Your Coding Skills
Merkles and Social Engineering

Joe Celko has come up with a math puzzle based on one of the current political hot topics - but let the team from International Storm Door & Software explain the problem of faced by planners who w [ ... ]


Sharpen Your Coding Skills
Sharpen your Coding Skills - Elevator Puzzle

Introducing Melvin and Bugsy, characters who are the creation of Joe Celko who has joined the team to give you an opportunity to sharpen your coding skills with puzzles that will both amuse and tormen [ ... ]


Other Articles


<ASIN:0470395095>

<ASIN:1932394753>

<ASIN:0596006810>

<ASIN:0672329166>


  



 
 

   
RSS feed of all content
I Programmer - full contents
Copyright © 2014 i-programmer.info. All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.