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
function greet(string $name): string
{
return "Hello, {$name}!";
}
echo greet('Asha'); // Hello, Asha!
echo greet('Ben'); // Hello, Ben!
function greetnames the function.string $nameis a parameter: a typed input.: stringis the return type.returnsends 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
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
echo formatPrice(1234.5, decimals: 0); // £1,235
Types
Declaring types documents the function and catches mistakes early:
<?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:
| Declaration | Means |
|---|---|
int, float, string, bool, array | That exact type |
?string | A string or null |
int|float | Either type (a union) |
void | Returns nothing |
mixed | Anything (use sparingly) |
<?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
$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
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
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
$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
$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
?stringandint|floatdocument 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.