Tag: Laravel

  • PHP 8.5 Pipe Operator (|>): A Complete Guide with Laravel & Real-World Examples

    What Is the PHP 8.5 Pipe Operator?

    PHP 8.5 (released November 2025) officially introduces the pipe operator (|>), one of the most requested syntax features in PHP’s history. Authored by Larry Garfield as part of the “Pipe Operator v3” RFC, it lets you pass the result of one expression directly as input to the next function — creating a clean, left-to-right data flow instead of deeply nested function calls.

    If you’ve used pipelines in Elixir, F#, Hack, or even Unix shell commands (cat file | grep "x" | sort), this will feel instantly familiar.

    $result = strtoupper("Hello World") |> str_shuffle(...) |> trim(...);
    

    The value on the left is passed as the first argument to the callable on the right.


    The Problem It Solves

    PHP code that applies multiple transformations to a value traditionally ends up deeply nested and hard to read.

    Old Way (Nested Calls)

    $result = strtoupper(
        trim(
            htmlspecialchars($input)
        )
    );
    

    You have to read from the inside out to understand the order of operations — and it only gets worse as more steps are added.

    New Way (Pipe Operator)

    $result = $input
        |> htmlspecialchars(...)
        |> trim(...)
        |> strtoupper(...);
    

    Now the code reads top-to-bottom, in the exact order the transformations happen.


    Basic Syntax Example

    $name = " john doe ";
    
    $result = $name
        |> trim(...)
        |> ucwords(...);
    
    echo $result; // John Doe
    

    Note the ... — this is PHP’s first-class callable syntax, required so the pipe knows which function to call.


    Real-World Example 1: Sanitizing Email Input

    Old Way

    $email = strtolower(
        trim(
            filter_var($email, FILTER_SANITIZE_EMAIL)
        )
    );
    

    New Way

    $email = $email
        |> fn($e) => filter_var($e, FILTER_SANITIZE_EMAIL)
        |> trim(...)
        |> strtolower(...);
    

    Real-World Example 2: Array Transformations

    Old Way

    $numbers = [1, 2, 3, 4, 5];
    
    $result = array_sum(
        array_map(
            fn($n) => $n * 2,
            $numbers
        )
    );
    

    New Way

    $result = $numbers
        |> fn($arr) => array_map(fn($n) => $n * 2, $arr)
        |> array_sum(...);
    

    Real-World Example 3: JSON API Processing

    Old Way

    $data = json_decode($json, true);
    $data = array_filter($data);
    $data = array_values($data);
    

    New Way

    $data = $json
        |> fn($j) => json_decode($j, true)
        |> array_filter(...)
        |> array_values(...);
    

    Laravel Examples: Old Way vs New Way

    Laravel developers already enjoy fluent, chainable Collection and Eloquent APIs. The pipe operator shines specifically when mixing Collections with plain PHP functions, or when processing request data.

    Example 1: Collection Output → PHP Function

    Old Laravel Way

    $json = json_encode(
        User::all()
            ->where('active', true)
            ->pluck('email')
            ->toArray()
    );
    

    New Way with Pipe Operator

    $json = User::all()
        ->where('active', true)
        ->pluck('email')
        ->toArray()
        |> json_encode(...);
    

    Example 2: Cleaning Request Input

    Old Laravel Way

    $email = strtolower(
        trim(
            $request->input('email')
        )
    );
    

    New Way

    $email = $request->input('email')
        |> trim(...)
        |> strtolower(...);
    

    Example 3: Formatting an API Response

    Old Laravel Way

    return response()->json(
        array_values(
            array_filter($users)
        )
    );
    

    New Way

    return $users
        |> array_filter(...)
        |> array_values(...)
        |> fn($u) => response()->json($u);
    

    Example 4: File Content Processing in a Service Class

    Old Way

    $content = file_get_contents($path);
    $content = trim($content);
    $content = strip_tags($content);
    $content = strtolower($content);
    

    New Way

    $content = file_get_contents($path)
        |> trim(...)
        |> strip_tags(...)
        |> strtolower(...);
    

    Real-World Example: Order Analytics

    A common reporting task — sum up the amount of all “paid” orders.

    Old Way

    $total = array_sum(
        array_map(
            fn($order) => $order['amount'],
            array_filter(
                $orders,
                fn($order) => $order['status'] === 'paid'
            )
        )
    );
    

    New Way

    $total = $orders
        |> fn($o) => array_filter($o, fn($order) => $order['status'] === 'paid')
        |> fn($o) => array_map(fn($order) => $order['amount'], $o)
        |> array_sum(...);
    

    Each transformation step is now isolated and easy to scan.


    Key Benefits of the Pipe Operator

    1. Better readability — Code reads top-to-bottom in the same order it executes, instead of inside-out.

    2. Fewer temporary variables — No need for $data = step1($data); $data = step2($data); chains.

    3. Reduced nestingfn3(fn2(fn1($value))) becomes a flat, linear pipeline.

    4. Encourages functional, reusable transformation functions — small single-purpose functions compose naturally:

    function sanitize($value) {
        return trim($value);
    }
    
    function normalize($value) {
        return strtolower($value);
    }
    
    $email = $email
        |> sanitize(...)
        |> normalize(...);
    

    5. Compiler optimizations — Pipe chains compile to opcodes similar to nested calls, and in some cases the compiler can optimize away temporary variables for memory and performance gains.


    When NOT to Use the Pipe Operator

    For object method chaining, Laravel Collections and Eloquent query builders already provide elegant fluent syntax:

    User::query()
        ->where('active', true)
        ->orderBy('name')
        ->get();
    

    Adding |> here adds no value — the pipe operator is best reserved for chaining standalone functions or mixing function calls with method-chain results, not for replacing object method chains that are already fluent.


    A Note on Arrow Functions

    Because of how the implementation captures arrow function bodies, wrapping inline arrow functions in parentheses is sometimes necessary to avoid ambiguity:

    $result = $value |> (fn($x) => $x * 2)(...) |> strval(...);
    

    Keep this in mind when piping into anonymous functions directly.


    Final Thoughts

    The PHP 8.5 pipe operator (|>) brings a long-requested functional programming feature to the language, reducing nested function calls and creating natural, linear data pipelines. For Laravel developers, it’s especially useful for request sanitization, API response formatting, and bridging Collection output with native PHP functions.

    It won’t replace Eloquent or Collection chaining — but for transformation-heavy code, it’s likely to become one of the most-used additions since arrow functions and the nullsafe operator.