Get "PHP 8 in a Nutshell" (Soon PHP 8.5)
Amit Merchant
Amit Merchant

A blog on PHP, JavaScript, and more

Seven Real-World Examples of Using the Pipe Operator in PHP 8.5

The pipe operator (|>) in PHP 8.5 is a powerful addition that allows for a more functional programming style by enabling the chaining of operations clearly and concisely. It takes the result of an expression on its left and passes it as the first argument to the function or method on its right.

$value = "hello world";

$result = $value
    |> function3(...)
    |> function2(...)
    |> function1(...);

I have written a dedicated article on it, but in this article, I want to share some real-world examples of how you can use the pipe operator in your PHP code to make it cleaner and more readable.

String cleanup in APIs

The ‘username’ input often needs normalization. Pipes make the steps readable.

$raw = "  John   Doe  ";

$username = $raw
    |> trim(...)
    |> strtolower(...)
    |> (fn($x) => preg_replace('/\s+/', '-', $x));

// Output: "john-doe"

As you can tell, here each stage is a focused, testable transform: trimlowercasewhitespace-to-dash.

Processing uploaded CSV rows

Clean, validate, and map rows into DTOs in one flow.

$rows = [
  ['name' => ' Widget A ', 'price' => '12.99', 'sku' => 'W-A'],
  ['name' => 'Widget B',   'price' => 'n/a',   'sku' => 'W-B'],   // invalid price
  ['name' => 'widget c',   'price' => '7.5',   'sku' => 'W-C'],
];

// normalizeRow might trim, cast price to float, unify casing:
// ['name' => 'Widget A', 'price' => 12.99, 'sku' => 'W-A']
// ['name' => 'Widget B', 'price' => null,  'sku' => 'W-B']
// ['name' => 'Widget C', 'price' => 7.5,   'sku' => 'W-C']

// isValidRow returns false if price is null or <= 0

$products = $rows
    |> (fn($xs) => array_map('normalizeRow', $xs))
    |> (fn($xs) => array_filter($xs, 'isValidRow'))
    |> (fn($xs) => array_map(Product::fromArray(...), $xs));

// Output: [Product('Widget A', 12.99, 'W-A'), Product('Widget C', 7.5, 'W-C')]

The chain expresses a pipeline: normalization, filtering, then construction.

HTTP response building

Compose middleware-like transforms to produce a final response body.

$data = ['msg' => 'hello', 'n' => 3];

$body = $data
    |> json_encode(...)
    |> (fn($x) => gzencode($x, 6))
    |> base64_encode(...);

// Output: H4sIAAAAAAAAA2WOuwrCMBBE…

Each callable is a single-arg step, resulting in a compact, linear build.

Search query preparation

Sanitize and tokenize a query before passing it to the search engine.

$query = "  Hello, WORLD!  ";

$tokens = $query
    |> trim(...)
    |> strtolower(...)
    |> (fn($x) => preg_replace('/[^\w\s]/', '', $x))
    |> (fn($x) => preg_split('/\s+/', $x))
    |> (fn($xs) => array_filter($xs, fn($t) => strlen($t) > 1));

// Output: ['hello', 'world']

The pipeline turns messy input into indexed tokens ready for search.

E-commerce cart totals

Derive totals from items with discounts and tax, staying point-free.

// Assume helpers:
// priceAfterDiscount(['price' => 100, 'discount' => 0.10]) -> 90.0
// applyTax(90.0) with 10% tax -> 99.0

$cartItems = [
  ['price' => 100, 'discount' => 0.10],
];

$total = $cartItems
    |> (fn($xs) => array_map('priceAfterDiscount', $xs))
    |> array_sum(...)
    |> (fn($sum) => applyTax($sum)); 
    // applyTax takes one argument

// Output: 99.0

Steps are clear: per-item discountsumtax; no temporary variables needed.

Logging and metrics enrichment

This pipeline enriches an event with a timestamp, request ID, and IP, then redacts sensitive fields before logging.

$incomingEvent = [
    'user' => 'alice', 
    'email' => '[email protected]'
];

$event = $incomingEvent
    |> (fn($x) => array_merge($x, ['received_at' => 1696195560])) // e.g. time()
    |> (fn($x) => array_merge($x, ['request_id' => '9f2a1c0b7e3d4a56'])) // example random id
    |> (fn($x) => array_merge($x, ['ip' => '203.0.113.42'])) // example IP
    |> (fn($x) => redactSensitive($x)); // e.g. masks email

// Output:
/*
    [
        'user' => 'alice', 
        'email' => 'a***@example.com', 
        'received_at' => 1696195560, 
        'request_id' => '9f2a1c0b7e3d4a56', 
        'ip' => '203.0.113.42'
    ]
*/

Image processing chain (e.g., thumbnails)

In some image processing tasks, you might want to load an image, resize it, apply a watermark, and then optimize it for web delivery. The pipe operator can help express this sequence of operations clearly.

$imagePath = '/images/source/beach.jpg';

$thumb = $imagePath
    // GD image resource from beach.jpg
    |> (fn($p) => imagecreatefromjpeg($p))
    // resized to 320×240   
    |> (fn($im) => resizeImage($im, 320, 240))
    // watermark added (e.g., bottom-right)
    |> (fn($im) => applyWatermark($im))
    // returns binary JPEG data or saved file path       
    |> (fn($im) => optimizeJpeg($im, 75));      

// Output: '/images/thumbs/beach_320x240_q75.jpg'

Each step is a single-argument transform returning the next value, producing an optimized thumbnail.

Learn the fundamentals of PHP 8 (including 8.1, 8.2, 8.3, and 8.4), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-digest guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

👋 Hi there! This is Amit, again. I write articles about all things web development. If you enjoy my work (the articles, the open-source projects, my general demeanour... anything really), consider leaving a tip & supporting the site. Your support is incredibly appreciated!

Comments?