A function is a named block of code that performs a task and can be reused.
In programming, there is a sacred principle: DRY (Don’t Repeat Yourself). If you find yourself copying and pasting the same block of code in two different places, you are doing something wrong.
Functions allow us to package logic, give it a name, and reuse it as many times as we want. They are like small sub-programs within your program.
Anatomy of a Function
To define a function we use the keyword function. But since we are in a professional course, we will apply everything we have learned about strict types.
// Structure:
// function name(Type $argument): ReturnType { ... }
function calculateDiscount(float $price, int $percentage): float {
$discount = $price * ($percentage / 100);
return $price - $discount;
}Arguments and Return
- Arguments: The data the function needs to work (inputs).
- Return: The result the function sends back to the main code (output).
Try to ensure each function has a single clear responsibility. Avoid functions that calculate, save to a database, AND send an email all at once. Divide and conquer.
return vs echo
A classic beginner mistake is putting an echo inside the function.
- Bad: The function prints the result. (It limits you; you cannot use that result for other calculations).
- Good: The function uses
return. You decide externally whether to print it, save it, or send it.
The void Type
If your function does not return anything (for example, it only saves a log to a file), you must specify its return type as : void.
function saveLog(string $message): void {
file_put_contents('log.txt', $message . "\n", FILE_APPEND);
// No return
}Default Values
Sometimes, an argument often has a common value 90% of the time. To avoid writing it every time, we can define a default value.
// If you don't pass the $vat, I assume it's 21
function calculateTotal(float $price, int $vat = 21): float {
return $price * (1 + ($vat / 100));
}
// Usage:
echo calculateTotal(100); // Uses 21% (Result: 121)
echo calculateTotal(100, 10); // Uses 10% (Result: 110)Arguments with default values must always go at the end of the argument list.
Named Arguments
Imagine a function with many optional arguments:
function configureCookie(
string $name,
string $value,
int $lifetime = 3600,
string $path = '/',
bool $secure = false
): void {
// Function implementation
}In the past, if you wanted to change only the last argument ($secure), you had to fill in all the previous ones even if they were default values:
configureCookie('user', 'luis', 3600, '/', true);
What does that true at the end mean? No one knows just by reading it. It is opaque code.
The Modern Solution: You can call the function using the argument name. The order no longer matters, and you can skip those with default values.
configureCookie(
name: 'user',
value: 'luis',
secure: true
);Notice: we have skipped $lifetime and $path. PHP uses their default values automatically. Moreover, secure: true explains the intention better than a loose boolean.
Since the parameter name is part of the call, changing it can break code that uses named arguments.
“Nullable” Types (?)
Sometimes you want to allow an argument to be a valid value OR null. We use the question mark ? before the type.
function greet(?string $name): string {
if ($name === null) {
return "Hello, Guest";
}
return "Hello, $name";
}
greet("Luis"); // Ok
greet(null); // Ok