May 21 2009

NULL in PHP

In many programming lanugages there is a keyword for something which is empty, not set or an invalid pointer. So, there is null in Java, nil in Ruby, None in Python and finally NULL in PHP. Although they somehow appear to describe the same thing - be aware of their differences when switching from one programming language to another.

For example, in C++ NULL is defined as the number zero :

#define NULL 0

In PHP however, NULL is a datatype. The only possible value of NULL is NULL. That means if you assign NULL to a variable you unset the variable while assigning to it the value and type NULL - and not zero. The trapfall however is, that you need to be careful if you are checking a variable for a NULL value/type.

$var = NULL;
if ( NULL == $var ) echo "Var is NULL";
// outputs Var is NULL

The if-clause is true in this case - but this check is error-prone. Look at the following check:

$var = 0;
if ( NULL == $var ) echo "Var is NULL";
// outputs Var is NULL

This if-clause is true as well, since PHP just checks if the value of NULL and $var is equal. The converted integer value of NULL is 0

echo (int)NULL;
// outputs 0

Therefore the if clause is true. To really test if the values are equal and the type is identical you need to use the “===”-comparison operator of PHP.

Alternatively, you can use the php function is_null() to determine if a variable is of type NULL.


Jan 22 2009

Trapfall in using PHP’s is_int() function

When processing data, especially from formulars or general user input, it is sometimes necessary to determine if a given value is of a certain type. In case of IDs for example there might be the need to check if a given id is of type Integer or not.

Since PHP does not require (or support) explicit type definition in variable declaration functions that checks for a certain type are a tricky topic. I saw a lot of code where people tried to use the PHP function called is_int() in that case. However is_int() should be used with great care. This function only returns true if a given value ($val) is initiated like the following:

$val = 1; // Without quotation marks

Processing form data

I did some research on it and found out that is_int() seems to work only with variables which are initialized in above’s way. However, the major domain where PHP coders might want to use the is_int() function is in
validating user- or form-data. For example have a look at the following URL:

http://localhost/index.php?id=1

If you validate the id in index.php with is_int() it will always return false:

That is because PHP seems to consider every user data passed from forms or simply via GET parameters as strings. So, do keep this in mind using the is_int() function.

Processing database data

In addition I ran a test to determine the types of the fields of simple mysql result sets. Although a field is defined in the mysql database as an Integer field is_int() will not work with it. Have a look at the following code snippet.

1
2
3
4
5
6
7
8
9
10
$res = mysql_query($sql);
$row = mysql_fetch_row($res);
// First field is of type Integer in mysql
(is_int($row[0])) ? print("int") : print("No int");
print (gettype($row[0]));
print (mysql_field_type($res, 0));
// This program outputs:
// No int
// string
// int

In line 1 and 2 I get the data of a row. Assuming that the first field is set to hold only Integer values in the database table, line 4 prints out No Integer. Line 6 prints out why. PHP treats this value as a String again. However, line 6 assures us that the mysql field type is of type Integer. So, again - the use of is_int() function is rather useless in such a case.

I saw some people that tried a work-around with casting values to integers, but casting a value to an integer always ends up in a valid integer value. That means casting e.g. (int)”Test” will result in 0, which is of course a valid integer value. So, casting in that case totally misses the point.

Conclusion

In summary, I recommend not to use the is_int() function to process and validate form data. Personally I use the is_numeric() instead, although they are not identically. If you deal with data which come from databases there are two possible solutions I can think of. The first one would be also the usage of is_numeric() instead of is_int(). The second one would be a little bit more complex work-around. You could always check the mysql_field_type() if it is an integer and assume that all data from that field are of that type. If you place such a general check at a central place in your database abstraction layer, this might be a good solution.

In the end, I really wonder what the purpose of is_int() is. The only use I could think of would be in the following context:

$val = 10;
if ( is_int($val) ) echo "It's an integer";

Use the results of my research at your own risk. Maybe I overlooked something in this issue. Well, this is open for discussion ;-)


Dec 25 2008

Implement autorun for shadowbox via URL parameter

As you probably already realized I used the javascript lightbox engine called ShadowBox to show my media content. I really love this engine and I think it belongs to one of the best lightbox javascript engines around. One drawback of such engines is though - that they are normally launched when the visitor actively pressed a relative link. I thought it would be nice if you could spread a link url that directly links to the activated shadowbox content.

After reading the doc page of shadowbox - I realized that it is possible while adding the appropiate Shadowbox.open method to the windows onload event. That’s why I implement the following hacky code that I added to the header.php file of my wordpress installation. With this code I check for the existance of a sbx_run parameter in the get request which should contain the filename of the flash file to load. I also check for height/width values. (Note: You could easily add more flexibility to it - like setting the various shadoxbox player types et cetera).

<?php
  // Quick hack to implement direct shadowbox autorun via URL parameter
  // benny!weltenkonstrukteur.de
  // Disclaimer: Use code at your own risk!
  if ( isset( $_GET['sbx_run'] ) )
  {
     // Construct url of swf content to play
     $sbx_content = "http://www.weltenkonstrukteur.de/wp-content/uploads/" . urldecode((string)$_GET['sbx_run']) . ".swf";
 
     // Retrieve width/height parameter
     ( isset($_GET['sbx_width']) ) ? $sbx_width = (int)$_GET['sbx_width'] : $sbx_width = 520;
     ( isset($_GET['sbx_height'])) ? $sbx_height= (int)$_GET['sbx_height']: $sbx_height= 390;
 
     echo '<script>
           window.onload = function()
           {
              Shadowbox.init(shadowbox_conf);
              Shadowbox.open({
              player:     "swf",
              content:    "' . $sbx_content . '",
              height:     ' . $sbx_height . ',
              width:      ' . $sbx_width .'
             });
           }
         </script>
        ';
  }
?>

So, using this techinque I could directly start the rotozoomer of the previous post with the following URL:

http://www.weltenkonstrukteur.de/2008/12/rotozoomer-in-actionscript30/?sbx_run=2008%2F12%2Frotozoom

Important:
Use this code at your own risk. Including content in the way I did is very open for cross-site-scripting (XSS) and therefor makes your website vulnerable. Please keep this in mind.