Function Type System

Loading concept...

🎯 PHP Function Type System: Teaching Your Code to Be PICKY!

The Magic Analogy: Imagine you have a toy sorting machine. This machine only accepts specific toys—cars go in the car slot, dolls in the doll slot. If you try to put a car in the doll slot, the machine says “NOPE!” That’s exactly what PHP’s type system does for your functions!


🎪 The Story Begins: Why Types Matter

Once upon a time, PHP was very relaxed. You could pass anything to a function—numbers, words, bananas (okay, not bananas). But this caused problems! Imagine asking for someone’s age and getting “purple” as an answer. Confusing, right?

So PHP learned to be picky. Now your functions can say: “I only want numbers!” or “Give me text, nothing else!”

Let’s explore this magical world together! 🚀


📦 1. Type Declarations: Labeling Your Toy Boxes

What is it? Type declarations are like labels on toy boxes. They tell PHP exactly what kind of data a function accepts (input) and returns (output).

🧸 Simple Example

function addNumbers(int $a, int $b): int
{
    return $a + $b;
}

echo addNumbers(5, 3); // Output: 8

What’s happening?

  • int $a → “I only accept whole numbers for $a”
  • int $b → “Same for $b”
  • : int → “I promise to return a whole number”

📋 Common Type Labels

Type What It Means Example
int Whole numbers 42, -7
float Decimal numbers 3.14, 99.9
string Text "Hello"
bool True or False true, false
array Lists of things [1, 2, 3]

🎨 Real-World Example

function greetUser(string $name): string
{
    return "Hello, " . $name . "!";
}

echo greetUser("Emma"); // "Hello, Emma!"

⚡ 2. Strict Types: The SUPER Picky Mode

The Problem: By default, PHP tries to be helpful. If you pass "5" (text) to a function expecting int, PHP quietly converts it. Sometimes helpful, sometimes… chaos!

The Solution: declare(strict_types=1);

This tells PHP: “Don’t guess. Don’t convert. Be STRICT!”

🔒 How to Enable Strict Mode

<?php
declare(strict_types=1);

function multiply(int $x, int $y): int
{
    return $x * $y;
}

echo multiply(4, 5);    // ✅ Works: 20
echo multiply("4", 5);  // ❌ ERROR! String not allowed!

🎭 With vs Without Strict Types

graph TD A[Pass "5" to int function] --> B{Strict Mode?} B -->|No| C[PHP converts to 5] B -->|Yes| D[ERROR! Type mismatch!] C --> E[Function runs] D --> F[Code stops]

🌟 Why Use Strict Mode?

  1. Catches bugs early → No silent conversions
  2. Code is predictable → What you see is what you get
  3. Easier debugging → Errors point exactly where things went wrong

🌙 3. Nullable Types: “Maybe” Values

The Story: Sometimes a function might return something… or nothing. Like asking “What’s your middle name?” Some people have one, some don’t!

The Solution: Add ? before the type to say “this can be null”

💫 Example: Maybe a String, Maybe Nothing

function findNickname(?string $name): ?string
{
    if ($name === null) {
        return null;
    }
    return substr($name, 0, 3);
}

echo findNickname("Alexander"); // "Ale"
echo findNickname(null);        // null (nothing)

🎯 Breaking It Down

  • ?string $name → “Give me text OR null”
  • ?string return → “I’ll give back text OR null”

📊 Visual: Regular vs Nullable

Type Accepts Example
string Only text "hi" ✅, null
?string Text OR null "hi" ✅, null

🌈 4. Union Types: “This OR That” (PHP 8+)

The Magic: What if your function accepts MULTIPLE types? Like a sorting machine that takes cars OR trucks!

The Syntax: Use | (pipe) between types

🎪 Example: Accept Number or Text

function display(int|string $value): void
{
    echo "Value: " . $value;
}

display(42);        // ✅ "Value: 42"
display("Hello");   // ✅ "Value: Hello"
display(3.14);      // ❌ ERROR! Float not allowed

🔗 Multiple Union Types

function process(
    int|float|string $input
): int|float
{
    if (is_string($input)) {
        return strlen($input);
    }
    return $input * 2;
}

echo process(5);      // 10
echo process(2.5);    // 5.0
echo process("cat");  // 3 (length of "cat")

🎨 Flow Diagram

graph TD A[Input Value] --> B{What type?} B -->|int| C[Accept ✅] B -->|float| D[Accept ✅] B -->|string| E[Accept ✅] B -->|array| F[Reject ❌]

📤 5. Pass by Value: Making Copies

The Toy Analogy: When you lend your toy to a friend, you give them a COPY. They can break their copy, but YOUR original toy is safe at home!

Default Behavior: PHP passes copies to functions.

🎁 Example: The Original Stays Safe

function addTen($number)
{
    $number = $number + 10;
    return $number;
}

$myAge = 25;
$result = addTen($myAge);

echo $myAge;   // 25 (unchanged!)
echo $result;  // 35 (the copy was modified)

🔍 What Happened?

  1. $myAge has value 25
  2. Function receives a COPY of 25
  3. Copy becomes 35
  4. Original $myAge still 25!
graph LR A[Original: $myAge = 25] --> B[Copy sent to function] B --> C[Copy becomes 35] A --> D[Original still 25]

📎 6. Pass by Reference: Sharing the REAL Thing

The Toy Analogy: Instead of giving a copy, you give your friend your ACTUAL toy. If they paint it red, YOUR toy is now red!

The Magic Symbol: & (ampersand)

🔴 Example: Modifying the Original

function addTenRef(&$number)
{
    $number = $number + 10;
}

$myAge = 25;
addTenRef($myAge);

echo $myAge;  // 35 (changed!)

💡 Why Use References?

  1. Modify multiple values without returning
  2. Large data → Avoid copying for performance
  3. Build connected systems → Changes reflect everywhere

🎯 Real Example: Swap Two Values

function swap(&$a, &$b)
{
    $temp = $a;
    $a = $b;
    $b = $temp;
}

$x = "apple";
$y = "banana";
swap($x, $y);

echo $x;  // "banana"
echo $y;  // "apple"

📊 Value vs Reference Comparison

Feature Pass by Value Pass by Reference
Symbol None &
Original changes? No ❌ Yes ✅
Memory Copy created Same memory
Safe? Very safe Be careful!

🧩 Putting It All Together

Here’s a complete example using EVERYTHING we learned:

<?php
declare(strict_types=1);

function processUser(
    string $name,
    ?int $age,
    string|array $hobbies,
    &$score
): ?string
{
    // Modify score directly (reference)
    $score += 10;

    // Handle nullable age
    if ($age === null) {
        return null;
    }

    // Handle union type
    $hobbyCount = is_array($hobbies)
        ? count($hobbies)
        : 1;

    return "$name ($age) has $hobbyCount hobbies";
}

$points = 50;
$result = processUser(
    "Luna",
    28,
    ["reading", "coding"],
    $points
);

echo $result;   // "Luna (28) has 2 hobbies"
echo $points;   // 60 (modified by reference!)

🎓 Summary: Your Type System Toolkit

graph LR A[Function Type System] --> B[Type Declarations] A --> C[Strict Types] A --> D[Nullable Types] A --> E[Union Types] A --> F[Pass by Value] A --> G[Pass by Reference] B --> H[Label inputs/outputs] C --> I[No auto-conversion] D --> J[Allow null with ?] E --> K[Multiple types with |] F --> L[Safe copies] G --> M[Modify originals with &]

🚀 You Did It!

You now understand how PHP functions can be picky, strict, and powerful!

Remember:

  • 📦 Type Declarations = Labels for your data
  • Strict Types = No guessing allowed
  • 🌙 Nullable = “Maybe null” with ?
  • 🌈 Union Types = “This OR that” with |
  • 📤 Pass by Value = Safe copies
  • 📎 Pass by Reference = Share the original with &

Go forth and write type-safe PHP code! 🎉

Loading story...

No Story Available

This concept doesn't have a story yet.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Interactive Content

This concept doesn't have interactive content yet.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Cheatsheet Available

This concept doesn't have a cheatsheet yet.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Quiz Available

This concept doesn't have a quiz yet.