My BlogAbout MePortfolioTemplatesArticlesWeb StoreMessage Board (Forums)Guestbook

Browse archives

September 2012  
Mo Tu We Th Fr Sa Su
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

Search this site with Google

Five perhaps not-so-known PHP tricks for leaner and cleaner code

Submitted by Jakob on 7 April, 2008 - 23:21.My Blog | Computers & Hardware | Drupal

In this article I'll give a few examples of powerful ways to program PHP that aren't obvious to many. The tricks I mention here are in themselves nothing new and experienced programmers probably know about them all but budding and intermediate PHP programmers can probably pick up a thing or two.

The ternary

Behind this exotic name is a control structure that allows you to write very compact and efficient conditional clauses. The ternary is simply put a shorthand for an if-clause, written as:

expression1 ? expression2 : expression3

Expression1 is evaluated, if it evaluates to TRUE, expression2 is evaluated, otherwise expression3.

So let's look at an example:


if ($a) {
  print $b;
}
else {
  print $c;
}

Can be written as:

print ( $a ? $b : $c );

The ternary is especially powerful in conjunction with the print statement as it allows you to write in one line what could take many and makes your code more compact and readable.

Ternaries can be chained into compound statements like:

expression ? ( expression1 ? expression1a : expression 1b ) : expression2

In these cases, you have to use parentheses to separate expressions. I usually use parentheses when writing ternaries not just for its logical meaning but also for the sake of clarity.

Code consists of expressions and expressions are evaluated

Program code consists of a series of symbol, speaking strict computer science. Symbols form expressions and the expressions are evaluated when the program is run.

This is important to remember because you often come across code like:


if ( get_a_value($b) ) {
  $a = get_a_value($b);
  return $a;
}

This is not optimal since the function get_a_value() is called twice (which may or may not be a problem depending on how efficient the interpreter is). So people often take to storing the return value so as not having to call the function more than once:


$a = get_a_value($b);
if ( $a ) {
  return $a;
}

What people tend to forget is that the expression $a = get_a_value($b) is also evaluated and can be seen as returning value; as it says in the PHP Manual: the value of an assignment expression is the value assigned.

In this case its value is what the function returns and what is assigned to $a. So this code would work equally well as the previous:


if ( $a = get_a_value($b) ) {
  return $a;
}

Another example of using the evaluation of expressions is this:

Common form:


if ($a == 5) {
  return true;
}

Lean form:

return ($a == 5);

This works because the expression $a == 5 is evaluated and will, if $a equals 5, have the value TRUE.

The drawback of writing more concise code is readability and sometimes an if-clause is in fact preferred if it makes the code more readable.

Arrays are useful

One of the data structures that PHP supports really well is the array. A data structure is a way to store data so it can be stored and retrieved efficiently. PHP has a number of built-in functions for manipulating arrays and makes it extremely easy to work with them.

An array is simply put a list of values with keys. Keys are like the numbers on your todo list, or like the pages in a book, they can be used to address values in the array.

To make an array in PHP:

$array = array();

To add an element to an array:

$array[] = 'foo';

You can also add content to an array this way:

$array = array(1, 2, 3, 4, 5);

Or if you want to define keys (array(key => value)):

$array = array(1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5);

Arrays can be associative meaning strings are used for keys, for example:

$array['time'] = time();

Using an array you can more easily pass data to your functions. Instead of passing five variables like so:

function myfunc($a, $b, $c, $d, $e) { ... }

You can pass an array containing all those values:

function myfunc($array) { ... }

An array can contains a lot of values, so it's often useful to go through an array and examine each array element. To do that, you can use foreach, which is used here to print every value in the array (providing the array doesn't contain other arrays):

foreach ($array as $key => $value) {
  print "[$key] $value";
}

Arrays can be nestled or hierarchical, meaning the array contains more arrays. This way you can build trees of arrays which can be very useful to store data about complex structures such as a chess board which consists of 8 x 8 squares. A chess board can therefore be described with an array holding eight elements, each holding an array of eight elements, every value holding the x and y coordinates of its square:


$a = array();
for ($i = 0; $i < 8; $i++) {
  $a[] = array(0, 1, 2, 3, 4, 5, 6, 7);
}

You can then store a value in a square such as first column, sixth row like so:

$a[0][5] = 'black pawn';

What we did above with filling the array:

array(0, 1, 2, 3, 4, 5, 6, 7);

Can more easily be done with PHP's array_map function or by nestling another for clause inside the one above. I'll leave it to you as an exercise to figure out how.

Type casting

One feature of PHP by many overlooked due to PHP's variable type agnostic nature is the type casting of variables. Type casting is programmer lingo for converting a variable from one type to another. Variables are of different types depending on what kind of value they hold. Type casting offer an extremely useful way to make your code leaner and more readable.

Variables that hold text are called "strings", and variables that hold numbers without a decimal are called "integers". There are more variable types in PHP, for a full list please refer to the PHP Manual.

Type casting, or just casting, variables can be a very useful way to write lean and clean code. By casting a string or integer to a boolean you can easily determine whether a variable is empty, is null or 0. Since many functions such a database query functions frequently return false or 0, it's often useful to determine what a function handed us before we pass it back.

In PHP, a string of '' that is cast to boolean is considered FALSE. An integer with the value 0 is also considered to be FALSE. Say for example we have a function that counts a result set from a database query and returns TRUE if the result set contains rows, otherwise FALSE (code has been omitted here for the sake of clarity):

return (bool) mysql_num_rows($dbres);

Much leaner but more cryptical than writing:


if( mysql_num_rows($dbres) > 0 ) {
  return true;
}

Always weigh the benefits of leaner code against the disadvantage of making your code less readable. If necessary, write comments that explain your thinking and why you do something. The code itself should be clean enough to explain what you do.

As a rule of thumb, if you see the keywords true or false written out literally in your code there may be room for improvements with regards to how you write your expressions.

Printing stuff out

A program usually needs to show some kind of output, and in PHP you can print stuff out to the browser using the print function. The print function takes a variable as argument and prints it out, meaning it is sent back to the browser when your PHP code is run by the server.

The print function can also take literal strings, such as 'hello world'. This becomes very useful sometimes because PHP treats strings surrounded with '...' different than strings surrounded with "...". A string that uses double quotes ("") allows variables to be used as placeholders. An example:


$name = 'stranger';
print "Hello $name";

But a single quoted string can't:


$name = 'stranger';
print 'Hello '. $name;

The period is used to concatenate strings - that is to add strings to one another.

The drawback is that double quoted strings take longer time to evaluate since PHP needs to go through them, byte by byte, looking for variable references. For that reason, always use single quoted strings unless there's a very specific reason why you need to use double quoted strings.

You can also use printf to use variable place holders but it uses a different (perhaps more complex) syntax:


$name = 'stranger';
printf ('Hello %s', $name);

For full details, look up printf in the PHP Manual.

There's another sibling in the print family and it's print_r which prints data structures recursively. This is immensely useful when debugging code and not having access to a real fully featured debugger. The first argument to print_r is the expression to print. The second argument is a boolean that determines whether it should be printed or returned. In the example below, the result is returned and not printed.

Say we have an array $a, and we want to see its contents. We could define a function such as this:


function p($v) {
  printf('<pre>%s</pre>', print_r($v, true));
}
p($a);

The <pre> tag preformats the output so that it gets easier to read, using a monospaced font, and respects line breaks. The function p() will print out the contents of $a in an easily readable way.

More information

Ternary

http://www.php.net/manual/en/language.operators.comparison.php#language.operators.comparison.ternary

Expressions

http://www.php.net/manual/en/language.expressions.php

Assignment operator

http://www.php.net/manual/en/language.operators.assignment.php

Arrays

http://www.php.net/manual/en/ref.array.php

Type casting

http://www.php.net/manual/en/language.types.type-juggling.php#language.types.typecasting

Print

http://www.php.net/manual/en/function.print.php



Trackback URL for this post:

http://www.jakob-persson.com/trackback/547

Post new comment



The content of this field is kept private and will not be shown publicly.


*

  • Web and e-mail addresses are automatically converted into links.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.
Verify comment authorship
Captcha Image: you will need to recognize the text in it.
*
Please type in the letters/numbers that are shown in the image above.