in General PHP

How To Write A Function In PHP

PHP allows developers to write a variety of different styles of code: procedural, object-oriented, or simply scripts. This flexibility makes PHP easy to learn, and also means that new developers to PHP may not be programmers in other languages.

For new developers, especially developers who have never been programmers before, moving from writing simple scripts to writing functions is a process that takes time. I developed in PHP for years before I wrote a single function. I also never found a comprehensive tutorial on how functions work, or how to write them. There’s documentation in the manual, but it’s a bit hard to grasp if you’re new. This article is about writing functions.

For starters, what is a function? A function is a collection of code that is available for use and reuse repeatedly throughout a particular script or application. You’re probably already familiar with functions because you probably use them in PHP. If you’ve used print() or mysql_connect() you’ve used a function. Both of these functions encapsulate other code (in their case, core PHP code written in C), and allow you to accomplish certain tasks.

Matthew Turland equates writing a function to tasking a junior level employee. After describing a short name for a particular task, you teach the scope of that task, and then can direct the task to be executed at any time.

The beauty of functions is that you don’t have to rewrite the same code over and over again. Once it’s encapsulated in a function, that function provides a shortcut to executing the code you’ve defined. This is a pretty cool tool when you think about it.

For example, let’s say that you establish a MySQL connection every single page. You could do the following on every page:

$connection = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('mydatabase');

Or, you can write a function that does this, and call the following on every page:

$connection = myConnectionFunc();

Which would be easier for you? Well, the second one of course. Let’s learn how we did that.

The source code behind myConnectionFunc() is pretty basic. If you don’t understand the syntax entirely from looking at it, don’t worry. I will explain.

<?php

function myConnectionFunc($host = 'localhost', $user = 'user', $pass = 'pass', $database = 'mydatabase')
{
$conn = mysql_connect($host, $user, $pass);
mysql_select_db($database);
return $conn;
}
&#91;/sourcecode&#93;

That may look quite complicated but once you understand the syntax, it's not all that complicated at all. We'll come back to this example once we know a little bit more about functions.

<strong>All Functions Share These Characteristics</strong>

For starters, all functions share certain characteristics. The function definition starts with the word "function", followed by the name of the function, an opening parenthesis, any arguments, and a closing parenthesis. You must also include curly braces to delimit the body of the function. Here is the most basic function you can have in PHP:


function basic()
{
}

All functions should share these qualities. They are required by the PHP engine to determine that a function has been defined. Without them, you will get a syntax error.

Function Bodies

A function body can contain any user-defined (that’s functions you write) or internal (that’s functions PHP provides by default) functions, structures, and code that you like. Remember: functions serve to encapsulate the functionality you want to express, meaning that a function can be called repeatedly to accomplish a certain task. For example, a function can look like this:

function iterateArray($array)
{
foreach($array as $item)
{
$newArray[] = 'Iterated: ' . $item;
}
return $newArray;
}

What you put in the body is largely up to you. There are few (if any) restrictions. Bear in mind, that there are best practices; you should make yourself aware of them through the PHP manual and further reading.

Function Scope, Arguments, and Return Values
One of the most important things (and most difficult concepts to grasp) about functions is the concept of a function’s scope.

Functions don’t know about what is going on outside the function. They don’t know what variables have been defined, or what is going on around your application at the time you invoke them. They only know about the information they have been given, and the contents of their bodies. This behavior is necessary because if functions were aware of the “global scope” (all the variables and information that is defined in your application), you could get very unpredictable behavior. Instead, they are “dumb code units”, as Matthew Turland describes it.

Similarly, when a function ends, anything that happened inside of it is forgotten. This is to prevent the function from improperly altering behavior in your application, which would also result in some very strange bugs.

But this creates a big problem: how on earth do we get information into and out of a function?

To get information in, we pass the function some arguments. An argument is a variable that exists between the parenthesis in the declaration. See the example below, with the variable $argument:

placeholder for ANY value we want to give it. That variable need not be named $argument. The function doesn’t care if the global scope has a variable named $argument; it only cares about what you give its placeholder.

You can have multiple arguments. You only need to separate them by a comma. Convention says that you should add a space after each comma, but that’s entirely up to you and your own personal coding standard; it is not required by the parser.

How do we get information out of a function? In the previous example, we used the echo() construct to directly output our statement, but this wouldn’t work if we had assembled an array, for example. Since everything inside a function is destroyed when the function’s execution ends, we’ve got to use a different method to get information out of a function: the language construct ‘return‘.

This language construct allows us to return a value from the function. It also has the benefit of halting execution of the function, meaning we can use it to return a value early if we’re done executing the function. You can return any PHP type, including the value of a variable. Note that returning a variable does not place that variable into the global scope; it returns the value only. For example:

Default Argument Values

You may have noticed in our initial example that I added an equals sign and a string value after defining the arguments. This is a perfectly valid technique, which adds a default value to each of the arguments. You may assign a default value to some, all, or none of your arguments, as you see fit.

The benefit of default argument values is that it allows you to call the function without having to set default values each time. For example, in our initial function the login credentials are unlikely to change. However, by permitting arguments, you are allowed to connect to a different database or database server. If you assign values to the arguments when you call the function, they automatically override the default values in the definition.

Bear in mind that if you want to assign some of your arguments default values, it is best to place these arguments towards the end of your function signature. The reason is that if you place them at the front, you will have to assign them a null value. For example:

Returning Multiple Values From A Function

PHP does not allow for the return of two values from a function. This is a limitation of the language’s structure. However, it is possible to return an array from a function, which results in similar functionality. For example:

objects, if you like. This is considered an acceptable practice.

Bringing The Global Scope Into Your Function

Warning: The behavior discussed in here may result in an unpredictable behavior in your PHP applications. There are very valid reasons for using this functionality, but they are few and far between. The information is provided for completeness only, and should not be used unless you fully understand why you’re using it. Using this behavior probably means that a refactoring of your code is in order.

It is possible to bring parts of the global scope into your application by using the keyword ‘global’. The global keyword allows you to define variables that exist in the global scope as variables that also exist in the function’s internal scope.

For example:

are reflected in the global scope.

This is a very bad programming practice. Typically, if you are finding it necessary to pass variables into a function through the global scope, you should consider how your code can be refactored so that this is no longer necessary.

Passing By Reference

Warning: Passing variables by reference is a very powerful, and potentially dangerous, behavior. Additionally, it makes debugging and testing difficult. Always consider carefully your reasons for passing or returning by reference, and consider refactoring to make it unnecessary.

When you define arguments for a normal function, these arguments are given to the function in a fashion that is known as “by value.” Essentially, PHP copies the value of the variable, and then gives it to the function. Changes to that copy are not reflected in the global scope.

There is another way to pass to and return from functions: by reference. Passing “by reference” means that rather than copying the value, you are tying the two variables together. When you alter the value of one variable, you alter the value of the second. For example:

<?php

$var1 = 'a';
$var2 =& $var1;
$var2 = 'b';

echo $var1; //outputs 'b'

In this example, we attach the two by reference, making our change to $var2 reflected in $var1. You can also do this with functions:

<?php

function addOne(&$num)
{
	$num++;
}

$var = 6;
addOne($var);

echo $var; // Outputs 7

Note that even though we did not return anything from addOne(), the $var value was affected in the global scope. This is because we passed it by reference when we defined the function. This tied the value of $var to $num, and when we incremented $num, we also incremented $var.

Passing by reference should always be done when you define the function. You should never pass by reference at runtime. For example, the following syntax would be unacceptable:

function addOne($num)
{
	$num++;
}

$var = 6;
addOne(&$var);

While this behavior will not break in PHP 5, it will probably not be allowed in PHP 6, and will emit a nasty warning if you do it.

Bear in mind that when passing by reference, a variable is the only thing you may pass. You cannot pass an expression or any other value to a function that expects a variable passed by reference.

With regards to references as a programming practice, be aware that references aren’t doing what you think they are behind the scenes. While they have very limited application, you should understand the implications, and more often than not, you will want to pass by value.

Conclusion

By now, you’ve had a chance to be exposed to some of PHP’s most common function behavior and, hopefully, will be able to write functions yourself. Functions provide a powerful way to encapsulate and extend your code, share common functionality without writing it for each occasion, and improving your ability to prevent bugs.

This blog entry implements The Beginner Pattern.

Be the first to get Modern Object-Oriented PHP!

Long to learn how you can develop modern applications using object-oriented PHP? Curious about how to apply all these best practices to your code?

Modern Object-Oriented PHP is a brand-new book focused on teaching you the techniques you need for writing modern, well-designed object-oriented applications!

The book lands in April. Sign up today for a sample chapter plus special launch day discounts!

Powered by ConvertKit

11 Comments

  1. … and if you are beginner and use ext/mysql you code crap. The current MySQL extension is ext/mysqli. The php.net manual tells you why.

  2. Hello

    Why do you use this :
    function goodFunc($var2, $var1 == false)

    When you can use this :
    function goodFunc($var2, $var1 = false)

    The default value of a variable is a definition, not a comparaison.

    Sry if i got something whrong.

  3. Sky, you caught a mistake I made and didn’t catch when I was proofreading. Good eye!

    I’ve fixed the mistake.

  4. > Bear in mind that if you want to assign some of your arguments
    > default values, it is best to place these arguments towards the
    > end of your function signature. The reason is that if you place
    > them at the front, you will have to assign them a null value.
    Unlike you imply this will not have the same effect as not passing the argument, as illustrated by the following example:

    [weirdan@home ~]$ php -r ‘echo PHP_VERSION . PHP_EOL; function a($b = false, $c = false) { var_dump($b, $c); } a(null);’
    5.2.8
    NULL
    bool(false)
    [weirdan@home ~]$

    As you can see, $b is null inside the function, just what was passed to the function.

    Your goodFunc example have a syntax error:
    function goodFunc($var2, $var1 == false) // <— it should be $var1 = false

  5. > I think its important to say, that objects since PHP 5 always are passed by reference.

    Well, it’s not true. In fact Brandon linked in this very blog post to the article by Sara Golemon that specifically deals with this very misconception.

  6. Hey Bruce, I fixed that syntax error earlier, and it looks to be fixed in my version. Are you seeing it differently?

  7. > Hey Bruce, I fixed that syntax error earlier, and it looks to be fixed in my version. Are you seeing it differently?
    No, I just had this tab opened since morning, and forgot to refresh prior to posting.

  8. Excellent article. I just have one teensy tiny problem: print() is actually not a function. Its a language construct. That aside, good work!

  9. I always make the mistake of confusing print() with a function because it has a return value, unlike echo(). My bad!

Comments are closed.