The PHP Classes: Iteration #1

IMPORTANT! Both the Database Class and Record Class has already been updated with newer versions!

One of the first things I said when posting the PHP Class series #1 was that none of the classes were in any way perfect or flawless. So, here is Iteration #1 containing a few error fixes and upgrades for the PHP Class series #1. We are going to start in the Database Class fixing one error and make sure the char set between our MySQL database and web application works as it should. We begin with the simple, yet annoying, error found at line 58 in the fetch_field_name() function found in the database.php file. Instead of assigning $i = 1 we assign it to 0. This error appears when we use the fetch_field_name() function in our Record Class. What the error does is simple: The table column name starts with 0 not 1. That means we are discarding the first column in the table we are fetching our fields from. Of course we want to include all fields in our function therefore:

Replace:
for($i = 1; $i < mysql_num_fields($result); $i++) {

With:
for($i = 0; $i < mysql_num_fields($result); $i++) {

Next is our char set fix. Even though the MySQL database table has UTF-8 as default charset and utf8_general_ci as collation and every field in the table has the same settings including the web application page I still had trouble converting the Swedish chars åäö correctly. After reading on the MySQL web site about this issue they suggest calling a query just after my web application did the connection to the MySQL database. This query looks like this:

Query fixing the char set problem:
$this->query("SET NAMES 'utf8'");

What it does is telling the server and the client that between us two out of this moment we are going to send data using the UTF-8 encoding. This solved the problem. Another reason to encounter char set and encoding issues is when saving the actual web application file. You should always save your file in UTF-8, not ANSII or anything else. That’s the very first thing I do when I get an error about char sets. The code above should be included in the __construct() function just after we have connected to the database.

Moving on to the Forms Class. After the error fix in the Database Class we need to do an update in the generate() function too. At line 75 in the forms.php do the following:

Replace:
$value = $values[$i-1];

With:
$value = $values[$i];

This makes sure we set the correct default values into the fields when we auto generating. Since we jumped over the first column before we had to use -1 to fix that, now when the error is found we enter a much easier code and the problem is fixed. We continue working in the same function and we just move a few lines down to line number 87. The error is this: As soon as we encounter a data type = file we add “(exists)” to the label, that is wrong. We only want to add “(exists)” if the file actual already exists. To correct this we do:

Replace:
$fdo['exist'] = !empty($value) ? $value : '';
$label .= ' (exists)';

With:
if(!empty($value)) {
$fdo['exist'] = $value;
$label .= ' (exists)';
}

The next error is in the draw() function. At line 170 I forgot to add the action attribute. So, do this:

Replace:
$draw .= "<form id=\"$this->id\" name=\"$this->id\" method=\"".strtoupper($this->method)."\" $enctype>";

With:
$draw .= "<form id=\"$this->id\" name=\"$this->id\" action=\"$this->action\" method=\"".strtoupper($this->method)."\" $enctype>";

Next we go to the Record Class. In the __construct() function at line 14. Since we did our change in the fetch_field_name() function we don’t need to add the $primary as a field.

Remove:
$this->fields[$primary] = null;

Replace:
$this->id = 0;

With:
$this->id = null;

We replace the default value on the private class variable $id to null because we don’t know if the primary is actual an integer or a string. Looks a lot better giving it the null value too. We continue the search for bugs and go down to the set() function and line 60. If we have a image saved in the database we don’t want to add this image every time we do an update. If the image exist we just format the current value with the mysql_real_escape_string and returns it, if the value is new we do an update. This is done doing this:

Replace:
if(array_key_exists($file, $this->fields)) {

With:
if(array_key_exists($file, $this->fields) && ($value['size'] != 0)) {

And at line 64 add:

else {
$this->fields[$file] = mysql_real_escape_string($this->fields[$file]);
}

This will fix our goals we had above. But, does this mean you can’t remove an already existing blob in the database just sending the null value? Yes, that is true, we need to do something else when we want to remove a blob from the database, this “something” hasen’t been created yet. :)

The next fix is a bit bigger. First off, we don’t want to save empty strings in the database, it’s much better saving null values. Before we weren’t saving fields with an empty value at all. Now if a field is empty it gets null as it’s default value. Since we changed the default value of the $id variable we cannot do the check with == 0, we need to use the built-in PHP method is_null() to see if we want to insert or edit a record. Lastly we add an extra line updating the id on a record when we insert a new entry. The updates is made in the save() function.

Code describing a update on the save() function

Lastly we need to update the delete() function to.

Replace:
if ($this->id != 0) {

With:
if (!is_null($this->id)) {

All done in the Record Class. And that’s it for now. You can download the updated files below. Please help me find bugs and report them. Thank you! Enjoy!


About this entry