Skip to content
Cognate Press
Alden Pike, PHP engineer and the byline behind ElephantPHP
First issue 13 issues publishedOne byline, nothing syndicatedWrites only the language they work in

Their publication

ElephantPHP

PHP · elephantphp.com

PHP internals, performance, architecture and production behavior — measurements over assumptions, trade-offs over rules.

Read the archive ↗

All authors →

Author

Alden Pike

Writes ElephantPHP — understanding PHP below the abstraction.

Alden Pike writes about PHP, backend engineering, and the systems behind modern PHP applications. His work focuses on understanding what happens beneath frameworks and abstractions, from language internals and performance to architecture and production behavior. He prefers measurements over assumptions and trade-offs over universal rules.

ElephantPHP exists because most PHP writing stops at the API surface — which function to call and what it returns — and stops exactly where the interesting part starts. Each issue takes the layer underneath: the Zend VM and memory layout, profiling and benchmark method, dependency injection and layering, FPM pools and long-running runtimes, and the tooling and PSRs around the language.

One rule orders every post: explain the mechanism, then give the advice. Every performance claim carries a number and the method that produced it, or says plainly that the thing was not measured. Nothing published there is paid for — no sponsored posts, no affiliate links, no vendor writing about its own product under a byline.

Alden Pike is a publishing byline. It identifies the author of every article at elephantphp.com, and nothing else — it is not the operator of the domain named in that site's legal pages.

Every issue so far

  1. The same .= statement took 0.269 ms and 218.836 ms in two loops that differ by one assignment. What a zend_string costs, where literals live, and why implode is not the fix.

  2. Plain, backed and virtual property reads compile to one identical FETCH_OBJ_R. What separates them is a function call the opcode does not show, measured at nine times.

  3. One hundred thousand four-field records cost 143.54 bytes each as objects and 397.14 as associative arrays. Where the crossover is, and what one undeclared property costs.

  4. Two hundred thousand objects created and dropped, and zero collections. What puts an object in the root buffer, and why the collector's cost is set by what you keep alive.

  5. memory_get_usage(), memory_get_usage(true) and ps disagree about one process. What each counts, which one memory_limit reads, and why a one-megabyte string costs two.

  6. Walking an array with foreach ($rows as &$row) wraps every element in a zend_reference. On a million integers that is 32 MB the loop never gives back.

  7. A zval is sixteen bytes, a value union and a type tag. What that tag says decides whether an assignment copies anything, what a reference costs, and which variable pays.

  8. pm static, dynamic and ondemand, the memory ceiling nothing enforces, and how to size a pool from measurements rather than guesses.

  9. Container compilation moves reflection from request time to build time. What that removes, what it costs, and when it matters.

  10. One structure serves as list, dictionary and set. Packed and hashed layouts, what each costs in memory, and when a conversion happens.

  11. OPcache removes compilation, not execution. The JIT reaches arithmetic-heavy code and little else. Where the remaining time lives.

  12. Microbenchmarks measure exactly what you tell them to, which is rarely what you meant. Method, noise, and the numbers worth reporting.

  13. A request walks from the SAPI to the Zend VM — lexing, compilation to opcodes, the OPcache lookup that skips both, and execution.

Elsewhere in the network

JS Ledger · JVM Scope · PyDepth · CSharpMind · SQLPress · Gopheria — six more languages, six more specialists, one imprint. Every language has a page of its own.