Functions
Defining and calling
<?php
function greet(string $name): string {
return "Hello, $name!";
}
echo greet("Asha"), "\n";
echo greet("Leo"), "\n";string $name declares the parameter's type, and : string the return type. Types are optional in PHP, but they catch mistakes early and document what a function expects.
Default values and named arguments
<?php
function price(float $amount, float $tax = 0.18, string $currency = "INR"): string {
return sprintf("%.2f %s", $amount * (1 + $tax), $currency);
}
echo price(100), "\n"; // both defaults
echo price(100, 0.05), "\n";
echo price(100, currency: "USD"), "\n"; // named argument: skip $tax
echo price(currency: "EUR", amount: 50), "\n";Named arguments (PHP 8) let you skip optional parameters and pass arguments in any order. They also make calls self-explanatory: price(100, currency: "USD") reads better than price(100, 0.18, "USD").
Nullable and union types
<?php
function findUser(int $id): ?string { // ?string: a string or null
$users = [1 => "Asha", 2 => "Leo"];
return $users[$id] ?? null;
}
function double(int|float $n): int|float { // union type: either
return $n * 2;
}
var_dump(findUser(2), findUser(9));
var_dump(double(4), double(2.5));Any number of arguments
<?php
function average(float ...$nums): float {
return count($nums) ? array_sum($nums) / count($nums) : 0;
}
echo average(4, 8, 6), "\n";
$scores = [70, 85, 90];
echo average(...$scores), "\n"; // spread an array into arguments...$nums collects all the arguments into an array; ...$scores does the reverse, spreading an array out into separate arguments.
Passing by reference
<?php
function addBonus(array &$scores, int $bonus): void {
foreach ($scores as &$s) {
$s += $bonus;
}
}
$scores = [70, 85];
addBonus($scores, 5);
print_r($scores);PHP normally passes copies, so a function can't change the caller's variables. An & before a parameter passes the variable itself. Use it sparingly: returning a new value is usually clearer.
Anonymous functions and closures
<?php
$taxRate = 0.18;
$withTax = function (float $price) use ($taxRate): float {
return $price * (1 + $taxRate);
};
echo $withTax(100), "\n";
$double = fn($x) => $x * 2; // arrow function
$addTax = fn($price) => $price * (1 + $taxRate); // captures $taxRate automatically
echo $double(21), " ", $addTax(200), "\n";
print_r(array_map($double, [1, 2, 3]));- An anonymous function can be stored in a variable and passed around. To use an outside variable, list it with
use. - An arrow function,
fn($x) => expression, is a one-line version that captures outside variables automatically.
Strict types
<?php
declare(strict_types=1);
function add(int $a, int $b): int {
return $a + $b;
}
echo add(2, 3), "\n";
echo add("2", 3), "\n";By default, PHP converts "2" to 2 to fit an int parameter. With declare(strict_types=1); as the file's first statement, it throws a TypeError instead, as you can see. Many modern projects put this line at the top of every file.