Functions

Functions let you group reusable logic with inputs (parameters) and outputs (return values). PHP supports default/typed/variadic parameters, pass-by-reference, anonymous & arrow functions, and closures.

Declare & Call

<?php
  function greet($name) {
    echo "Hello, $name";
  }
  greet("Sonu");
?>

Parameter Types & Defaults

FeatureExampleNotes
Defaultfunction f($x = 10)Must come after required params
Typedfunction f(int $x)Works better with declare(strict_types=1)
Nullablefunction f(?string $s)Allows $s to be null
Unionfunction f(int|string $id)PHP 8+. Combine allowed types
Variadicfunction f(...$items)Accepts any number of args
<?php
  declare(strict_types=1);

  function makeLabel(string $text, int $qty = 1) : string {
    return str_repeat($text . " ", $qty);
  }

  function formatId(int|string $id) : string {
    return "ID:" . $id;
  }

  function hello(?string $name = null) : string {
    return $name ? "Hello $name" : "Hello Guest";
  }
?>

Return Types

Return TypeExampleNotes
Scalarfunction f(): int {}int, float, string, bool
Array/Objectfunction f(): array {}Or object / class types
Nullablefunction f(): ?User {}May return null
Unionfunction f(): int|string {}PHP 8+
voidfunction f(): void {}No return value
neverfunction f(): never { throw ... }Does not return

Pass-by-Reference &

Allows the function to modify the caller’s variable.

<?php
  function addTax(&$price, float $rate) : void {
    $price *= 1 + $rate;
  }
  $p = 100;
  addTax($p, 0.18);
  echo $p; // 118
?>
Use sparingly: Reference parameters can make code harder to reason about.

Variadic Parameters ...$args

<?php
  function sumAll(int ...$nums) : int {
    $total = 0;
    foreach ($nums as $n) { $total += $n; }
    return $total;
  }
  echo sumAll(1,2,3); // 6
?>

Anonymous Functions & Closures

Anonymous functions can capture variables from the outer scope using use.

<?php
  $rate = 0.18;
  $addTax = function($price) use ($rate) {
    return $price * (1+$rate);
  };

  echo $addTax(100); // 118
?>

By-reference use

<?php
  $count = 0;
  $inc = function() use (&$count) {
    $count++;
  };
  $inc(); $inc();
  echo $count; // 2
?>

Arrow Functions (fn)

Short syntax; implicitly capture outer variables by value (no use needed).

<?php
  $tax = 0.18;
  $apply = fn($p) => $p * (1+$tax);
  echo $apply(200); // 236
?>

Callbacks & Higher-Order Functions

Many built-ins accept callable (string function name, array [obj, "method"], anonymous/arrow).

<?php
  $nums = [1,2,3];

  // array_map with arrow function
  $double = array_map(fn($x) => $x*2, $nums);

  // usort with custom comparator
  $users = [['name'=>'A','age'=>30],['name'=>'B','age'=>25]];
  usort($users, fn($u1,$u2) => $u1['age'] <=> $u2['age']);
?>

Variable Functions (Dynamic Call)

<?php
  function hello() { echo "Hi"; }
  $fn = "hello";
  $fn(); // calls hello()
?>

Recursion

<?php
  function factorial(int $n) : int {
    if ($n <= 1) return 1;
    return $n * factorial($n-1);
  }
  echo factorial(5); // 120
?>

Static Variables & Scope

<?php
  function counter() {
    static $i = 0;
    $i++;
    return $i;
  }
  echo counter()." ".counter(); // 1 2
?>

Error Handling in Functions (Brief)

  • Return special values (like null) and document it, or
  • Throw exceptions for exceptional conditions and catch them where appropriate.

Best Practices

  • Prefer small, single-purpose functions with clear names.
  • Use type hints and return types. Enable declare(strict_types=1) per file.
  • Use default values for optional params; put required params first.
  • Avoid global state; prefer passing dependencies explicitly.
  • Document edge cases and return values (especially nullable/union types).

Practice Tasks

  1. Create slugify(string $title): string that lowercases, trims, replaces spaces with -, and removes non-alphanumerics.
  2. Write sumOfSquares(int ...$n): int using a variadic param and array_reduce.
  3. Use a closure with use to build a multiplier factory: makeMultiplier($k) returns a function that multiplies by $k.
  4. Write deepCount(array $a): int recursively counts all values including nested arrays.
  5. Sort a product list by price (then name) using usort and a comparator that returns <=>.
Next: Head to Arrays for deep operations (creation, slicing, searching, sorting, mapping, filtering) and common patterns.