RU beehive logo ITEC dept promo banner
ITEC 325
2019fall
ibarland

php’s slippery types

summary

Takeaway points: video: turn on error-reporting! (7m52s)

There are some things that are not an error, but should be. For example: var_dump( $iNeverDefinedThisVariable + 47 ); or var_dump( $notAnArray[9+$notAnIndex] + 47 ); or var_dump( strlen(heyThisHasNoQuotesSoIsNotReallyAString) );.

This means that if you ever mis-type a variable name, you won't get an error, but instead PHP will happily proceed as if nothing is wrong1.
PHP does not have your back.

Solution: Fortunately, people figured out that PHP's default behavior is unforgiveable, and added a switch to turn the above three behaviours into errors, as they should be: error_reporting(E_ALL);. Put this line at the top of all your PHP files, and save hours of headaches later.

Types in php

video: type conversion in php (15m38s)

PHP is dynamically typed: that is, it figures out the type of values at run time — whether an expression evaluates to a boolean, int, float, string, arrays, or object. (Contrast that with Java, which is statically typed: it knows the type of each value at compile-time, since the programmer is required to state the type each variable will hold, and the type returned by a function, and the type that must be passed in to each function.) So a PHP variable can hold an int at one moment in time, and later hold a string; a function might return a string sometimes and return a boolean other times, etc.. Javascript, python, and racket are other dynamically-typed languages.

aside: Some people say that PHP is “untyped”; that is wrong. It is always aware of the type of any value. PHP has the types you might expect, including boolean, int, float, string, arrays, objects.2 Sometimes people (erroneously) say PHP is “weakly typed”. They might be trying to say “dynamically typed”, or they might be trying to say “PHP is particularly fast-and-loose about type conversions.”. It is true that PHP does significantly more “type juggling” than most sane languages.

Conversion between strings and integers:

var_dump( "hello" + "world" );
var_dump( 12 + 3 );
var_dump( "12" + "3" );
var_dump( "12" + 3 );
var_dump( "12hello" + "3world7" + "nevermind92" );

var_dump( strlen(37) );
     
Remember: PHP does not have your back.

Rationale:

The solution: If you have a string, use is_numeric along with type casting.

Booleans: Many values, if used in a boolean context, are "false-ish":

var_dump( false == false );
var_dump( false == 0 );
var_dump( false == 0.0 );
var_dump( false == "0" );
var_dump( false == array() );
var_dump( $someUndefinedVar == false );   // ?!
    
Be careful:
var_dump( false == 0 );           // true, as just noted.
// == is not transitive (!):
var_dump( 0 == "00" );            // true.
var_dump( false == "00" );        // false?!

var_dump( 0 == "-0" );            // true.
var_dump( false == "-0" );        // false?!

var_dump( 0 == 0.0 );             // true.
var_dump( false == "0.0" );       // false?!
    

Caution: There are also the boolean operators with spelled-out names, AND and OR. Do not use them! They are just like &&, || except that they have unexpectedly low precedence (less than the assignment operators3 Use parentheses to force precedence if you are doing something unusual (or even, just use parentheses routinely, so that you never even need to think twice about precedence!).

Upshot: PHP has ===, which does comparison suppressing any type-casts. Using this avoids unexpected results; when you want to convert you can call conversion-functions explicitly.


1 In human law, if you know something is wrong and don't report it, it's often criminal negligence. Why we don't hold PHP or certain other languages to the same standard, I don't know.      
2 Though PHP does not have the type "char"; it just has strings-of-length-one. It makes one wonder: When creating a string, what does php think it's stringing together?      
3 So $x = false || true; is fine; it means So $x = (false || true);, and $x gets the value true. But $x = false OR true; means ($x = false) OR true;, which means $x gets false but the entire line returns true if used in some bigger context. (Btw, using the result of assignment in a bigger context is rarely a good idea; it's a holdover from more primitive I/O libraries that didn't have any peek/hasNext functionality.)
Bottom line: use && and ||, and use parentheses if you need some unusual precedence.      

logo for creative commons by-attribution license
This page licensed CC-BY 4.0 Ian Barland
Page last generated
Please mail any suggestions
(incl. typos, broken links)
to ibarlandradford.edu
Rendered by Racket.