Mid-level 5 min · March 06, 2026

PHP Functions — Parameter Order Change Breaks Checkout

Swapped price and tax parameters in calculateTotal() silently outputs zero in checkout.

N
Naren · Founder
Plain-English first. Then code. Then the interview question.
About
 ● Production Incident 🔎 Debug Guide
Quick Answer
  • Functions are named blocks of reusable code defined with the function keyword.
  • Parameters act as placeholders; arguments are the real values passed during a call.
  • Use return to hand back a result — far more flexible than echo inside the function.
  • Variables outside a function are invisible inside unless passed as arguments.
  • Always capture return values or they silently vanish as NULL.
Plain-English First

Think of a PHP function like a vending machine. You put in your money (the input), press a button (call the function), and out comes your snack (the output). The machine handles everything in between — you don't need to know how it works inside, just how to use it. Once the vending machine exists, anyone can use it, as many times as they want, without rebuilding it each time. That's exactly what a function does in PHP.

Every real-world PHP application — from a login form to an e-commerce cart — is built on functions. They're the backbone of organised, maintainable code. Without them, you'd be writing the same logic over and over in dozens of places, and the moment something changes (a tax rate, a validation rule, a greeting message), you'd have to hunt down every copy and fix each one manually. That's where bugs are born.

Functions solve the 'write once, use everywhere' problem. You package a piece of logic into a named block, and then call that block by name whenever you need it. The code stays in one place, so a fix in one spot fixes it everywhere. This is one of the most fundamental ideas in all of programming, and PHP makes it beautifully simple to get started.

By the end of this article you'll know how to define your own PHP functions, pass data into them using parameters, get data back out using return values, set sensible defaults, and understand the difference between built-in and user-defined functions. You'll also walk away knowing the mistakes that trip up almost every beginner — and exactly how to dodge them.

What a PHP Function Actually Is (And Why You Need One)

A function is a named block of code that sits quietly until you call it. The moment you call it, PHP executes every line inside it, then hands control back to wherever you called it from.

PHP ships with hundreds of built-in functionsstrlen() counts characters in a string, array_push() adds items to an array, date() formats a timestamp. You've been using other people's functions without even realising it.

But the real power is writing your own. Imagine you're building a website that greets every user by name. Without a function, you'd write that greeting logic on every page. With a function, you write it once, give it a name like greetUser(), and call that name wherever you need it.

This principle has a name: DRY — Don't Repeat Yourself. Functions are the primary tool for achieving it. They also make your code readable. A well-named function tells a future developer (or future you) exactly what a block of code does, without them having to read every line of it.

BasicFunction.phpPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

// Define the function using the 'function' keyword,
// followed by the name you choose, then parentheses.
function greetUser() {
    // Everything between the curly braces runs when the function is called.
    echo "Hello! Welcome to TheCodeForge." . PHP_EOL;
}

// The function does NOTHING until you call it by name.
// Call it once:
greetUser();

// Call it again — same result, zero extra code written.
greetUser();

// PHP's own built-in function for comparison:
$message = "Hello, World!";
$length  = strlen($message); // strlen is a built-in function — works the same way
echo "The message is " . $length . " characters long." . PHP_EOL;

?>
Output
Hello! Welcome to TheCodeForge.
Hello! Welcome to TheCodeForge.
The message is 13 characters long.
Good to Know:
In PHP, function names are NOT case-sensitive — greetUser(), GreetUser() and GREETUSER() all call the same function. That said, always use the exact name you defined as a habit; it keeps your code readable and consistent.
Production Insight
Without functions, duplicated logic multiplies maintenance cost. Fix one copy and the rest stay broken.
A single function change propagates everywhere automatically – DRY in action.
Rule: if you see the same logic more than twice, refactor into a function.
Key Takeaway
Functions bundle reusable logic under a name, eliminate repetition, and localise changes.
DRY (Don't Repeat Yourself) is the core principle behind function usage.

Passing Data Into Functions — Parameters and Arguments

A function with no input is useful, but a function that can accept data is powerful. This is where parameters come in.

A parameter is a variable you declare inside the function's parentheses. It acts as a placeholder — a slot waiting to receive a value. When you actually call the function and pass a value into that slot, that value is called an argument.

Here's the analogy: a parameter is like a labelled inbox on a desk ('place name here'). An argument is the actual piece of paper you drop into that inbox. The function then uses whatever you dropped in.

You can define multiple parameters by separating them with commas. The order matters — the first argument you pass maps to the first parameter, the second argument maps to the second parameter, and so on.

PHP also lets you define default parameter values. If the caller doesn't pass an argument, the parameter falls back to its default. This is incredibly handy for optional settings — think of it as a form field that's pre-filled but can be changed.

FunctionParameters.phpPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php

// A function with one parameter: $name
// $name is the PLACEHOLDER (parameter), not a real value yet.
function greetUserByName($name) {
    echo "Hey, " . $name . "! Great to see you." . PHP_EOL;
}

// We pass the actual value (argument) when calling the function.
greetUserByName("Alice");   // $name becomes "Alice" inside the function
greetUserByName("Bob");     // $name becomes "Bob" inside the function


// A function with TWO parameters.
function describeProduct($productName, $price) {
    echo $productName . " costs $" . $price . "." . PHP_EOL;
}

describeProduct("Wireless Keyboard", 49.99);
describeProduct("USB Hub", 19.99);


// DEFAULT PARAMETER VALUES
// If no currency is passed, it defaults to "USD".
function formatPrice($amount, $currency = "USD") {
    // The default only kicks in when the caller omits the argument.
    echo $currency . " " . number_format($amount, 2) . PHP_EOL;
}

formatPrice(1299.9);          // Uses default: USD
formatPrice(1299.9, "EUR");   // Overrides default: EUR

?>
Output
Hey, Alice! Great to see you.
Hey, Bob! Great to see you.
Wireless Keyboard costs $49.99.
USB Hub costs $19.99.
USD 1,299.90
EUR 1,299.90
Watch Out:
Parameters with default values MUST come after parameters without defaults. Writing function formatPrice($currency = 'USD', $amount) is a fatal error in PHP. Always put your required parameters first, optional (defaulted) ones last.
Production Insight
Swapping argument order accidentally is a common production bug — wrong data gets mapped to each parameter.
Always define parameters in a stable order and document it; use PHP 8 named arguments to decouple order.
Rule: parameter order is part of your public API — treat it as immutable once callers exist.
Key Takeaway
Parameters are placeholders in the definition; arguments are the actual values passed.
Defaults make parameters optional, but required parameters must come before optional ones.

Getting Data Back Out — Return Values

So far our functions print things directly. That's fine for simple output, but most of the time you want a function to calculate or process something and hand the result back to you so you can decide what to do with it next. That's what return does.

Think of return like a function handing you a receipt. You gave it your payment details (arguments), it processed the transaction (ran the logic), and now it's giving you something back (the return value) that you can hold onto, print, store in a variable, or pass into another function.

Once PHP hits a return statement, the function stops immediately. Anything after return in the same function is ignored. This makes return useful for early exits too — you'll see that pattern a lot in validation functions.

A function that doesn't have a return statement returns NULL by default. That's not an error, it just means the function produces no usable output beyond any side effects (like printing to the screen).

ReturnValues.phpPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php

// This function CALCULATES a result and RETURNS it.
// It does NOT print anything — that's intentional.
function calculateDiscount($originalPrice, $discountPercent) {
    $discountAmount = $originalPrice * ($discountPercent / 100);
    $finalPrice     = $originalPrice - $discountAmount;

    return $finalPrice; // Hand the result back to whoever called us.
}

// We CAPTURE the return value in a variable.
$laptopPrice     = calculateDiscount(1200, 15); // 15% off $1200
$headphonesPrice = calculateDiscount(80, 10);   // 10% off $80

// Now we decide what to DO with those values.
echo "Laptop after discount: $" . number_format($laptopPrice, 2) . PHP_EOL;
echo "Headphones after discount: $" . number_format($headphonesPrice, 2) . PHP_EOL;

// You can also pass a return value directly into another function.
// Here we pass the return value of calculateDiscount() straight into number_format().
echo "Quick price: $" . number_format(calculateDiscount(500, 20), 2) . PHP_EOL;


// EARLY RETURN — stopping a function the moment something goes wrong.
function divideNumbers($numerator, $denominator) {
    if ($denominator === 0) {
        return "Error: Cannot divide by zero."; // Exit immediately.
    }

    return $numerator / $denominator; // Only runs if denominator is not zero.
}

echo divideNumbers(10, 2) . PHP_EOL;  // Works fine
echo divideNumbers(10, 0) . PHP_EOL;  // Caught early

?>
Output
Laptop after discount: $1,020.00
Headphones after discount: $72.00
Quick price: $400.00
5
Error: Cannot divide by zero.
Pro Tip:
Prefer return over echo inside functions. A function that returns a value is flexible — you can print it, store it, or pass it elsewhere. A function that echoes directly is locked into one behaviour. Return gives you options; echo takes them away.
Production Insight
Forgetting to capture a return value is a silent failure — the function runs, but its result disappears into NULL.
If you chain functions, a missing capture can break the entire pipeline without an error.
Rule: every call that returns a value should either be captured or explicitly ignored with @ if intentional.
Key Takeaway
Use return to hand data back — it gives the caller control over output.
Returning NULL when no return is present can cause subtle bugs if the result is used in expressions.

Variable Scope — Why Your Variables 'Disappear' Inside Functions

This is the concept that surprises almost every PHP beginner, so pay close attention. In PHP, variables defined outside a function are NOT automatically available inside it. Functions have their own private scope — like a room with a closed door.

If you create $username = 'Alice' at the top of your script and try to use $username inside a function without passing it in, PHP won't find it. The function's room has no window into the outside world by default.

There are three ways to get data into a function's scope: pass it as an argument (the recommended way), use the global keyword (rarely recommended, mostly a code smell), or use a closure with use() (an advanced topic). For now, stick to passing arguments — it makes your functions predictable and testable.

The reverse is also true: a variable you create inside a function disappears the moment the function finishes. It doesn't leak out into the rest of your script. This isolation is actually a feature, not a bug — it means functions can't accidentally overwrite your other variables.

VariableScope.phpPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<?php

$siteName    = "TheCodeForge";  // This lives in the GLOBAL scope.
$visitorCount = 4200;

function displaySiteInfo() {
    // PHP cannot see $siteName here — it's outside this function's scope.
    // Uncommenting the line below would print nothing (or a notice in strict mode):
    // echo $siteName;

    // This variable lives ONLY inside this function.
    $localMessage = "This message only exists inside displaySiteInfo()";
    echo $localMessage . PHP_EOL;
}

displaySiteInfo();

// $localMessage does NOT exist out here — it died when the function ended.
// echo $localMessage; // Would cause an 'Undefined variable' notice.


// THE RIGHT APPROACH: pass the data as arguments.
function displaySiteInfoCorrectly($siteName, $visitorCount) {
    // Now $siteName and $visitorCount exist in THIS function's scope
    // because we passed them in as arguments.
    echo $siteName . " has " . $visitorCount . " visitors this month." . PHP_EOL;
}

// We explicitly hand the outer variables INTO the function.
displaySiteInfoCorrectly($siteName, $visitorCount);


// THE global KEYWORD — know it exists, but use it sparingly.
$taxRate = 0.08;

function calculateTax($price) {
    global $taxRate; // Reach outside and grab $taxRate from global scope.
    return $price * $taxRate;
}

echo "Tax on $200: $" . calculateTax(200) . PHP_EOL;

?>
Output
This message only exists inside displaySiteInfo()
TheCodeForge has 4200 visitors this month.
Tax on $200: $16
Watch Out:
Using global variables inside functions makes code hard to test and debug — you can never be sure what value $taxRate holds without reading the entire script. Pass values as arguments instead. Your future self will thank you.
Production Insight
Global variables inside functions introduce hidden dependencies — changing a global value affects every function that uses it.
Debugging such bugs often requires tracing through the whole request, which is slow and error-prone.
Rule: keep functions pure — accept everything they need as parameters and return results.
Key Takeaway
Functions have their own scope — outer variables are inaccessible by default.
Always pass required data as parameters; avoid global except for legacy code.

Type Declarations and Return Types – Writing Self-Documenting Functions

PHP 7+ and especially PHP 8 made it possible to declare the type of each parameter and the type of the return value. This isn't just documentation — it forces PHP to enforce the types at runtime, catching bugs before they reach production.

When you write function greet(string $name): string, you tell PHP: 'I expect a string as input, and I guarantee I'll return a string.' If someone passes an array or the function accidentally returns an integer, PHP throws a TypeError immediately.

Type declarations make your function contracts explicit. Anyone reading or using your function knows exactly what to pass and what to expect. Combined with strict mode (declare(strict_types=1);), even implicit type coercions are caught.

Common types include: int, float, string, bool, array, callable, iterable, object, and class/interface names. Union types (int|string) and nullable types (?int) give you even more flexibility.

TypeDeclarations.phpPHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

declare(strict_types=1); // Enforce strict type checking

// Parameter type: int, return type: string
function formatAge(int $age): string {
    return "You are $age years old.";
}

// Union type — either int or float, return type: float
function applyTax(int|float $price, float $rate): float {
    return $price * (1 + $rate);
}

// Nullable parameter — ?string allows null or string
function greetOptional(?string $name): string {
    // If $name is null, replace with a default
    $name = $name ?? 'Guest';
    return "Hello, $name!";
}

// Usage
echo formatAge(30) . PHP_EOL;                    // Works
echo applyTax(100, 0.08) . PHP_EOL;             // Works: 108
// echo formatAge('thirty'); // TypeError if strict_types=1

echo greetOptional('Alice') . PHP_EOL;           // Hello, Alice!
echo greetOptional(null) . PHP_EOL;              // Hello, Guest!

?>
Output
You are 30 years old.
108
Hello, Alice!
Hello, Guest!
Good to Know:
PHP's strict_types=1 directive must be placed at the top of the file (before any other code) and affects only the file where it's declared. It doesn't propagate to included files.
Production Insight
Without type declarations, a function expecting an integer may receive a string '0' and silently produce incorrect results.
Strict types catch these mistakes at the call site immediately, preventing hard-to-debug data flow errors.
Rule: always declare parameter and return types for new functions — it's a minimal cost for huge safety gains.
Key Takeaway
Type declarations make function contracts explicit and catch type mismatches early.
Use declare(strict_types=1) to disable coercion and enforce strict types per file.
● Production incidentPOST-MORTEMseverity: high

Parameter Order Change Breaks Checkout

Symptom
Prices displayed as ‘0’ or swapped with product names in the checkout summary. No error, just wrong numbers.
Assumption
PHP allows variable numbers of arguments, so reordering parameters is safe without updating callers.
Root cause
Function calculateTotal($price, $tax) became calculateTotal($tax, $price). All existing calls passed arguments in the original order, leading to misuse of values.
Fix
Use PHP 8 named arguments (calculateTotal(tax: $rate, price: $subtotal)), or wrap parameters into an associative array. Also update all callers to match the new order.
Key lesson
  • Parameter order is part of the public contract — treat it as immutable once callers exist.
  • Named arguments eliminate positional order dependencies and are easier to read.
  • Unit tests should catch swapped arguments if values are distinct enough.
Production debug guideCommon symptoms and immediate actions when things go wrong with functions.5 entries
Symptom · 01
Function unexpectedly returns NULL
Fix
Check each code path inside the function — is there a return statement on every branch? If not, default is NULL. Add explicit return for all cases.
Symptom · 02
Variable inside function is undefined (notice)
Fix
That variable likely lives outside the function. Either pass it as a parameter or use the global keyword (but prefer parameters).
Symptom · 03
ArgumentCountError: wrong number of arguments
Fix
Count the required parameters defined in the function signature. Match exactly when calling. If some parameters are optional, add defaults in the definition.
Symptom · 04
Function call produces no output and no error
Fix
Check if the function does return instead of echo. Capture the return value in a variable and then print it.
Symptom · 05
Call to undefined function error
Fix
Verify the function is defined in an included file and that the file was loaded before the call. Check for conditional definitions — functions inside if blocks aren't available until the block runs.
Aspectecho Inside Functionreturn From Function
What it doesPrints output directly to the browser/consoleSends the result back to the caller
FlexibilityLow — output is fixed, always goes to screenHigh — caller decides what to do with the result
ReusabilityHard to reuse in different contextsEasy — result can be stored, passed on, or printed
TestabilityDifficult to test automaticallySimple to test — just check the returned value
Best used forQuick debug output, final display layerBusiness logic, calculations, data processing
ComposabilityCannot be chained with other functionsReturn value can feed directly into another function

Key takeaways

1
A function is defined once with the function keyword and can be called as many times as needed
this is the DRY principle in action.
2
Parameters are the placeholders in the function definition; arguments are the real values you pass when calling it. Default values make parameters optional.
3
Use return to hand data back to the caller
it's far more flexible than echoing inside the function, because the caller decides what to do with the result.
4
PHP functions have their own variable scope
outer variables don't exist inside a function unless you pass them as arguments. This isolation is a feature, not a flaw.
5
Type declarations (parameter + return types) enforce contracts at runtime, preventing subtle data corruption bugs in production.

Common mistakes to avoid

3 patterns
×

Calling a function before it's defined in conditional code

Symptom
Fatal error: Call to undefined function — but only when the conditional branch hasn't been executed.
Fix
Define all user functions at the top of the file or in a separate included file, before any business logic. Avoid defining functions inside if/else blocks.
×

Forgetting to capture the return value

Symptom
The function runs but nothing visible happens — the result vanishes because it's not assigned or used.
Fix
Always assign the function result to a variable: $result = myFunction();. Then use $result as needed.
×

Assuming outer variables are available inside a function

Symptom
Undefined variable notices when trying to use a global variable inside the function, or the variable reads as empty.
Fix
Pass every needed value as a parameter: function myFunc($requiredVar). Do not rely on global scope.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01JUNIOR
What is the difference between a parameter and an argument in PHP, and c...
Q02JUNIOR
Explain variable scope in PHP. If I define a variable outside a function...
Q03SENIOR
What does a PHP function return if it has no explicit return statement, ...
Q04SENIOR
How do you declare a function that accepts either an integer or a float,...
Q01 of 04JUNIOR

What is the difference between a parameter and an argument in PHP, and can you give a concrete example of each?

ANSWER
A parameter is a variable listed in the function definition — it acts as a placeholder. An argument is the actual value you pass when calling the function. Example: ``php function greet($name) { // $name is a parameter echo "Hello, $name"; } greet('Alice'); // 'Alice' is an argument ``
FAQ · 4 QUESTIONS

Frequently Asked Questions

01
What is the difference between a built-in PHP function and a user-defined function?
02
Can a PHP function return more than one value?
03
What happens if I call a PHP function with the wrong number of arguments?
04
Do I always need to declare type hints for parameters and return values?
🔥

That's PHP Basics. Mark it forged?

5 min read · try the examples if you haven't

Previous
PHP Control Flow
5 / 14 · PHP Basics
Next
PHP Arrays