Title: The problem of untyped languages: PHP empty() function
Slug: the-problem-of-untyped-languages-php-empty-function
Date: 2009-03-30 11:07:00
Author: Kartones
Lang: en
Tags: Development, PHP, Patterns & Practices
Description: The problem of untyped languages like PHP, exemplified by the empty() function, which can lead to unexpected results.

 <p>There are a few programming languages that work nicely <a href="http://en.wikipedia.org/wiki/Programming_language#Typed_versus_untyped_languages">without typing</a> (for example, Javascript or PHP). They have their advantages, but I just can't put them on the same level of a strongly typed language like C# or Java, and here is an example that any PHP developer will suffer sooner or later.</p>  <p>In PHP, we have a function to determine if a variable has no value, <a href="https://www.php.net/manual/en/function.empty.php">empty()</a>. But most experienced PHP developers will advise you to never use it. Why? Let's see an example:</p>  <p><font face="Courier New">&lt;?php      <br>$test1 = '0';       <br>$test2 = false;       <br>      <br>if (!empty($test1)) {       <br>    echo $test1.'&lt;br /&gt;';       <br>} else {       <br>    echo 'test1 is empty&lt;br /&gt;';       <br>}       <br>if (!empty($test2)) {       <br>    if($test2) {       <br>        echo 'true';       <br>    } else {       <br>        echo 'false';       <br>    }       <br>} else {       <br>    echo 'test2 is empty&lt;br /&gt;';       <br>}</font></p>  <p><font face="Courier New">?&gt;</font>     <br></p>  <p>This code looks correct. We create a string variable (<font face="Courier New">$test1</font>) and a boolean one (<font face="Courier New">$test2</font>). We check their values and output different messages depending on their content. But can you guess the output? </p>  <p>"<i>testx is empty</i>" in both cases.     <br>The reason is that, in PHP, false equals empty too, and as there is no typing, a string containing only a zero will be interpreted as a false (exactly, like a "zero byte", "<font face="Courier New">\0"</font>), and thus, <font face="Courier New">empty()</font> will return <font face="Courier New">true</font>.</p>  <p>So, what's a correct way to check for empty variables AND handle this special cases? Another small example:</p>  <p><font face="Courier New">&lt;?php      <br></font></p> <font face="Courier New">$test1 = '0';    <br>$test2 = false;</font>   <p><font face="Courier New">     <br>if (isset($test1) &amp;&amp; $test1 !== '') {       <br>    echo $test1.'&lt;br /&gt;';       <br>} else {       <br>    echo 'test1 is empty&lt;br /&gt;';       <br>}       <br>if (isset($test2) &amp;&amp; $test2 !== '') {       <br>    if($test2) {       <br>        echo 'true';       <br>    } else {       <br>        echo 'false';       <br>    }       <br>} else {       <br>    echo 'test2 is empty&lt;br /&gt;';       <br>}       <br>?&gt;</font></p>  <p>The <a href="https://www.php.net/manual/en/function.isset.php">isset()</a> function works much better, as checks for a specific <font face="Courier New">null</font> value. Using <font face="Courier New">===</font> or <font face="Courier New">!==</font> we force that both parameters have to be of the same type (although not typed, PHP supports casting and type checks to aid us). And finally, as PHP implements <a href="http://en.wikipedia.org/wiki/Lazy_evaluation">lazy evaluation</a>, we don't need to worry about comparing a null against a string because <font face="Courier New">isset()</font> will catch it first.</p>  <p> </p>  <p>As with most programming languages, there are ways to do things right. But I can't stop thinking why the PHP team doesn't at least improves the code of the <font face="Courier New">empty()</font> function to make it work properly and instead add new functions. Compatibility with crap only makes crap still available, doesn't fixes it.</p>
