Functions in PHP Tutorial

In this tutorial we learn about functions in PHP and how they help us break up our application logic into smaller sections for easy reuse throughout our code.

Functions

As an application becomes bigger and more complex, we need ways to separate our code into smaller, reusable sections of logic. Functions are wrappers for those sections of logic.

But they’re not just wrappers, they allow us to interact with the code inside to make a section of logic as reusable as possible.

As an example, let’s consider the following code. It uses conditional control to evaluate if a number is even or odd.

Example: typical section of code logic
<?php

// Number to check
$num = 5;

// If the number can be divided by two
// without a remainder, it's an even number
if ($num % 2 == 0) {
    echo $num . " is an even number.<br>";
} else {
    echo $num . " is an odd number.<br>";
}

?>

If we want to do the same evaluation on other numbers, we would have to rewrite the whole section of logic. To avoid this problem, we can wrap the logic inside a function.

note We’ve used some built-in PHP functions earlier in the tutorial course, like the array() function.

How to define a function

A function can be simple or complex, based on the logic it contains. We will start with a simple function definition and add to its functionality as we go along.

Functions in php consist of a minimum of 4 tokens.

  • The function keyword.
  • A descriptive identifier (name).
  • A parameter list wrapped with () (open & close parentheses).
  • A code block wrapped with {} (open & close curly braces).

Inside the code block is where we write our section of logic.

Syntax:
function funcName() {
  // section of logic to execute
}

Functions are typically responsible only for a single task, which makes it easy to give them names. Our example below is responsible for alerting the user, so we can call it alertUser .

Example: alert a user
function alertUser() {
    echo "You've got mail.";
}

To keep things simple for the moment, the logic is just an echo statement. But we can have conditional statements, loops, even other functions inside.

How to call (invoke) a function

At this point our function is defined, but we haven’t actually used it yet. To use a function we call it, which will execute the logic in the code block.

To call a function all we need to do is reference the function name and the parameter list parentheses.

note Even though we don’t have any parameters in our function yet, we still have to write the parentheses when calling the function.

Syntax:
// Function definition
function funcName() {
    section of logic to execute
}

// Function call
funcName();

To demonstrate, let’s call the alertUser() function we defined earlier.

Example: call/use a function
// Define the functionality to
// alert the user if they have
// a message
function alertUser() {
    echo "You've got mail.";
}

// Actually use the function
// to alert the user
alertUser();

If we run the example above in the browser, it will display the message that’s defined in the function’s code block.

Once a function has been defined, we can use it anywhere in our script, even above the definition.

Example: call function anywhere
// Call
alertUser();

// Definition
function alertUser() {
    echo "You've got mail.";
}

The only exception to this is when a function is defined conditionally.

Example: conditional function definition
// This will error
alertUser();

if (true) {
    // Conditional Definition
    function alertUser() {
        echo "You've got mail.";
    }
}

// This is fine
alertUser();

Function names are case insensitive, but it’s good practice to always use the same case that the function was defined with.

Example: case insensitive calling
function alertUser() {
    echo "You've got mail.";
}

// This is okay, but bad practice
ALERTUSER();
// The same case is good practice
alertUser();

We covered PHP's casing conventions earlier in the course.

Functions can be called as many times as we need.

Example: multiple function calls
function alertUser() {
    echo "You've got mail.";
}

// Multiple calls
alertUser();
alertUser();
alertUser();

Each time the function is called, it will execute its logic.

How to define a function with arguments

We know from using the array() function that we can pass some values to a function through its parameter list.

Parameters are temporary variables that we define and then use in the logic of the function’s code block. It’s similar to the temporary variable in a foreach loop.

To create parameters, we specify them in the parameter list (between parentheses) when we define the function. If we use more than one parameter, we separate them with a commas.

Syntax:
function funcName(param1, param2, param3, ...) {
    // section of logic to execute
    // that contains param1, param2 etc.
}

The parameters we define should be used somewhere in the logic. To demonstrate, let’s add a $user parameter to our function and use it in the echo statement.

Example: function with an argument
function alertUser($user) {
    echo "{$user}. You've got mail.";
}

The value (argument) we pass to the funtion when it’s called will replace all the instances of $user in the logic.

If a function contains a non-default parameter, we have to specify an argument for it when we call the function. Otherwise, the interpreter would raise an error.

Example: no argument specified
function alertUser($user) {
    echo "{$user}. You've got mail.";
}

alertUser();
Output: Missing argument error
 Fatal error: Uncaught ArgumentCountError: Too few arguments...

The output above means that the interpreter expects values in the function call that correspond to the parameters.

So let’s add a string name as an argument.

Example:
function alertUser($user) {
    echo "{$user}. You've got mail.";
}

alertUser("John");

When we run the example above, it will print “John. You’ve got mail”.

note The parameter and argument terms are sometimes mistakenly used interchangeably. A parameter is what we use in a function definition, whereas an argument is what we use in a function call.

How to use optional (default) parameters

PHP allows us to define a fallback value for a parameter. If an argument isn’t given in the function call, the function will use the fallback value.

To do this we simply assign a value to the parameter directly inside the parameter list. However, default parameters must always be at the end of the parameter list.

Syntax: default parameter
function funcName(param1, param2 = value) {
    // logic
}
Example: default parameter
<html>
<body>

<p style="
    background: <?php hslaPicker(206, 100, 44); ?>;
    color: <?php hslaPicker(); ?>"
  >
  Hello there
</p>

<?php

function hslaPicker($h=0, $s=100, $l=100, $a=1.0) {
  echo "hsla({$h}, {$s}%, {$l}%, {$a})";
}

?>

This is useful in situations where we don’t always need a value for a parameter.

How to use named parameters

PHP 8 introduced a feature called named arguments, which allow arguments to be passed to a function in any order.

All we have to do is specify the parameter name followed by a : (colon) and then the argument.

Syntax: named arguments
function funcName(
  param1,
  param2 = value,
  param3 = value
) {
    // logic
}

funcName(param3: value, param1: value)

This feature compliments default parameters perfectly by allowing their values to be skipped.

For example, for the blue color in our hslaPicker() function call we don’t affect the saturation at all, but it has to be included because the lightness is after it in the sequence.

Example: named arguments
<html>
<body>

<p style="
    background: <?php hslaPicker(h:206, l:44); ?>;
    color: <?php hslaPicker(a:0.9); ?>"
  >
  Hello there
</p>

<?php

function hslaPicker($h=0, $s=100, $l=100, $a=1.0) {
  echo "hsla({$h}, {$s}%, {$l}%, {$a})";
}

?>

With named arguments we don’t have to worry about the sequence, we can just pick the parameters we want.

How to use variable parameter lists

PHP allows us to pass more arguments to a function than it has parameters.

We can then access those extra arguments by using the built-in func_get_arg() function, among others.

This function takes a single argument, which is the index number of the parameter we want to access, starting with zero.

Example: variable parameter list
function greeting() {
  $userID   = func_get_arg(0);
  $userName = func_get_arg(1);

  echo "<p>Hello {$userName} ({$userID})</p>";
}

greeting(1, "John");
greeting(2, "Jane");
greeting(3, "Jack");
greeting(4, "Jill");

In the example above we know how many arguments will be passed in the function call, but that may not always be the case.

Luckily, PHP gives us two more functions to handle an unknown amount of arguments.

Example: variable parameter list
function greetAll() {

  // Get the number of arguments
  $len = func_num_args();

  // Store the arguments in array
  $args = func_get_args();

  // Use
  for ($i=0; $i<$len; $i++) {
    echo "<p>Hello {$args[$i]}</p>";
  }
}

greetAll(
  "John",
  "Jane",
  "Jack",
  "Jill",
);

Of course, we may not always need the func_num_args() method to get the number of arguments. An example would be the foreach loop , which doesn’t need an explicit iteration definition.

Example: variable arguments in a foreach loop
function greetAll() {

  // Store the arguments in array
  $args = func_get_args();

  // Use
  foreach ($args as $arg) {
    echo "<p>Hello {$arg}</p>";
  }
}

greetAll(
  "John",
  "Jane",
  "Jack",
  "Jill",
);

How to use variadic parameters

PHP 5.6 simplified the use of variable parameter lists by allowing us to include a variadic parameter.

A variadic parameter is indicated by an ... (ellipsis) and accepts a variable number of arguments.

PHP will automatically populate the variadic array with the arguments from the function call. We don’t need to get the arguments manually with func_get_args() .

Example: variable arguments in a foreach loop
function greetAll(...$args) {

  foreach ($args as $arg) {
    echo "<p>Hello {$arg}</p>";
  }
}

greetAll(
  "John",
  "Jane",
  "Jack",
  "Jill",
);

note A variadic parameter must be the last parameter in the list.

How to call a function in a loop

As mentioned earlier, we can call a function multiple times with or without different arguments.

Example: multiple function calls
function alertUser($user) {
    echo $user . ". You've got mail.<br>";
}

alertUser("John");
alertUser("Jane");
alertUser("Jack");
alertUser("Jill");

In the example above, we call the function four times, and each time we pass a different username as an argument.

A more practical situation will have users in a database, or array. We can call the function inside a loop to handle a large amount of calls.

Example: loop multiple function calls
// Collection of users
$user = ["John", "Jane", "Jack", "Jill"];

// Loop through users and alert each
foreach($user as $username) {
    alertUser($username);
}

// Function definition
function alertUser($user) {
    echo $user . ". You've got mail.<br>";
}

note Complex functions in a loop with many iterations may have a negative impact on the application’s performance. In most cases we don’t have to worry, but it is something to be aware of.

How to return a value from a function

Not only can a function receive values, it can also return values. The value can be ignored, used directly or stored in a data container.

To return a value, we use the return keyword in front of whatever we want to return.

Syntax: return
function funcName(param1, param2, param3, ...) {
    // section of logic to execute

    return something
}

As an example, consider the following function.

Example: return a value
function canVote($age) {
    if($age >= 18) {
        return true;
    } else {
        return false;
    }
}

We evaluate if a user is old enough to vote. If so, the function will return true; otherwise it will return false.

As mentioned before, we can use the value directly, store it in a data container or ignore it.

Example: using the returned value
$userAge = 17;

// Store
$userVote = canVote($userAge);

// Use directly
if( !canVote($userAge) ) {
    echo "Sorry, you are not old enough to vote yet.";
} else {
    echo "You are old enough to vote";
}

// Ignore
canVote($userAge);


// Definition
function canVote($age) {
    if($age >= 18) {
        return true;
    } else {
        return false;
    }
}

The example is somewhat impractical, but it demonstrates how powerful functions can be.

Function return types

In strongly typed languages, such as C#, we have to specify the type of value that a function can return.

Example: C# return type
using System;

namespace Functions
{
    class Program
    {
        static void Main(string[] args)
        {
            isEvenInt(5);
            Console.ReadLine();
        }

        static bool isEvenInt(int num)
        {
            if (num % 2 == 0)
                return true;
            else
                return false;
        }
    }
}

When we look at the example above, we can see that the function isEvenInt() has the bool keyword written in front of it.

This means that the function can only return a boolean value of true or false. If we try to return another type, the compiler will raise an error.

From PHP 7 we can also restrict the return type, although the syntax is different. After the function parentheses, we write a : (colon) and then the type.

Syntax: restrict return type
function functionName(param1, param2, ...) : TYPE {
    // function body
}
Example: restrict return type
function canVote($age) : bool {
    if($age >= 18) {
        return true;
    } else {
        return false;
    }
}

note Returning the wrong type can cause all sorts of problems within our code. It’s important to remember to return the same type as specified.

Anonymous functions

Since PHP 5.3 we are allowed to pass a function as an argument to another function. These functions are called anonymous functions, or lambda’s.

We can think of them as throwaway functions. Sometimes you will need a function to perform an operation, but that operation is not so common that we want to define a regular function as part of the codebase.

An anonymous function is defined like a regular function, except we don’t specify a name.

Syntax: anonymous function
function (parameters) {
    // logic
}

We can assign an anonymous function to a variable using the normal assignment syntax, including the semicolon. The variable can then be called as a function.

Example: variable assignment
$greeting = function($user) {

  echo "Hello {$user}";
};

$greeting("John");

Callback functions

Anonymous functions are mostly used as callback functions. A callback is a function that’s passed as an argument to another function, which calls it as part of its execution.

If a function definition wants to accept a callback it must do 2 things.

  1. Specify a parameter where the anonymous function will be defined.
  2. Invoke that parameter as a function somewhere in the body.

Then, in the function call, we must define an anonymous function as argument.

Example: callback function
function regularFunc($callbackFunc) {

  // Using the parameter as a function
  // turns it into a callback function
  $callbackFunc();
};

// The argument must then be an
// anonymous function
regularFunc(function() {
  echo "Hello there";
});

Closures

A closure is an anonymous function that can capture variables defined outside of the function that are not parameters.

To capture variables defined outside of the function, we specify them in the use() clause after the parameter list in the function header.

We can then use those variables in the function body as we normally would with parameters.

Example: closure with use()
// variable outside function
$msg = "Hello there";

// Capture outside variable with use()
$greeting = function($user) use ($msg) {

  echo "{$msg} {$user}";
};

$greeting("John");

note In PHP, all anonymous functions are closures, implemented using the Closure class.

Arrow functions

PHP 7.4 introduced a more concise syntax for anonymous functions called arrow functions.

Arrow functions support all the same features as anonymous functions, but they are defined and used a little differently.

  • They use the fn keyword instead of the function keyword.
  • The body doesn’t allow curly braces and is denoted with a => (fat arrow) operator.
  • They only allow a single expression, which is implicitly returned.
  • Variables outside of their scope are automatically captured without the use() clause.

So we can shorten our example from the Closures section above as follows.

Example: arrow functions
// Captured automatically
$msg = "Hello there";

// fn instead of function
// => instead of { }
// One auto-returned expression only
$greeting = fn($user) => "{$msg} {$user}";


echo $greeting("John");

Generators

Generators are functions that behave like iterators. They are used to generate a series of values.

Generator values are returned with the yield statement, which will save the state of the function. That means it will be able to continue where it left off when it’s called again.

Example: generator definition
function increment() {

  for ($i = 0; $i <= 5; $i++) {

    // Return $i then save state
    // (current iteration number)
    yield $i;
  }
}

The generator basically reads as follows.

  1. I am at the first iteration.
  2. The value of $i is 0, I returned it for you to use.
  3. Waiting for you to request the next iteration’s value.

As we mentioned earlier, generator functions behave like iterators so we can use them in a foreach loop to get the iteration’s value.

Example: generator definition
function increment() {

  for ($i = 0; $i <= 5; $i++) {

    // Return $i then save state
    // (current iteration number)
    yield $i;
  }
}

foreach(increment() as $value) {
  echo $value;
}

tip A generator will only yield its values on demand, one at a time. They don’t require a whole loop to be computed and stored in memory, which gives us a significant performance boost when handling large amounts of data.

Built in functions

PHP comes with a large amount of built-in functions that are always available, as well as other functions that depend on certain extensions like MySQLi.

Luckily, the development team have assembled a list of all these functions in the PHP Function Reference , and the extensions in the PHP Extension Reference .

Summary: Points to remember

  • A function separates code into smaller sections of logic.
  • A function must be defined with the function keyword.
  • An existing function can be used by calling the function with any arguments it may require between parentheses.
  • A function’s arguments are only available in the local scope (inside the function’s code block).
  • A function can return a single value by using the return statement.
  • A function can restrict its return value with : type.