Software Design Enthusiast And Engineer
A tip of the hat to 2 great articles written by Nikita Popov

Understanding PHP 7's Performance Boost: A Peek Under the Hood

5 min read
Status: Completed Read year: 2025

It's been years since this topic was relevant at this point, but I think it's worth revisiting at a steady cadence. And for future-me, the cliff notes.

PHP 7 was a turning point for the language. It didn’t just tweak a few things—it overhauled how PHP runs under the surface, delivering a performance boost that made developers sit up and take notice. A lot of that magic comes down to changes in how PHP handles its internal workings, and two articles by Nikita Popov lay it all out beautifully (I'll provide the links at the end). Nikita, a giant in the PHP community, was one of the brains behind these improvements before he moved on to work on LLVM. His writing is sharp, insightful, and—honestly—a gift to anyone who cares about how PHP ticks. I’ve been wanting to summarize his work for my blog, not just to share it with you but also to create a go-to reference for myself whenever I need a refresher. So, let’s dive into the key ideas from his articles about PHP 7’s internal value representation—using some everyday analogies to keep it clear and approachable, whether you’re new to PHP or a seasoned pro.

Zvals: The Envelopes of PHP

At the heart of PHP’s variables is something called a zval. Think of a zval as an envelope that holds everything PHP needs to know about a variable’s value. Back in PHP 5, every envelope had a little slip of paper inside with an address—an address that told PHP where to find the actual value, like a number, string, or array. It worked, but it was a bit like sending you on a scavenger hunt every time you wanted to read a variable. You’d open the envelope, read the address, then traipse off to fetch the data. That extra step—called indirection in C-land—added overhead, especially when you’re looping through thousands of variables or crunching big datasets.

PHP 7 said, “Let’s simplify this.” For small, straightforward values like integers or floats, the value itself gets scribbled right on the envelope. No more address slips, no more detours—just open the envelope and there’s your number, ready to go. It’s a small change that makes a big difference, cutting out unnecessary trips and speeding things up. For bigger stuff like strings or arrays, the envelope still has an address pointing to the value, but even those pointers got a tune-up to run smoother. It’s clever, practical stuff—exactly the kind of thinking Nikita brought to the table.

Reference Counting: Who’s Borrowing What?

Next up is reference counting, PHP’s way of keeping track of when a value can be tossed out of memory. Imagine a library book: as long as someone’s borrowing it, it stays on the shelf. When the last borrower returns it, the book can be archived—or in PHP’s case, deleted from memory. In PHP 5, every zval tracked its own borrowing status. If two variables pointed to the same string, each zval had its own little tally of who was using it. It was like every envelope had its own checkout card, even if they were all pointing to the same book. That setup worked, but it could get clunky and redundant.

PHP 7 flipped the script. For shareable things like strings or arrays, the reference count moved to the value itself. Now, multiple zvals can point to the same string, and that string keeps a single tally of how many envelopes are linked to it. When an envelope gets tossed or points somewhere else, the tally drops. If it hits zero—poof, the string’s gone. For integers, since they’re written directly on the envelope, there’s no sharing or counting needed; when the envelope’s trashed, the number’s trashed with it. It’s a slicker system, reducing waste and making memory management feel a little less like herding cats.

Arrays: Filing Cabinets Done Right

Arrays in PHP are a big deal—they’re these flexible, ordered maps built on hash tables in C. In PHP 5, every element in an array was its own zval, complete with its own envelope-and-address setup. Picture a filing cabinet where every drawer has a note saying, “Go look in this other cabinet for the file.” It got the job done, but all those extra steps and reference counts piled up, especially with big arrays.

PHP 7 tightened things up. The zvals inside arrays are leaner, and the reference counting got smarter by piggybacking on that shared-value trick I just mentioned. Plus, there’s a cool feature for arrays that don’t change: if you’ve got an array that’s just sitting there, multiple variables can share it without making copies. It’s called copy-on-write—the array only gets duplicated if someone tries to tweak it. Think of it like handing out photocopies of a master document only when someone wants to scribble on it. For big arrays in web apps, that’s a game-changer for both speed and memory.

Memory Management: The Quiet MVP

Oh, and one more thing—PHP 7 didn’t stop at zvals and arrays. It also rolled out a shiny new memory management system. With a custom allocator under the hood, it’s better at keeping memory neat and tidy, avoiding the mess of fragmentation (think of it like keeping your desk organized instead of letting papers scatter everywhere). It also plays nicer with your computer’s cache, making data access faster. It’s not the flashiest change, but it’s a quiet hero that ties everything together.

Why It All Matters

So, what’s the takeaway? PHP 7’s performance leap came from rethinking zvals to cut out unnecessary steps, streamlining reference counting to save resources, optimizing arrays with clever sharing, and topping it off with sharper memory management. These aren’t just tweaks—they’re a reimagining of how PHP works, spearheaded by folks like Nikita Popov, whose knack for explaining this stuff is as impressive as his coding. I love how his articles break it down, and I’m glad I could distill them into something I can revisit whenever I need a refresher.

Whether you’re just starting with PHP or you’ve been at it for years, I hope this gives you a feel for what’s happening behind the scenes. It’s a reminder of how much thought goes into the tools we use—and how a few smart changes can make a world of difference. Next time you’re speeding through a PHP 7+ script, tip your hat to the internals that got us here.

Check out Nikita's articles here:

Internal value representation in PHP 7 - Part 1
Internal value representation in PHP 7 - Part 2