Functions and PHP: Do’s and Don’ts

Posted: October 1, 2011 in PHP, Programming, Tutorial
Tags: , , , ,

Functions in PHP are an integral part of any PHP coder’s programming career, whether you are developing complex social applications, or are creating simple scripts for use in a basic website. However, as I have noticed in my experience as a tutor and contributor to PHP help forums, many people have some bad habits with functions. Especially new programmers, who see functions as a way to just place code they would normally copy paste, without any notion or portability or re usability. For this tutorial, you should have a basic understanding of functions, including the syntax for creating/defining one, and calling one. Before I go over best/worst practices in terms of functions, lets go over how functions work in PHP

 

Function Basics

Functions are a very basic programming concept that many people learn within a few weeks of first learning to code. In PHP, functions have the following basic structure


function function_name(argument list){
function body

return statement (if applicable)
}

//function call
function_name(passed in arguments);

Very simple right? Lets break it down

function function_name(argument list){

The first part of this line is the function keyword. This tells PHP that you are about to define a function. The function_name is the name of your function. Like a variable name, you refer to this name when calling the function. Calling a function means to invoke its code. The argument list is an optional list of variables that you give values to when you call the function. When a function needs information that is outside of its scope, then it is best to pass this information via the argument list.

function body

return statement (if applicable)

The function body is the meat of your function. It is the code that is run every time you call the function. This is probably the most important part of any function. The return statement is an optional statement that will return information back to the line that called the function. The return statement is extremely useful, and an integral part of any functions in any programming language. Some times, you may not want or need to return anything however. An example function that would return something is, say, a function that calculates the square root of a number. An example function that may not return anything would be, say, a function that outputs (IE echo or print) some HTML that goes on a web page.


function_name(passed in arguments);

This is the function call. Here is where you actually invoke the code in a function, and pass it any relevant information via the argument list. If your function returns a value, you can set a variable equal to the function call, and the value returned from the function will be assigned to the variable. Lets take a simple example shall we!


//function definition
function square($number){
$product = $number * $number;
return $product;
}

//function call
$five = 5;
$five_squared = square($five);

Here we see an example of a function with an argument list and a return statement. Our code simply accepts a number, and returns what its square is. In our case, the variable $five_squared will contain the value of 25 (which is the value that our function returned). Lets look at another example.

function showHTML(){
echo "<h2>Welcome to my Website!</h2>";
}

showHTML();

 

 

Here we have a function without a return statement or an argument list. This function simply shows some HTML. Functions of this type are used primarily for outputting some kind of content. Of course, the return statement and the argument list are not dependent on one another, so you can mix and match functions having an argument list and having a return statement to fit your needs.

 

Scope

In a normal PHP script, variables have a script wide scope, meaning that when you define a varible, any line after that variable definition (as long as its not part of a function or class) can access and use that variable. However, functions are discreet, stand-alone entities. Variables available inside the script are not available in a function, and variables that are part of a function (including the variables in an argument list) are not available outside of the function. To illustrate this, consider the following example

$somevar = "some value";
function test($var1, $var2){
echo $somevar;//this will fail. $somevar is not in the functions scope, and thus is not available
echo $var1 . $var2;//this is correct. $var1 and $var2 are part of the functions argument list, and thus are available in the function
$somevar = "Another value";
echo $somevar;//now this will work, as $somevar is now defined inside the functions scope. However, it will echo "Another value" rather than "some value"
//because the function uses the variable from its scope.

}//end function

echo $var1 . $var2;//this will fail, as $var1 and $var2 are part of the functions scope, not the rest of the script;
echo $somevar;//this will echo "some value".

test(4,5);//outputs the following
/*************
a PHP notice will be issued for trying to use $somevar when its not defined in the functions scope
45
Another value
*************/

 

Although the above seems like it would prevent you from accessing variables inside a function that are defined outside, there is actually a way around the scope problem. There is a keyword global in PHP that lets you essentially import a variable defined outside the scope of a function to a function. To illustrate


$var = "Hello World"

function incorrect(){
echo $var;
}

function correct(){
global $var;
echo $var;
}

incorrect();
correct();


In the above snippet, the first function call (the line: incorrect();) will fail because $var is not in the scope of the function incorrect(). However, in the function correct(), we use the global keyword, which puts the variable $var from the outside script into the function. The resulting output would be: “Hello World” (excluding the notice that would be issued from the first function.)

 

Global can be nifty, but for new programmers can become a crutch. Most experienced programmers will never use the global keyword (unless they are being lazy, or providing a quick fix that they will revisit later), as it kind of defeats the purpose of a function. A function should be a completely standalone piece of code. If you use the global keyword, you are making your function dependent on the environment it is called in. This results in your function only being usable in a very specific script, and forces a programmer to change or code pages that use this function in a specific way. This makes the function much less portable, and makes reusing the function very difficult. Usually adding the global keyword to give a function a variable that would normally be out of scope is done as a quick fix for a badly written function.

When creating a function, a programmer must always plan it out. You must first determine what information a function needs, and what information it will return. In almost every case where a programmer uses the global keyword, they could have easily passed the relevant variables value into the argument list. Lets take the example function correct() above, and rewrite it.


function correct($var){
echo $var;
}

As we see, this was a very simple change (and actually results in a smaller function!). This also makes it so that our function is much more portable and reusable. For example, with the old function (the one that uses global) if we wanted to call the correct() function more than once, and echo different things each time, before each call we would have to change the value of $var. This could result in very messy code, especially if $var (or whatever the global‘ed variable is named) is an important variable in the script. Tracking a bug with a variable that is changed so much just because it is used in a function can become tedious and frustrating. However, with our new version of correct, you simply have to change the value of the parameter in the call. Lets take a look at some code to illustrate what I mean:

function correct1($var){
echo $var;
}

function correct2(){
global $var;
echo $var;
}

//output 3 different things with correct1
correct1('Hello');
correct1("I'm outputting stuff");
correct1('weeeee');

//now output 3 different things with correct2
$var = "hello";
correct2();
$var = "I'm outputting stuff";
correct2();
$var = "weeeee";
correct2();

As you can see, the code using the first function looks much nicer, and is much clearer. For someone reading just the code that outputs the information, it is much clearer what is happening when using the first function.

 

To Return, or To Not Return

Another common place I see new programmers forming bad habits is the return statements. As a general rule of thumb, when creating functions you should always think about returning something. Of course sometimes a function just doesn’t need to return anything, but more often than not, I will see a function that by all accounts should return a value, but instead output the value you want instead. Lets take an example


function showHeader(){
echo "<h2>Some text thats part of the Header</h2>";
}

This function seems ok at first (and for all intents and purposes it is, you can apply the following concept to any function of this form). It simply outputs a Header that a programmer may want to show on multiple pages. However, what if we wanted to, say, change the header size from header 2 to header 3? Of course we could create a new function, but if instead of simply echoing the HTML we want to output, we return the string to output, we can manipulate the string. So for example

function showHeader1(){
echo "<h2>Some text thats part of the Header</h2>";
 }
function showHeader2(){
return "<h2>Some text thats part of the Header</h2>";
 }

showHeader1();//we can only output the hardcoded info that is in the function.
//however with out other function we can output like the first
echo showHeader2();
//but we can also manipulate the value if we want to
echo str_replace("h2", "h3", showHeader2());//change it from h2 to h3

This example may seem somewhat arbitrary and unnecessary, so lets take an example more relevant to fledgling developers.

 

Say we have a system where we output users comments. Assume we have a function called getComment($id) which returns the comment of a specific user (who has a User ID of $id). Of course you must assume we have the correct database structure. Now assume we have another function called showComment($id) which outputs the comment from the specific user. Now, when simply outputting the comment, both would preform the same. However, what if we wanted to only show the first 500 characters? Or if we wanted to convert all the HTML characters in the comment into the html entities via the htmlentities function. With the showComment function, we would have to change the function itself to achieve this (which may result in this change breaking another part of your website). However, with getComment, since it returns a string, we can choose to simply output the returned value, or further manipulate it (with substr or htmlentities with the examples given above)

 

Of course, I could talk about proper use of functions for days, but the problems I discussed above are the most common problems I see

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