Home PHP Function Design

Function Structure

If you have a single function that is very long, break it apart into smaller sub-functions. The definition of "very long" is vague, but often a function longer than 20-30 lines is pushing it.

If you try to describe the function's purpose and find yourself using the word "and" a lot, that probably means the function does too many things and should be split into sub-functions.

Very rarely should you have all of your PHP code outside of a function in a PHP file. It's important to define functions to delegate the significant behaviors of your PHP program. There is no main function in PHP, but it is good practice to write your own "delegator" function to check for things like GET or POST variables and to delegate behavior with functions as appropriate. For small (< 30 lines) PHP programs it is usually appropriate to have only one function, but for longer you should probably have at least two.

Boolean Zen

Don't ever test whether a boolean value is == or != to TRUE or FALSE.

if ($x == TRUE) {
  ...
} else if ($x != TRUE) {
  ...
}
if ($x) {
  ...
} else {
  ...
}

If you have an if/else statement that returns a boolean value based on a test, just directly return the test's result instead.

if ($score1 == $score2) {
  return TRUE;
} else {
  return FALSE;
}
return $score1 == $score2;

If/Else Usage

If/Else Branching Patterns

When using if/else statements, properly choose between various if and else patterns depending on whether the conditions relate to one another. Avoid redundant or unnecessary if tests.

if ($grade >= 90) {
  print("You got an A!");
}
if ($grade >= 80 && $grade < 90) {
  print("You got a B!");
}
if ($grade >= 70 && $grade < 80) {
  print("You got a C!");
}
...
if ($grade >= 90) {
  print("You got an A!");
} else if ($grade >= 80) {
  print("You got a B!");
} else if ($grade >= 70) {
  print("You got a C!");
}
...

If/Else Factoring

Move common code out of if/else statements so that it is not repeated (ie., minimize redundancy in your code).

if ($x < $y) {
  foo();
  $x++;
  print("hi");
} else {
  foo();
  $y++;
  print("hi");
}
foo();
if ($x < $y) {
  $x++;
} else {
  $y++;
}
print("hi");

Loop Usage

For Loops vs. While Loops

Use a for loop when the number of repetitions is known (definite); use a while loop when the number of repetitions is unknown (indefinite).

// repeat exactly size/2 times
for ($i = 0; i < $size / 2; $i++) {
  ...
}

// repeat until $x is <= 0
while ($x > 0) {
  ... // do something with $x
}

Break and Continue

In general, you should avoid break and continue statements unless absolutely necessary. In this class, you should never use these statements (it would be very unlikely you would write code for our assignments in which using one of these would be proper style).

Error Handling

Using die() and setting errors with header

When handling errors in PHP, you should set the appropriate error code, header content type (if not already set) and output an error message. In general, you should try to use good conditional flow so that no other code will execute after outputting an error message. But this isn't always possible to do cleanly, and in such cases you may use die($msg) which will print the provided $msg and cause your program to automatically exit without executing further.

If you have several error messages, you may consider factoring them out with an handle_error function.

header("HTTP/1.1 400 Invalid Request");
echo "Invalid mode: {$mode}. Please pass modes of 'add' or 'remove'.";
header("HTTP/1.1 400 Invalid Request");
# use die if your program would otherwise continue executing when you instead want to exit
die("Invalid mode: {$mode}. Please pass modes of 'add' or 'remove'.");

Handling Exceptions with try/catch

You may use try/catch statements to handle exceptions as long as you do so without deviating from clean and logical program flow. In this course, you should usually only try/catch to handle possible PDOExceptions. You should also output the appropriate error messages when catching errors, but print the contents of a PDOException with caution (in practice, a client fetching from your web service should not be getting a error message showing internal database exception details. But for debugging it can help to see these exception details).

function handle_error($msg) {
  header("Content-Type: text/plain"); 
  header("HTTP/1.1 400 Invalid Request"); # 503 is another error code for handling internal db errors
  echo "{$msg}\n";
}

... 
try {
  # some success code
} catch (PDOException $ex) {
  handle_db_error("Error adding product into database. Please try again later.");
}