PHP: Turning Bad Code into Good

25 07 2017

You don’t have to write beautiful or elegant code in PHP. In fact, some would argue that PHP would never win a beauty contest. Yet, one might argue that beauty is a marker for health, so beautiful, elegant code may indicate something about how robust the code is.

The following snippet contains a number of errors.. See if you can spot them:

 $fruit = array()
 $fruit[1]="apple"; $fruit[2]="peach"; $fruit[3]="orange";
 $slist = array($fruit[1],$fruit[2],$fruit[3]);
 $i=0;
 while ( $i < 3 ) {
   if( isset( $slist[$i] ){
       echo 'The meal includes a/an' . $slist[$i] ;
   }
   else {
      echo 'No fruit today'}

One of the errors may not be so obvious: omitting to turn on error reporting. Had the user done so, then the developer might have had a clue as to what was necessary to make the code work correctly. Although, I’ll be the first to admit that unless one is an experienced user, the first error message that displays may seem a bit cryptic:

Parse error: syntax error, unexpected ‘$fruit’ (T_VARIABLE) in … on line 4

Without the semi-colon after “array()”, the parser sees code like this:

$fruit = array()$fruit[1]=15;

Now the complaint about the “unexpected ‘$fruit'” makes more sense. After more than two decades, it would be wonderful if users could get a simple, direct message informing about a missing colon.

The funny thing is that in the C Programming language, one of PHP’s predecessors, if one neglects to terminate a statement with a semi-colon, a precise and helpful error message displays:

In function ‘main’:
Line 5: error: expected ‘;’ before ‘printf’

See here.

Perl is another language that influenced PHP’s development. Apparently, PHP follows Perl regarding a failure to identify the missing colon. When I run the following code:

print("\nNewlines start new lines\n")
print("\nCarriage Returns do not\n");

The error message hints at where the problem may be without going into detail, raising this sort of error message:

syntax error at line 2, near “)
print”
Execution aborted due to compilation errors.

See demo.

Perhaps, if one makes the PHP code more concise, utilizing helpful features, such as short-array syntax one might have an easier time spotting a missing semi-colon. So, I suggest assigning an array to $fruit with the following code:

$fruit = [];

While there is nothing incorrect with the next line which initializes three array variables, taking the linear approach makes it more difficult to quickly discern what the code seeks to do. The following vertical format is much easier for human eyes:

$fruit[1] = "apple";
$fruit[2] = "peach";
$fruit[3] = "orange";

The next line also has nothing incorrect, but it could be improved:

 $slist = array( $fruit[1], $fruit[2], $fruit[3] );

Instead of taking three array variables and dropping them into another array and then assigning that newly created array to a variable, so that $slist contains three values and its first element has an key of zero, one could code as follows:

$slist = array_values( $fruit );

The result is the same but attaining it requires less code, and is less prone to coding errors since there is less minutia like specifying the array keys of $fruit.

The line assigning zero to $i is fine but it could use some spacing, as follows:

$i = 0;

Adding white space is another way to make the code more legible.

Now, let’s consider the while-loop which most certainly has a problem, a missing closing brace. So, it’s a good idea to write your while-loop, making sure to add the opening and closing braces before adding code to the loop. In this case, will PHP’s parser figure out that the brace is missing? Let’s find out!

When I ran the code, the parser complained:

Parse error: syntax error, unexpected ‘{‘ in … on line 10

This error message results because of another error, the missing closing parenthesis in the if-conditional. So, I’ll close it and see what happens. Interestingly, the following error appears:

Parse error: syntax error, unexpected ‘}’, expecting ‘,’ or ‘;’ in … on line 14

So, the parser fails to specify that the while is missing a closing brace or else it mistakes the closing brace as pertaining to the while loop when it was expecting one for the if-conditional. The remedy is easy — just add the closing brace for the while loop. But, that addition won’t ameliorate this code. Note, one more error: the missing semi-colon in the second echo statement. Note, the only time you can omit the semi-colon is right before a closing PHP tag. A good habit is to just make sure to end all statements with semi-colons.

Unfortunately, adding the missing punctuation is insufficient because this code has a much more serious problem. It now runs as an endless loop owing to a failure to increment the loop counter variable $i. So, here’s how the loop code ought to be remedied:

while ( $i < 3 ) {
 if( isset( $fruit[$i] ) ) {
   echo 'The meal includes a/an:' . $fruit[$i] ;
 }
 else {
    echo 'No fruit today.';
 }
 $i++;
}

This loop will work but the code could be improved with the addition of a few more variables and replacing the if-conditional with a ternary one-liner that does the same thing. Also, hard-coding the maximum value into the while-loop makes it more susceptible to breakage should $slist change and acquire more or fewer elements. So, here’s the entire replacement code:

    $fruit = [];
    $fruit[1] = "apple";
    $fruit[2] = "peach";
    $fruit[3] = "orange";

    $slist = array_values( $fruit );

    $i=0;
    $fruit_type = "";
    $mess_result = "";
    $mess_error  = "No fruit today.";
    $max = count( $slist );

    while ( $i <  $max) {
      $fruit_type = $slist[ $i++ ];
      $mess_result = "The meal includes a/an: $fruit_type";
      echo isset( $fruit_type )? $mess_result : $mess_error,"\n";
    }

Of course, you want your development to go fast and quickly get something up and running and PHP was designed precisely to help out developers in this fashion. But, it’s important to watch out for errors occurring by at minimum turning on error reporting and becoming familiar with PHP’s error messages, especially whether to take them literally or instead be familiar with their implications.

Advertisements

Actions

Information

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s




%d bloggers like this: