Functions are one of the most important building blocks in PHP. They allow developers to group reusable pieces of logic, improve readability, and make code easier to maintain. PHP provides a wide range of ways to define and work with functions - from simple user-defined functions to advanced features like closures, references, and first-class callable syntax.


User-defined Functions

In PHP, you can define your own functions using the function keyword. Function names are case-insensitive.

The list of parameters may also include a trailing comma, which makes it easier to maintain code when adding new parameters.

You can also nest functions inside other functions, though inner functions will not be available until the outer function is executed.

// Simple function
function sayHello($name,) { // trailing comma allowed
    echo "Hello, ${name}!";
}

// Nested function
function outer() {
    function inner() {
        echo "This is the inner function.";
    }
}

// outer() must be called before inner() exists
outer();
inner(); // works now

Function Type Declaration

You can declare the type of parameters and the return type of a function. This makes code more predictable and self-documenting.

function sum(int $a, int $b): int {
    return $a + $b;
}

echo sum(3, 5); // 8

You can use scalar types (int, float, string, bool) as well as object, array, and even union or mixed types.


Recursive Functions

A function can call itself - this is called recursion. Recursion is often used for tasks like calculating factorials, traversing trees, or searching structures.

function factorial(int $n): int {
    if ($n <= 1) {
        return 1;
    }

    return $n * factorial($n - 1);
}

echo factorial(5); // 120

Function Parameters and Arguments

Parameters are variables declared in the function definition. Arguments are the values passed when calling the function.

function greet($name) {
    echo "Hello, ${name}!";
}

greet("Alice"); // "Hello, Alice!"

Passing Arguments by Reference

By default, arguments are passed by value in PHP. If you want a function to modify the original variable, pass it by reference using &.

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

$x = 5;
addOne($x);

echo $x; // 6

Default Parameter Values

You can assign default values to parameters. These are used if no argument is provided.

function greet($name = "Guest") {
    echo "Hello, ${name}!";
}

greet(); // Hello, Guest!
greet("Alice"); // Hello, Alice!

Using Non-scalar Types as Default Values

You can use non-scalar types (arrays, objects, etc.) as default parameter values.

function printItems(array $items = ["apple", "banana"]) {
    foreach ($items as $item) {
        echo $item;
    }
}

printItems();

Using Objects as Default Values

Similarly, objects can also be used as default parameter values.

class Config {
    public string $name = "Default";
}

function showConfig(Config $config = new Config()) {
    echo $config->name;
}

showConfig(); // Default

Variable-length Argument Lists

PHP allows variable-length argument lists using ... (variadic functions).

function sum(...$numbers) {
    return array_sum($numbers);
}

echo sum(1, 2, 3, 4); // 10

Using ... to Provide Arguments

You can also use ... to unpack an array when calling a function.

function multiply($a, $b, $c) {
    return $a * $b * $c;
}

$values = [2, 3, 4];
echo multiply(...$values); // 24

Named Arguments

You can pass arguments by name instead of position.

function createUser($name, $role = "user") {
    echo "${name} is a ${role}";
}

createUser(role: "admin", name: "Bob"); // Bob is a admin

Returning an Array to get Multiple Values

Functions can return values with the return keyword. To return multiple values, you can use an array.

function divide($a, $b): array {
    return [$a / $b, $a % $b];
}

list($quotient, $remainder) = divide(10, 3);

echo $quotient;  // 3.333...
echo $remainder; // 1

Returning a Reference from a Function

You can return a reference so the caller can modify the original variable.

$val = 10;

function &getVal() {
    global $val;

    return $val;
}

$ref = &getVal();
$ref = 20;

echo $val; // 20

Variable Functions

In PHP, you can store a function name in a variable and call it dynamically.

function sayHi() {
    echo "Hi!";
}

$func = "sayHi";
$func(); // Hi!

Anonymous Functions (Closures)

Functions can be created without names. These are often assigned to variables or passed as arguments.

$square = function($n) {
    return $n * $n;
};

echo $square(4); // 16

Closures and Scoping

Closures can use variables from the parent scope with the use keyword.

$message = "Hi";

$greet = function() use ($message) {
    echo $message;
};

$greet(); // Hi

Automatic Binding of $this

In object-oriented PHP, closures can automatically bind $this.

class Demo
{
    public function run()
    {
        $func = function() {
            echo $this->hello();
        };

        $func();
    }

    private function hello()
    {
        return "Hello from class";
    }
}

(new Demo())->run(); // Hello from class

Static Anonymous Functions

You can declare anonymous functions as static. In this case, $this is not available inside the function.

$func = static function() {
    // no $this here

    echo "Static closure";
};

$func();

Arrow Functions

Arrow functions are a shorter syntax for simple closures. They automatically capture variables from the parent scope (by value, not reference).

$numbers = [1, 2, 3];
$squares = array_map(fn($n) => $n * $n, $numbers);

print_r($squares); // [1, 4, 9]
print_r($numbers); // [1, 2, 3]

Values from the outer scope cannot be modified inside arrow functions.


First-class Callable Syntax

You can get a function or method reference using ....

function hello($name) {
    return "Hello, ${name}!";
}

$func = hello(...); // first class callable
echo $func("Alice"); // Hello, Alice!

Source: Orkhan Alishov's notes