Monday, January 11, 2010

Simple Optimizing Tips for PHP Part IV - By Example (Part I)

Ss we write PHP code (or any language for that matter) we begin to start thinking about optimizing code. But even though our intentions are for "the greater good", we sometimes miss things that should be obvious.

Today's article takes a look at:

By Example


All developers progress at their own rate. As we progress, a few things that become evident is the existence of built-in php functions that can replace many of our own custom code, simply because we didn't know any other way. We also learn how to see repetition in our code and how to simplify it, when we should separate functionality into their own functions (or even classes!), and also just *know* when something will or will not work from personal experience. During this phase in life, we're becoming a senior developer.

Before we get to this point though, we are intermediate developers. Intermediate developers (in my honest opinion) is where a LOT of innovation comes from. It's from this level of developer that they are exploring PHP's full potential and how to exploit it to their benefit. When we are reaching the end of intermediate level and are looking to become the senior level developer on our team, we begin to try to search for ways to better ourselves as a developer. Unfortunately, such tutorials are very scarce and hard to find.

This tutorial is not to be the end-all be-all, but it is intended to help an intermediate find that next level. And we do this by examples.

Since even simple examples can lead to a book's worth of information, I plan to break this 4th part of Simple Optimizing Tips for PHP into sub parts. This will help reduce the amount of time it takes you to read this article, but also not try to slam too much information into your brain. Please keep in mind that while some of these examples won't exactly speed php's performance up, they will instead inadvertently teach you new methods and in turn try to warp your mind into a more sophisticated developer.

So without further ado, let's begin!

Our first example is the following function:


function multi_array_search($search_value, $the_array)
{
if (is_array($the_array))
{
foreach ($the_array as $key => $value)
{
$result = multi_array_search($search_value, $value);
if (is_array($result))
{
$return = $result;
array_unshift($return, $key);
return $return;
}
elseif ($result == true)
{
$return[] = $key;
return $return;
}
}
return false;
}
else
{
if ($search_value == $the_array)
{
return true;
}
else return false;
}
}


This function is perfectly valid, and works exactly as intended. However, there are a few things that one should notice right away:
1) The spacing and tabing of the data is not lined up nor consistant, making it hard to read.

2) The function is not taking advantage of the typehints that are now available in php 5.

3) Some of the code is a bit long and can be reduced to smaller lines without obfuscating the code.

4) The naming of some of the variables could be redefined to make understanding their purpose easier.

4) There exists absolutely no commenting in this function to explain it's purpose.

5) The possible return value is either boolean (true AND false) OR array!

6) The 2 parts of this function (the first if and the following else statements) could be refactored to make more sense and be more useful.

So now that we know this, how can we make this function better? Here is a revised, optomized solution.

/**
* @author John Doe
*
* Takes an array and searching for a value within.
*
* @param string $search_value
* @param array $search_array
* @return boolean // Returns true if a search value found, false if not.
*/
function multi_array_search($search_value, array $search_array) {
$search_result = false;
foreach($search_array as $key => $value) {
if(is_array($value)) {
# We have an array, so let's recursively search the subarray values
$search_result = multi_array_search($search_value, array_unshift($value));
} else {
# We have a string, so let's compare and see if we have a match
if($value == $search_value) return true;
}
}
return $search_result;
}


Notice that we are using the recursive method that was explained in my second tutorial on recursively looping through arrays. Also, we are now only returning a boolean value from this point on. In the case that we find a value, we return only a true, otherwise (and by default) we return false.

Now the above may or may not run faster (I haven't exactly run a test on this), but it is more simple, less code, and more understandable with comments that guide the way.

For the second part of By Example, we will be looking at redundant functionality and definitions, and learn how to better adjust our code to be more useful rather than bloated.