Functions are a great way to organise your applications. They can be used to avoid repetition in your codebase. When you find a similar piece of code duplicated many times within your application, it's a good indicator that you should be using a function instead.
You can think of functions as little factory machines. Your variables (little boxes) go into a slot on one side of the machine, some cogs spin, crunching noises happen and something else comes out of the other side.
Basic Usage
Let's take a look at a function. You've been with me for many chapters, I'm sure you know how this works!
<?php
function echoSong() {
echo "So take the photographs, and still frames in your mind.\n";
echo "Hang it on a shelf in good health and good time.\n";
echo "Tattoos and memories and dead skin on trial.\n";
echo "For what it's worth, it was worth all the while.\n";
}
echoSong();
Right, this is all new! Before we begin the explanation, let's go ahead and execute the code. What's the output that we receive?
So take the photographs, and still frames in your mind.
Hang it on a shelf in good health and good time.
Tattoos and memories and dead skin on trial.
For what it's worth, it was worth all the while.
We're presented with some lyrics from a classic song. There's bonus points in it if you can name the artist and song title. Answers on a postcard folks! Actually, you can just tweet me!
We should take a look at the function definition. Before a function (little machine) can be used, we must tell PHP what it does. This is our definition. Here's the section that I'm talking about.
<?php
function echoSong() {
echo "So take the photographs, and still frames in your mind.\n";
echo "Hang it on a shelf in good health and good time.\n";
echo "Tattoos and memories and dead skin on trial.\n";
echo "For what it's worth, it was worth all the while.\n";
}
We know what the echo lines do, so let's strip out the body of the function definition for clarity.
<?php
function echoSong() {
// Do stuff here.
}
The first line in the example is called the method signature. It describes the method, and its shape. With a function this simple, all we really have is a name. We start the function definition with the keyword function
followed by the name of the function that we are defining. The function name has similar naming rules to variables, so we're going to stick with camelCased names for consistency.
Next, we have a pair of rounded brackets. Later we'll learn how we can give our function parameters, and these brackets will become more interesting, but for now, leave them empty! Finally, we have a block in curly brackets. This is similar to the loops and forks that we have seen in the previous chapters.
Our code snippet is letting PHP know that when we call our echoSong()
function, it should echo out the lyrics to a classic song which you're kicking yourself because you've forgotten the name of.
Now that we've told PHP about our function, we are able to make use of it. That's what this line does.
<?php
echoSong();
We can execute a function by providing its name, and a set of rounded brackets. The block within the function we defined will then be executed and our lyrics will be displayed.
We can execute our function as many times as we like. This means that the snippet of code we have created is now re-usable across the whole of our application. We're being efficient.
Here's an example of calling the function multiple times.
<?php
function echoSong() {
echo "So take the photographs, and still frames in your mind.\n";
echo "Hang it on a shelf in good health and good time.\n";
echo "Tattoos and memories and dead skin on trial.\n";
echo "For what it's worth, it was worth all the while.\n";
}
echoSong();
echoSong();
echoSong();
Let's execute the code snippet to see the output.
So take the photographs, and still frames in your mind.
Hang it on a shelf in good health and good time.
Tattoos and memories and dead skin on trial.
For what it's worth, it was worth all the while.
So take the photographs, and still frames in your mind.
Hang it on a shelf in good health and good time.
Tattoos and memories and dead skin on trial.
For what it's worth, it was worth all the while.
So take the photographs, and still frames in your mind.
Hang it on a shelf in good health and good time.
Tattoos and memories and dead skin on trial.
For what it's worth, it was worth all the while.
I'm sure that song was meant to have a chorus! Oh well, our code has executed as it should, calling our function three times. We should create functions for snippets of code that are used often within our application. They will serve to reduce the size of the codebase, and allow for us to change the common functionality in one place, rather than having to dig around our whole application making many changes.
Return Values
The blocks of our functions can be used to return a value or object (more on objects later). It can provide things that are useful to us. Let's take a look.
<?php
function getMeaningOfLife() {
return 42;
}
Here we have another function definition. This time, we use the return
keyword to return a value from the function upon execution. When we call the function, we'll receive the value 42
as the result of the statement.
Now I know that we could have simply stored the value 42
in a $meaningOfLife
variable, but when we continue in to the later sections of this chapter, you'll see why this return
keyword might be useful. It's not easy keeping these examples simple, you know!?
Let's try calling the function, and assigning the result to a variable. I'll add some comments for clarity. I'm a nice guy like that!
<?php
// Create a function.
function getMeaningOfLife() {
// Return a value.
return 42;
}
// Execute function and assign result.
$result = getMeaningOfLife();
// Dump the result.
var_dump($result);
The first section with the function definition is exactly the same, I've simply added some comments. On the next line we're executing our function getMeaningOfLife()
and assigning the result to a variable named.. well.. $result
. Finally, we'll dump the result. Let's run our code.
<?php
int(42)
There we go! We see that the 42
that we return
ed from our function was assigned to the variable when we executed it. We'd receive the same output with the following snippet.
<?php
// Create a function.
function getMeaningOfLife() {
// Return a value.
return 42;
}
// Dump the result of the function.
var_dump(getMeaningOfLife());
This time we're dumping the result of the function directly, instead of assigning it.
There's one final thing that we need to keep in mind when using the return
keyword. As soon as PHP comes across our return
line, it will exit the function, returning the value. For example, consider the following code sample.
<?php
// Create a function.
function getMeaningOfLife() {
return 42;
echo 'Here I am, rock you like a hurricane!';
}
// Dump the result of the function.
var_dump(getMeaningOfLife());
In the above example, when the function getMeaningOfLife()
is executed, it will return the value 42
, but the echo
statement will not be executed.
It's worth noting that you can use return
without a value to end a function before it's natural exit point. Doing this is the same as returning null
. Here's an example.
<?php
function getMeaningOfLife() {
return;
echo 'This line will never be executed!';
}
Parameters
Some machines take input. For example, a 3D printer takes plastic and a blueprint. An espresso machine will take one of those tiny coffee pods and some water.
Functions can also take input. We call these arguments or parameters; they make up part of the method signature, or the description of how the function works. Let's take a look at a simple function parameter.
<?php
// Welcome someone!
function welcome($name) {
echo "Welcome to PHP Pandas, {$name}!";
}
Between the rounded brackets within our function signature, just after the function name, we have our single parameter. We're calling it $name
. These parameters are placeholders for values that we will be giving to the function when we use it. This is what makes the function dynamic.
The parameters that are given to the function are available for use within the function block. In the above example, we use the $name
parameter handed to the function, and echo a welcome statement using the provided name.
Of course, this snippet of code won't do anything unless we tell PHP to execute, or 'call', the function. Let's add the call line to our snippet.
<?php
// Welcome someone!
function welcome($name) {
echo "Welcome to PHP Pandas, {$name}!";
}
// Call the welcome function.
welcome('reader');
We call the method using its name and rounded brackets. However, this time we provide a string value reader
within the brackets as our parameter. This means that the $name
parameter of our function will be set to reader
. It will only be set to this value for this one execution, and any later calls to the function will be replaced by whichever parameter value we provide to it. Our function doesn't have any state.
Let's take a look at the result that we see in our terminal, shall we?
Welcome to PHP Pandas, reader!
Great work! We receive a warm welcome. Why don't we try using a number of different values? This will serve to prove how the function is now dynamic.
<?php
// Welcome someone!
function welcome($name) {
echo "Welcome to PHP Pandas, {$name}!\n";
}
// Call the welcome function.
welcome('reader'); // This is you!
welcome('Captain Jon Morgan'); // This is an awesome guy!
welcome('Arno Dorian'); // Nothing is true...
welcome(64.54); // That's not a name!
Here, we are invoking the function four times. Each time, we are supplying a different value. The fourth value is a float, which demonstrates that it doesn't matter what type of data we provide to our function. I've also added a new line character (\n
) to the echo statement to give it some clarity. Let's execute this snippet.
Welcome to PHP Pandas, reader!
Welcome to PHP Pandas, Captain Jon Morgan!
Welcome to PHP Pandas, Arno Dorian!
Welcome to PHP Pandas, 64.54!
See how the result of our function changes each time, depending upon the input that we provide? This gives us more control over our functions, and the ability to react differently to different values. As you can see from the fourth value, it doesn't matter what data types we pass into the function, our code is happy.
We aren't limited to only one parameter. We can use as many parameters in our functions as we like. Let's abuse this right, shall we? Let's make one with... a whole five parameters! What rebels we are!
<?php
// Sum some values.
function addify($first, $second, $third, $fourth, $fifth) {
return $first + $second + $third + $fourth + $fifth;
}
// Call the addify function.
echo addify(1, 1, 2, 3, 5);
We've written a function that will take 5 values as parameters, and return the sum of them. With our addify()
function, the order doesn't matter, but it's worth noting that the order that you provide your parameters matches up to the placeholders in the signature. In the above example, the value of $first
will be 1
, and the value of $fifth
will be 5
.
Five parameters is great, but it feels like there shouldn't be a limit on a function like addify()
. We should be able to sum as many figures as we like. I've got an idea! Let's use func_get_args()
. This is a special PHP function that will return an array of all the values that have been passed as parameters to our function. What's even better, is that we don't need to define any parameters at all for it to work. Here's an example.
<?php
function welcome() {
// Get all function parameters.
$names = func_get_args();
// Iterate the names and welcome them.
foreach ($names as $name) {
echo "Welcome, {$name}!\n";
}
}
Here we've used another function called func_get_args()
within our own function. That's right, functions can use other functions too! When we use func_get_args()
we receive any parameters that are given to the function in the form of an indexed array. We don't even need to create placeholder variables for them. This means that the function above can take as many parameters as you like. Here's an example:
<?php
welcome('Dayle', 'James', 'Andrea', 'Ben', 'Mateusz');
We call the function using five names, and receive the following response.
Welcome, Dayle!
Welcome, James!
Welcome, Andrea!
Welcome, Ben!
Welcome, Mateusz!
All five people are welcomed. What happens if we change the number of parameters? Let's try it with two names instead.
<?php
welcome('Anthony', 'Alex');
Our function doesn't care. The array returned from func_get_args()
will now contain only two values, and the loop will continue as normal.
Welcome, Anthony!
Welcome, Alex!
Type Hinting
Earlier this chapter, we mentioned those nifty little espresso machines. The ones that take little plastic pods? I'm sure you've seen them. Well what would happen if you put an avocado into the slot where the pods go? Do you think it would work?
It would make a huge mess!
You're quite right! We'd end up with green gooey avocado all over our lovely espresso machine. It's only made to take coffee pods. Sometimes our functions are only made to take specific input too. If we want to ensure that our parameters are of a certain type, we can use a technique known as type-hinting.
Let's see this in action.
<?php
// Say hello to an array of people.
function sayHello(array $names) {
foreach ($names as $name) {
echo "Hello, {$name}!\n";
}
}
sayHello(['Katie', 'Corissa', 'Lucy']);
We've got another welcoming function called sayHello()
. The only new thing that we'll encounter in this example, is that the input array $names
has been type hinted as an array. We've done this by specifying the type array
before the parameter placeholder.
If we execute the code, we get the output that we expect.
Hello, Katie!
Hello, Corissa!
Hello, Lucy!
Let's change the function call to pass a number. Aren't we naughty!
<?php
sayHello(4);
What happens this time? Let's execute the code.
PHP Catchable fatal error: Argument 1 passed to sayHello() must be of the type array, integer given.
Interesting! PHP is now angry at us. With the type-hinting in place, PHP will only allow arrays to be passed to the sayHello()
function. If we pass anything else, we get a fatal error. The Catchable
part means that we could deal with this error sensibly using a try
block, but we'll look at that later.
Type-hinting is super useful, isn't it? Well there's a catch. I'm sorry. There's always a catch, isn't there? You can't type-hint scalar values with PHP (yet.. dun dun dun!). Don't ask me why, I didn't write the language! What this means, is that you can't type hint string
, integer
, boolean
and float
values. It's a real pain, but you'll have to learn to deal with it. It's a hard truth, isn't it?
It seems a little strange just hinting array
s, doesn't it? Well, later you'll discover that you can also type-hint parameters as classes, but we'll explain that in greater detail after we've learned about classes themselves. One step at a time young padawan. One step at a time...
My books are available online for free to encourage learning. However, if you'd like for me to keep writing, then please consider buying a digital copy over at Leanpub.com.
It's available in PDF, ePub, and Kindle format, and contains a bunch of extras that you won't find on the site. I have a full-time job, and I write my books in my spare time. Please consider buying a copy so that I can continue to write new books from the comfort of my sofa!