1.4 · Functions & variable scope

Level 1 · Language basics

1.4Functions & variable scope

Goal: write reusable functions (parameters, return, default values, typing), understand variable scope, and split code cleanly.
Estimated time: 11 min · self-paced reading · If you only have 5 min: read “The essentials in 30s” + the diagram.

The essentials in 30 seconds

  • Function = inputs → processing → output: function nom($params) { return ... } — explicit parameters, returned result.
  • Local scope, no globals: an inner variable is invisible outside (and vice versa) — pass everything as parameters.
  • Type in modern PHP: function f(int $a): int (+ strict_types) — documents, catches errors, makes robust.

Running mini-case — Riad factors his quotes in Constantine

Riad computes the incl-VAT price in three places on his site with the same copy-paste — and when the rate changes, he forgets one place: one quote in three is wrong. He creates a typed prixTTC($ht, $taux = 0.19) function, which receives everything as parameters and returns the result: a single place to fix. He notices along the way that a $total variable defined in the function does not exist outside — local scope forces him to return cleanly. All three quotes become right at once.

Sequel to cases 1.1-1.3 — Riad moves from repetition to reuse.

1. Defining and calling a function

A function is a REUSABLE block of code. Define it with function and call it by name: function saluer($nom) { return 'Hello ' . $nom; } then saluer('Alice'). Parameters are the inputs; return sends back the output. You can have default parameters ($nom = 'unknown'). Functions avoid duplication and improve readability, maintenance and testing.

Riad replaces his three TTC-computation copy-pastes with a call to prixTTC(10000): the default rate applies, and a special case passes its own rate.

2. Scope & typing

Scope: a variable defined INSIDE a function is local (invisible outside); an outer variable is not reachable inside. Wanted isolation — data is passed as parameters (not via globals). Modern PHP encourages typing: function additionner(int $a, int $b): int documents, catches errors, makes robust. Also worth knowing: closures (anonymous functions) and the hundreds of native functions — do not reinvent, check the docs.

Riad types his function as (float $ht, float $taux = 0.19): float with declare(strict_types=1): a wrong type raises a clear error instead of a silently wrong quote.

Common misinterpretation: "A function sees outer variables" or "typing is just for show". No. In PHP, the outside does not enter the function: a global variable is not reachable there (and that is intended) — everything goes through parameters, the result comes out via return. And typing is not decoration: it turns silent bugs into clear errors at the call site, documents the interface and helps the editor — minimal cost, major benefits.
A function Inputs → processing → output Parameters Theinputs (typed)Processing Local,isolated code (scope)return The returnedoutput
Inputs → processing → output
Text version of the diagram (SEO / screen readers / translation): 1) Define: Riad writes function prixTTC($ht, $taux = 0.19) once instead of three copy-pastes. 2) Isolate: inner variables are local — everything enters via parameters, everything exits via return, no globals. 3) Type: (float ...): float + strict_types, clear error on a wrong type. Lesson: one function = explicit interface, isolated space, declared types.

🔎 Concrete example — 🔎 Concrete example — A typed function

Clear inputs and output, like Riad for his quotes.

declare(strict_types=1);
function prixTTC(float $ht, float $taux = 0.20): float {
    return $ht * (1 + $taux);
}
echo prixTTC(100); // 120
echo prixTTC(100, 0.055); // 105.5

Reading: typed parameters, default for the current rate, typed return — the interface reads without opening the body.

Lesson: declare(strict_types=1) for rigorous typing — a reusable, self-documented function.

Section vocabulary

Function
Reusable block of code performing a task: function saluer($nom) { return ... }, called by name. Avoids duplication, improves readability and maintenance.

Simple example: Riad's single prixTTC($ht, $taux), called three times.

What it is not: the same computation copy-pasted in three places.

Reflex: computation repeated twice = function.

Parameters / return
Parameters: data passed as input (with possible default values). Return (via return): the sent-back result. The function's inputs and outputs.

Simple example: Riad's $ht and $taux, and the returned incl-VAT price.

What it is not: reading a global and modifying an outer variable.

Reflex: everything enters via parameters, everything exits via return.

Scope
A variable defined in a function is LOCAL (invisible outside); an outer variable is not reachable inside the function. Wanted isolation — pass data as PARAMETERS.

Simple example: Riad's inner $total, invisible from outside.

What it is not: reaching a global via the global keyword.

Reflex: need some data? parameter, not global.

Parameter/return typing
Declaring types (function f(int $a): int) documents, catches errors and makes code robust — strongly recommended in modern PHP.

Simple example: Riad's (float $ht, float $taux): float.

What it is not: a price passed as text silently skewing the quote.

Reflex: type parameters and return, enable strict.

Closures / native functions
Anonymous (closures) and arrow functions: unnamed, storable/passable (callbacks). PHP has hundreds of native functions (strlen, array_map…) — check the docs.

Simple example: Riad sorting with usort and an arrow function instead of coding his own sort.

What it is not: hand-rewriting an existing native function.

Reflex: look for the native before coding.

In practice — In practice — Writing reusable functions

  1. Define a function with `function`, parameters and a `return` (e.g. compute an incl-VAT price from an ex-VAT price).
  2. Add a default parameter and test the call with and without that parameter.
  3. Observe scope: a variable defined in the function does not exist outside; pass outer data as PARAMETERS (not via globals).
  4. Add parameter and return typing (`function f(int $a, int $b): int`) and discover a few native functions (strlen, count, array_map).
You write reusable functions (parameters, return, default values, typing), understand variable scope, and split your code cleanly — a pillar of programming.

Ready-to-say script — refusing the global in code review (30 s)

"I suggest we pass this data as a parameter rather than a global: the signature will say what the function expects, it will stay predictable and testable. Globals create hidden dependencies — the next bug will come from there."

Say in code review; show the signature before/after.

Copy-paste template — typed prixTTC function (parameters + default + return)

Quote in Constantine

Like Riad: a single typed prixTTC function — the day the rate changes, one line to fix, three correct quotes.

Outer data to use

Pass it as an explicit parameter: the signature documents the need, the function stays testable in isolation.

Default value

The current rate as default ($taux = 0.19): the simple call covers the common case, the full call the special case.

Sort or transform

A closure or arrow function for usort/array_map: the one-off processing fits in one line, with no dedicated named function.

✓ Best practices

  • Pass data as parameters and return the result (no globals).
  • Type parameters and return (declare(strict_types=1)).
  • Look for a native function before hand-coding.

✗ Common pitfalls

  • Using global variables (hidden dependencies, side effects).
  • Writing a giant function with multiple responsibilities.
  • Reinventing an existing native function.

Key takeaways

  • FUNCTIONS are reusable blocks (PARAMETERS in, RETURN out): avoid duplication, improve readability, maintenance and testing.
  • SCOPE: a variable defined in a function is LOCAL; outer variables are not reachable inside (isolation) — pass data as PARAMETERS.
  • Modern PHP: TYPE parameters and return (`function f(int $a): int`) documents, catches errors, makes robust.
  • Closures for callbacks; HUNDREDS of NATIVE functions — check the docs, do not reinvent. Well split = maintainable code.

48h challenge — apply tomorrow

Extract a duplicated computation from your code into a typed function (template above): explicit parameters, return, strict_types. Call it at the old places and check the results. 25 minutes is enough.

Section exit checklist
  • I define functions with parameters, default, return and types.
  • I respect local scope — no globals.
  • I look for the native function before hand-coding.
Self-assessment 1-5: do my functions receive everything as parameters?are my parameters and returns typed?

Frequently asked questions

Why pass data as parameters rather than global variables?

In PHP, a variable defined in a function is local, and an outer variable is not reachable inside (wanted isolation). You COULD use the `global` keyword, but that is bad practice: hidden coupling (nothing in the signature shows the dependency), unpredictable side effects (remote modifications), hard to TEST, limited reuse. Passing as PARAMETERS gives: EXPLICIT interface, predictability (same inputs = same result), testability, decoupling. For shared config, use clean approaches (dependency injection, services) rather than globals.

Should you type parameters and returns in PHP, and what does it bring?

Yes, strongly recommended in modern PHP. Typing brings: (1) ERROR detection — a wrong type raises a clear error at the call site (especially in strict mode); (2) implicit DOCUMENTATION — types describe the interface without reading the body; (3) better TOOLING — autocompletion, static analysis, safe refactoring; (4) ROBUSTNESS. Enable `declare(strict_types=1);` and convert explicitly when needed. Minimal cost, major benefits.

Check your understanding

How should a function receive the data it needs?

Additional resources (optional, to go further)

Level 1 examFresh, harder questions to test what you've learned