Functions

Package logic into reusable, typed functions with clear inputs and outputs.

  • Beginner
  • 5 min read
  • Updated 17 Oct 2026

What you will learn

  • Define and call functions
  • Add typed parameters, default values and return types
  • Explain variable scope inside functions
  • Use named arguments, arrow functions and closures

Before you start

A function is a named block of code you can run whenever you need it. Functions remove repetition, give logic a clear name, and make code easier to test.

Defining and calling

PHP
<?php

function greet(string $name): string
{
    return "Hello, {$name}!";
}

echo greet('Asha'); // Hello, Asha!
echo greet('Ben');  // Hello, Ben!
  • function greet names the function.
  • string $name is a parameter: a typed input.
  • : string is the return type.
  • return sends a value back to the caller and ends the function.

PHP has thousands of built-in functions, such as strlen() and count(). The ones you write work exactly the same way.

Parameters and defaults

Parameters can have default values, used when an argument is left out:

PHP
<?php

function formatPrice(float $amount, string $currency = '£', int $decimals = 2): string
{
    return $currency . number_format($amount, $decimals);
}

echo formatPrice(1234.5);          // £1,234.50
echo formatPrice(1234.5, '$');     // $1,234.50
echo formatPrice(1234.5, '€', 0);  // €1,235

Put parameters with defaults after the required ones.

Named arguments

Since PHP 8 you can pass arguments by name, which skips defaults you do not need and makes calls self-explanatory:

PHP
<?php

echo formatPrice(1234.5, decimals: 0); // £1,235

Types

Declaring types documents the function and catches mistakes early:

PHP
<?php

declare(strict_types=1);

function average(array $numbers): float
{
    if ($numbers === []) {
        return 0.0;
    }

    return array_sum($numbers) / count($numbers);
}

echo average([4, 8, 9]); // 7

Useful type declarations:

DeclarationMeans
int, float, string, bool, arrayThat exact type
?stringA string or null
int|floatEither type (a union)
voidReturns nothing
mixedAnything (use sparingly)
PHP
<?php

function findUser(int $id): ?array
{
    $users = [1 => ['name' => 'Asha']];

    return $users[$id] ?? null;
}

$user = findUser(2);

if ($user === null) {
    echo 'User not found';
}

Scope: functions have their own variables

Variables created outside a function are not visible inside it, and vice versa:

PHP
<?php

$siteName = 'Geeks2Smart';

function title(): string
{
    return $siteName; // Warning: Undefined variable $siteName
}

This is a feature: a function only depends on what it is given. Pass the value in as a parameter instead:

PHP
<?php

function title(string $siteName, string $page): string
{
    return "{$page} | {$siteName}";
}

echo title('Geeks2Smart', 'Arrays'); // Arrays | Geeks2Smart

You may see global $siteName; in old code. Avoid it. Functions that read globals are hard to reason about and hard to test.

Returning early and returning several values

A function can have several return statements; the first one reached wins. To return several values, return an array and unpack it:

PHP
<?php

function minMax(array $numbers): array
{
    return [min($numbers), max($numbers)];
}

[$lowest, $highest] = minMax([7, 3, 9, 1]);

echo "{$lowest} to {$highest}"; // 1 to 9

Anonymous functions, closures and arrow functions

Functions can be values. This is how you pass behaviour to functions like array_map and usort.

An arrow function is a short form for a single expression. It automatically sees variables from the surrounding code:

PHP
<?php

$rate = 1.2;
$prices = [10, 20, 30];

$withVat = array_map(fn(float $p): float => $p * $rate, $prices);
// [12, 24, 36]

A closure can contain several statements. It must list outside variables it uses with use:

PHP
<?php

$minimum = 18;

$isAdult = function (int $age) use ($minimum): bool {
    if ($age < 0) {
        return false;
    }

    return $age >= $minimum;
};

var_dump($isAdult(21)); // bool(true)

Good function habits

  • Do one thing. If you struggle to name a function without "and", split it.
  • Name with a verb: calculateTotal(), sendInvoice(), isValidEmail().
  • Keep them short enough to read without scrolling.
  • Prefer parameters and return values over reading or changing outside state.

Summary

  • Define functions with function name(type $param): returnType { ... }.
  • Defaults and named arguments make calls flexible and readable.
  • Types such as ?string and int|float document intent and catch bugs.
  • Functions have their own scope; pass in what they need.
  • Arrow functions (fn) and closures let you pass behaviour to other functions.

Further reading