PHP
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Object-Oriented PHP
-
Section 5: Working with Data
-
Section 6: Modern PHP (PHP 8)
-
Section 7: Working with Files and Networking
-
Section 8: Common PHP Frameworks Overview
-
Section 9: Tooling and Ecosystem
-
Section 10: Practical Projects
-
Section 11: Interview Practice
-
Section 12: More Standard Library
-
Section 13: Data Structures and Algorithms in PHP
-
Section 14: More Practice Exercises
-
Section 15: More Security and Best Practices
-
Section 16: More Testing and Tooling
-
Section 17: WordPress-Style CMS Concepts
-
Section 18: Advanced OOP Practice
-
Section 19: More Web Fundamentals
-
Section 20: Database Practice
-
Section 21: PHP Manual: Array Functions
-
Section 22: PHP Manual: Date and Calendar Functions
-
Section 23: PHP Manual: Filesystem and Directory Functions
-
Section 24: PHP Manual: Filter and Var Handling
-
Section 25: PHP Manual: Math Functions
-
Section 26: PHP Manual: JSON and XML
-
Section 27: PHP Manual: Network and Stream Functions
-
Section 28: PHP Manual: Error and Exception Handling
-
Section 29: PHP Manual: Output Control and Misc
-
Section 30: PHP Manual: FTP, Zip, and Mail
-
Section 31: Modern PHP Frameworks Deep Dive
-
Section 32: PHP Design Patterns
-
Section 33: More Practice Exercises
-
Section 34: PHP Performance and Deployment
-
Section 35: More Interview Practice
-
Section 36: More PHP Standard Library
-
Section 37: PHP Concurrency and Async
-
Section 38: More Web Development Practice
-
Section 39: PHP Testing Deep Dive
-
Section 40: Composer and Package Development
-
Section 41: PHP Security Deep Dive
-
Section 42: More Practical Projects
-
Section 43: Legacy PHP Maintenance
-
Section 44: More Algorithm Practice
-
Section 45: Final Practice and Review
-
Section 46: PHP for E-Commerce Patterns
-
Section 47: PHP API Design Deep Dive
-
Section 48: PHP Caching Strategies
-
Section 49: PHP Queue and Background Jobs
-
Section 50: PHP Multi-Tenancy Patterns
-
Section 51: PHP Real-Time Features
-
Section 52: PHP CMS and Content Modeling
-
Section 53: PHP Internationalization
-
Section 54: More Framework-Specific Practice
-
Section 55: PHP Legacy Code Refactoring
-
Section 56: More Practice Projects Round 2
-
Section 57: PHP Command-Line Applications
-
Section 58: PHP and Microservices
-
Section 59: More Interview and Review Round 2
12: Default and Variadic Arguments
I've noticed a recurring pattern when I'm reviewing code from developers moving into PHP: they often treat default arguments as "optional flags" that can be tossed anywhere in the function signature. You might think that as long as a variable has a default value, PHP will just "skip" it if you don't provide one and move on to the next required argument. It seems intuitive, but it's a trap.
The myth that default arguments can be placed anywhere
Let's look at why this doesn't work. Imagine you're building a notification system and you want a default subject line, but the recipient's email is mandatory. You might try writing it like this:
function sendNotification($subject = "System Alert", $email) {
echo "Sending '$subject' to $email";
}
// You try to call it by only providing the email
sendNotification("dev@example.com");
You're probably expecting PHP to see that you only passed one string, realize it doesn't match the default subject, and assign it to $email. But that's not how it works. PHP assigns arguments positionally. In the example above, "dev@example.com" is assigned to $subject because it's the first argument. Then, PHP realizes $email is missing and throws an ArgumentCountError.
Putting your defaults at the end of the line
To make this actually work, you have to follow one simple rule: optional parameters must come after all required parameters. I usually tell my juniors to think of it as a "mandatory first" queue. If you put the required arguments first, the function knows exactly what it needs to survive before it starts looking at the "nice-to-have" defaults.
function sendNotification($email, $subject = "System Alert") {
echo "Sending '$subject' to $email";
}
// Now this works exactly as you'd expect
sendNotification("dev@example.com");
// Output: Sending 'System Alert' to dev@example.com
Now, what happens if you have five or six optional settings? Writing five different default values starts to feel clunky. That's where variadic arguments come in.
Handling an unknown number of inputs with the splat operator
Sometimes you don't know how many arguments a user will pass. Maybe you're writing a function to calculate a total, or a logger that accepts any number of messages. Instead of forcing the user to wrap everything in an array, you can use the ... operator (which we often call the "splat operator").
When you prefix a parameter with ..., PHP gathers all remaining arguments passed to the function and bundles them into a single array. It's a much cleaner API for whoever is using your function.
function calculateTotal($taxRate, ...$prices) {
$subtotal = array_sum($prices);
return $subtotal + ($subtotal * $taxRate);
}
// I can pass two prices...
echo calculateTotal(0.05, 10.00, 20.00); // 31.5
// ...or twenty prices. The function doesn't care.
echo calculateTotal(0.05, 5.00, 1.50, 10.00, 2.00, 45.00);
One important detail: a variadic parameter must be the very last parameter in your function signature. You can't have a default argument or a required argument coming after the splat, because once PHP starts gathering arguments into that array, there's nothing left for the subsequent variables to grab.
- Required arguments first.
- Default arguments second.
- Variadic arguments (the splat) absolute last.
📋 Practical Task
Building a Flexible Invoice Total Calculator
You are tasked with creating a function called generateInvoiceTotal. This function needs to handle a variety of scenarios for a small business owner.
Requirements:
- The first argument must be the
$customerName(required). - The second argument should be a
$discount(default to 0). - The final argument should be a variadic list of
$items(each item is a numeric price).
The function should:
- Sum all the
$items. - Subtract the
$discountamount from that sum. - Return a string in this exact format:
"Invoice for [Customer]: $[Total]".
Test your code with these two cases:
echo generateInvoiceTotal("Alice", 5, 10, 20, 30);
// Expected: Invoice for Alice: $55 (Sum is 60, minus 5 discount)
echo generateInvoiceTotal("Bob", 0, 100, 200);
// Expected: Invoice for Bob: $300 (Sum is 300, minus 0 discount)
There are no comments for now.