🐘

A language tour

The Resilience of PHP

Written off a hundred times. Still running 77% of the web. PHP grew up in public — and the modern version is worth a second look.

scroll

01 — Where It All Started

HTML with a pulse

PHP's original insight was radical in its simplicity: put the logic inside the page. No framework, no build step — just a file the server executes. That frictionless beginning is why PHP spread everywhere.

"PHP is a minor web programming language whose name is a recursive acronym for PHP: Hypertext Preprocessor. The joke is that it preprocesses itself."

— The internet, fondly
template.php
<?php
$user = [
    'name'   => 'Ada Lovelace',
    'joined' => 2019,
    'posts'  => 142,
];

$greeting = date('H') < 12 ? 'Good morning' : 'Hello';
?>
<h1><?= htmlspecialchars($greeting . ', ' . $user['name']) ?></h1>
<p>Member since <?= $user['joined'] ?> &mdash; <?= $user['posts'] ?> posts</p>

<?php foreach ($user['posts'] as $post): ?>
    <article><?= htmlspecialchars($post['title']) ?></article>
<?php endforeach; ?>

<?= is shorthand for <?php echo — a small kindness that kept countless templates readable.


02 — PHP 8

A language that grew up

PHP 8 arrived with match expressions, named arguments, the nullsafe operator, and union types. The awkward teenager became a capable adult — concise where it used to be verbose, safe where it used to be fragile.

modern.php
<?php

// match — like switch but strict, exhaustive, and an expression
$status = 404;

$message = match($status) {
    200       => 'OK',
    301, 302  => 'Redirect',
    404       => 'Not Found',
    500       => 'Server Error',
    default   => 'Unknown',
};

// Named arguments — order doesn't matter, intent is clear
array_slice(
    array:        $items,
    offset:       2,
    length:       5,
    preserve_keys: true,
);

// Nullsafe operator — chain through null without crashing
$city = $user?->getAddress()?->getCity()?->getName();

// First-class callables (PHP 8.1)
$fn  = strlen(...);
$lengths = array_map($fn, ['hello', 'world']);
// → [5, 5]

The nullsafe ?-> operator short-circuits the whole chain the moment it hits null — no nested isset() required.


03 — Types & Enums

Structure you can trust

PHP 8 brought a real type system: union types, intersection types, readonly properties, and proper enums. Code that once relied entirely on convention now has the compiler on its side.

types.php
<?php

// Backed enum — each case carries a value
enum Suit: string
{
    case Hearts   = 'H';
    case Diamonds = 'D';
    case Clubs    = 'C';
    case Spades   = 'S';

    public function label(): string {
        return match($this) {
            Suit::Hearts   => '♥ Hearts',
            Suit::Diamonds => '♦ Diamonds',
            Suit::Clubs    => '♣ Clubs',
            Suit::Spades   => '♠ Spades',
        };
    }
}

// Readonly properties — set once, immutable forever
class Card
{
    public function __construct(
        public readonly Suit   $suit,
        public readonly int    $value,
        public readonly string $label,
    ) {}
}

$card = new Card(Suit::Hearts, 14, 'Ace');
echo $card->suit->label();  // → ♥ Hearts

Constructor promotion — public readonly string $label in the parameter list — declares, assigns, and locks the property in one stroke.


04 — Closures & Collections

Pipelines built from small pieces

PHP closures and arrow functions bring functional patterns to the language. Combined with array_map, array_filter, and array_reduce, you can build expressive data pipelines without a library.

collections.php
<?php

$orders = [
    ['id' => 1, 'total' => 120.00, 'paid' => true],
    ['id' => 2, 'total' =>  45.00, 'paid' => false],
    ['id' => 3, 'total' => 230.00, 'paid' => true],
];

// Arrow functions capture outer scope implicitly
$minPaid = 100.0;

$revenue = array_sum(
    array_column(
        array_filter(
            $orders,
            fn($o) => $o['paid'] && $o['total'] >= $minPaid
        ),
        'total'
    )
);  // → 350.00

// array_reduce — fold a collection into a single value
$summary = array_reduce($orders,
    fn($carry, $o) => $carry + ($o['paid'] ? $o['total'] : 0),
    0.0
);  // → 350.00

// Spread operator — unpack any array as arguments
function total(float ...$amounts): float
{
    return array_sum($amounts);
}

$prices = [9.99, 24.99, 4.50];
echo total(...$prices);  // → 39.48

Arrow functions with fn() => capture surrounding variables automatically — no use (&$var) boilerplate needed.


05 — Fibers

Cooperative concurrency without callbacks

PHP 8.1 introduced Fibers — suspendable execution contexts that let you write async-style code that reads synchronously. Frameworks like Laravel and ReactPHP use them under the hood to handle thousands of connections without multi-threading complexity.

fibers.php
<?php

// A Fiber is a function that can pause itself mid-execution
$fiber = new Fiber(function (): void {
    $value = Fiber::suspend('first yield');
    echo "Fiber received: " . $value . "\n";

    Fiber::suspend('second yield');
    echo "Fiber finishing.\n";
});

// Start the fiber — runs until first suspend()
$val1 = $fiber->start();
echo $val1 . "\n";  // → first yield

// Resume with a value — the fiber sees it as the return of suspend()
$val2 = $fiber->resume('hello back');
// → Fiber received: hello back
echo $val2 . "\n";  // → second yield

$fiber->resume();
// → Fiber finishing.

A Fiber yields control back to its caller mid-execution and resumes exactly where it left off — the foundation for non-blocking I/O without threads.


06 — The Whole Picture

More reasons PHP still matters

🌐

Runs the Web

WordPress, Wikipedia, Facebook (still), Slack's backend. More production traffic flows through PHP than almost any other language.

Laravel

Eloquent ORM, Blade templates, Artisan CLI, queues, broadcasting — Laravel turned PHP into one of the most productive web frameworks anywhere.

🔒

Strict Mode

declare(strict_types=1) turns PHP's type coercion off entirely. Opt in to strictness wherever you want it.

📦

Composer

Packagist hosts over 400,000 packages. composer require is fast, reproducible, and the model other ecosystems copied.

🚀

JIT in PHP 8

A Just-In-Time compiler landed in PHP 8, bringing significant performance gains for CPU-bound workloads — a long time coming.

🏋️

Battle-Hardened

30 years of production use means the edge cases are known, the security model is documented, and the community has seen everything.