GrUSP
AI-assisted summary of Rasmus Lerdorf - 25 Years of PHP - phpday 2019 — original source. Check the original for full context.
Source published:
Key ideas
- PHP originated in 1994 not as an independent programming language, but as a minimal C API and templating layer to simplify web development by abstracting HTTP headers, cookies, and GET/POST inputs away from backend logic. (2:37)
- Mod_php outperformed mod_perl in early web hosting economics because its strict shared-nothing execution sandbox allowed ISPs to safely pack 3,000 tenants onto a single bare-metal server, whereas mod_perl required expensive dedicated hardware. (9:32)
- Rasmus Lerdorf invented the relational SQL 'LIMIT' clause in 1994–1995 while working on David Hughes's mSQL, introducing query boundaries to prevent runaway SELECT queries over slow networks. (14:15)
- Modern optimizations in OPcache such as Dead Code Elimination, Sparse Conditional Constant Propagation, and PHP 7.4 features like OPcache preloading and FFI drastically boost performance and enable Composer-distributed C wrappers. (34:24)
- Lerdorf emphasizes that software engineering debates over tool selection are trivial compared to real-world outcomes, highlighting applications like Sahana that delivered life-saving disaster relief across more than 50 disaster zones. (64:51)
Detailed notes
## Background Published by GrUSP on YouTube on July 11, 2019, this presentation captures Rasmus Lerdorf's keynote at the phpday 2019 conference. The talk reflects on 25 years of PHP's history while urging developers to upgrade to modern versions through demonstrations of recent performance optimizations, OPcache advancements, profiling techniques, and upcoming engine features.
## TL;DR Rasmus Lerdorf recounts the origins of PHP, detailing how an early C templating engine built for Mosaic evolved into the dominant web language due to pragmatic architecture choices like Apache's mod_php multi-process model and shared-nothing execution. He provides a technical deep dive into modern performance gains across PHP 7.3 and 7.4, highlighting Dead Code Elimination in OPcache, static analysis with Phan, zero-overhead sampling profiling with phpspy, preloading, and Foreign Function Interface (FFI) bindings. Urging the audience to abandon end-of-life PHP 5 and early 7.x branches, Lerdorf concludes with a philosophical defense of software pragmatism, arguing that engineers must focus on building real-world solutions rather than debating developer tooling.
## Atmosphere & style The presentation is dryly humorous, deeply pragmatic, and refreshingly unpretentious. Rasmus delivers his technical breakdown with the quiet confidence of a veteran engineer who views code not as sacred art, but as an uncomfortable utility tool to get work done. His self-deprecating anecdotes about early design accidents and conference mishaps balance the dense compiler walkthroughs, eventually giving way to a grounded, reflective call for developers to maintain perspective and avoid burnout.
## Bulletin - [02:37](https://www.youtube.com/watch?v=iGOAQli7tGc&t=157s) PHP originated in 1994 not as an independent programming language, but as a minimal C API and templating layer to simplify web development by abstracting HTTP headers, cookies, and GET/POST inputs away from backend logic. - [09:32](https://www.youtube.com/watch?v=iGOAQli7tGc&t=572s) Mod_php outperformed mod_perl in early web hosting economics because its strict shared-nothing execution sandbox allowed ISPs to safely pack 3,000 tenants onto a single bare-metal server, whereas mod_perl required expensive dedicated hardware. - [14:15](https://www.youtube.com/watch?v=iGOAQli7tGc&t=855s) Rasmus Lerdorf invented the relational SQL 'LIMIT' clause in 1994–1995 while working on David Hughes's mSQL, introducing query boundaries to prevent runaway SELECT queries over slow networks. - [34:24](https://www.youtube.com/watch?v=iGOAQli7tGc&t=2064s) Modern optimizations in OPcache such as Dead Code Elimination, Sparse Conditional Constant Propagation, and PHP 7.4 features like OPcache preloading and FFI drastically boost performance and enable Composer-distributed C wrappers. - [01:04:51](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3891s) Lerdorf emphasizes that software engineering debates over tool selection are trivial compared to real-world outcomes, highlighting applications like Sahana that delivered life-saving disaster relief across more than 50 disaster zones.
## Key takeaways - [02:37](https://www.youtube.com/watch?v=iGOAQli7tGc&t=157s) PHP was created as a templating engine and C API abstraction layer, evolving into a language only after early users refused to write native C snippets and demanded inline logic. - [09:32](https://www.youtube.com/watch?v=iGOAQli7tGc&t=572s) The shared-nothing architecture and request-level isolation allowed mod_php to dominate early shared hosting environments while preventing single crashes from taking down concurrent traffic. - [14:15](https://www.youtube.com/watch?v=iGOAQli7tGc&t=855s) The SQL LIMIT clause was invented by Rasmus Lerdorf as an ad-hoc patch for mSQL and subsequently adopted across engines like MySQL and PostgreSQL despite not being part of ANSI SQL. - [18:54](https://www.youtube.com/watch?v=iGOAQli7tGc&t=1134s) Controversial PHP quirks like variable dollar signs, case-insensitive functions, register_globals, and magic quotes originated from specific historical constraints, backwards compatibility concerns, and avoiding cross-file global scope collisions. - [24:57](https://www.youtube.com/watch?v=iGOAQli7tGc&t=1497s) Inconsistencies across PHP function signatures and argument orders (needle vs. haystack) reflect the vertical wrappers over distinct underlying C libraries like LibC, MySQL, and Oracle OCI8. - [29:47](https://www.youtube.com/watch?v=iGOAQli7tGc&t=1787s) Migrating to PHP 7.3 brings strict regex compilation checks under PCRE2, breaking unescaped range patterns like '[a-\s]' that PCRE1 previously permitted. - [37:25](https://www.youtube.com/watch?v=iGOAQli7tGc&t=2245s) Dead Code Elimination (DCE) and Escape Analysis in OPcache remove intermediate opcodes for side-effect-free objects and arrays, meaning performance gains exceeding 10% often indicate the optimizer deleting redundant user code. - [44:48](https://www.youtube.com/watch?v=iGOAQli7tGc&t=2688s) Etsy's zero-overhead sampling profiler, phpspy, inspects Zend executor memory tables at 99 ms intervals directly from running PHP processes without extensions, engine hooks, or harmonic timing locksteps. - [50:24](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3024s) PHP 7.4 introduces typed class properties with implicit runtime type checks, but omits typed local variables to preserve execution speed in tight loops. - [53:46](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3226s) OPcache preloading eliminates per-request autoloading and class resolution at startup, though it disables disk-stat hot-reloading and requires full service restarts for code deployments. - [01:00:09](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3609s) Combining FFI with OPcache preloading allows low-overhead C shared-library integration, opening the door to distributing native extensions via Composer rather than compilation through PECL. - [01:08:15](https://www.youtube.com/watch?v=iGOAQli7tGc&t=4095s) Programming tools should be treated as disposable means to an end, with developer motivation sustained by focusing on real-world impact rather than bike-shedding over language purity.
## Detailed walkthrough ### [00:20](https://www.youtube.com/watch?v=iGOAQli7tGc&t=20s) Roots in Greenland, 1K Computers, and the Gopher Era
Rasmus Lerdorf opens his retrospective by sharing photographs from his childhood, tracing his origins back to northern Greenland—specifically a town called Qeqertarsuaq situated on Disko Island in the middle of Disko Bay. Looking at the audience while reflecting on the previous day’s opening keynote, Rasmus jokes about his seniority in the industry: “Born in the 60s, I'm old; as the keynote yesterday was saying, we're all getting older—I'm sort of leading the pack here, I think, almost.” He shows snapshots of his parents riding on a dogsled, the landscape of their family home across summer seasons, and his earliest days of hacking away in one of the most remote and extreme environments on Earth before his 25-year PHP journey ever began.
His earliest encounters with computing in the 1980s were thoroughly Spartan. He began tinkering on machines that barely resembled modern hardware, working on a home computer equipped with only 1,024 bytes (1 KB) of native onboard RAM, accompanied by a bulky 16 KB memory expansion module protruding from the back. Compared to the lavish computing power available to his son today, the technological landscape was primitive. Modems were either nonexistent or agonizingly slow, and there was no internet to speak of. During his university years in the late 1980s and early 1990s, the closest system resembling the modern web was Gopher, where reading academic research papers meant using keyboard cursor keys to scroll to the very bottom of a document to find text-based links to adjacent papers.
- **Birthplace:** Qeqertarsuaq, Disko Island, Disko Bay, Greenland. - **Early Hardware:** 1 KB native memory with an external 16 KB expansion pack. - **Pre-Web Navigation:** Text-only Gopher protocol using terminal arrow keys to jump between academic research papers.
---
[02:37](https://www.youtube.com/watch?v=iGOAQli7tGc&t=157s) The Arrival of Mosaic and PHP’s Origins as a C Templating Engine
Everything shifted radically in October 1994, shortly after Rasmus graduated from university, when the Mosaic browser was released. As the first widely adopted graphical web browser, Mosaic marked the official start of Rasmus's 25-year timeline. Anyone who had spent time dealing with UUCP addresses, Usenet groups, and local bulletin board systems immediately recognized that Mosaic was poised to alter the trajectory of global communication. Rasmus began hacking on web software immediately, but the prevailing development practices were deeply frustrating. Dynamic server-side scripting was dominated by CGI binaries compiled directly in C or Perl scripts utilizing `CGI.pm`. Rasmus found both approaches awful to maintain because both fundamentally required embedding raw HTML code inside foreign programming languages.
Rasmus set out with the opposite philosophy: keeping business logic strictly separated from templating and page presentation. Although modern developers who do not use PHP often chuckle because PHP gained a reputation for intertwining logic and markup, Rasmus’s original intent was to create an ultra-clean, minimal templating layer. His vision was a web page that looked like pure HTML, punctuated only by occasional specialized tags to ingest dynamic parameters from form submissions. Under the hood, dynamic functions were backed by native C implementations linked to a stack-based engine.
“My grand scheme was to write a C API for the web, so abstract away all the web-specific things that you needed to know to get your business logic up online.”
In this early architecture, if an author wanted to compute a mathematical operation like a cosine (`cos`), they would add a custom tag to the page. The underlying engine processed the markup, pushed input arguments onto an internal stack, invoked the corresponding C function, and pushed the calculated result back onto the stack to be rendered into the HTML document. This model abstracted away the nightmare of parsing HTTP headers, cookies, `GET` parameters, and `POST` variables, leaving developers free to write only their critical logic in high-performance C.
```mermaid flowchart LR accTitle: Early PHP C API Stack Architecture accDescr: Diagram illustrating how Rasmus Lerdorfs early C API parsed HTML tags and dispatched arguments through a stack.
subgraph HTML["Template Layer"] A["HTML Markup with Tag <br/><code><!--tag cos input--></code>"] end
subgraph Engine["PHP Core Engine"] B["Parse Tag & Push Arguments"] C["Internal Argument Stack"] D["Pop Output & Inject HTML"] end
subgraph Native["C Implementation"] E["Native C Function <br/><code>cos()</code>"] end
A --> B B --> C C --> E E --> C C --> D D --> A ```
---
[06:06](https://www.youtube.com/watch?v=iGOAQli7tGc&t=366s) Accidental Language Design: From Left-to-Right Parsers to Yacc and Lex
Rasmus's grand scheme crashed into an unexpected human reality: web creators had no desire to write C code. When users began emailing him about PHP, they praised the bundled demo tools and tags, but immediately asked how to perform operations that lacked existing tags. Rasmus would patiently supply them with concise C snippets, only for users to thank him and immediately ask for another one, effectively tricking him into writing their websites for them. As demands grew, users clamored for programming constructs inside the template layer itself, including recursion and mathematical expressions—features Rasmus had never intended for a presentation template.
“I was completely wrong: nobody wanted to write C code, and it was a bit distressing to me at the time, actually.”
Because Rasmus was not a language designer, his initial parser was an ad-hoc state machine that simply evaluated expressions strictly left-to-right. This naive approach collapsed on elementary arithmetic: evaluating an expression like `1 + 2 * 3` from left to right yields 9 instead of the mathematically correct 7, because it fails to enforce operator precedence. Realizing that building an entire programming language parser inside a hand-rolled state machine was unmanageable, Rasmus picked up a book on Yacc and Lex. By relying on Yacc and Lex, he offloaded arithmetic parsing and grammar definition, resulting in a parser that worked reliably enough to satisfy users.
From that moment forward, Rasmus deprioritized aesthetic language design in favor of ecosystem utility and practical integration. A programming language could have pristine syntax, but it was useless if it could not talk to backend infrastructure. He poured his energy into perfecting the four core pillars of what would become the LAMP stack: an operating system, a web server, a scripting engine, and a shared datastore.
“You don't necessarily need a beautiful language to program in; you can have the best language in the world, and if it doesn't talk to your Oracle database where all your data is, there's absolutely no point, right?”
- **The Naive Parser Flaw:** Evaluating `1 + 2 * 3` strictly left-to-right produced 9 instead of respecting standard multiplication precedence. - **Grammar Solution:** Replaced custom state machine with Yacc and Lex for tokenizing and AST generation. - **Ecosystem Focus:** Prioritized database connectivity (such as native Oracle drivers) and server integration over syntactic purity.
---
[09:32](https://www.youtube.com/watch?v=iGOAQli7tGc&t=572s) Apache Integration: Why Mod_PHP Conquered Hosting While Mod_Perl Failed
The breakthrough that propelled PHP past its competitors was `mod_php`, which embedded the PHP interpreter directly into the Apache web server process. At the time, rival scripting languages like Perl were technically faster and more mature, but they were hamstrung by the overhead of running as standalone CGI processes. Under CGI, the operating system had to perform expensive `fork()` and `exec()` calls on every single incoming HTTP request, forcing Apache to wait for the Perl binary to spin up and compile code. By the time Perl even initialized, embedded PHP had already executed and returned the response.
When the Perl community recognized the speed advantage of running inside the web server, they developed `mod_perl`. However, Rasmus points out that they severely over-engineered it by exposing virtually every internal Apache request hook. While PHP deliberately hooked only into Apache's content-generation phase—invoking the interpreter only after the web server had resolved the document root and matched the target script—`mod_perl` allowed scripts to hook into early lifecycle hooks such as the path translation hook. This created an insurmountable security vulnerability on shared servers: a malicious user on one virtual host could hook path translation and divert incoming traffic intended for any other virtual host directly into their own document root.
```mermaid flowchart TD accTitle: Apache Request Hooks Comparison accDescr: Flowchart contrasting Apache lifecycle hook exposure between mod_php and mod_perl.
subgraph Apache["Apache Request Pipeline"] R["Incoming HTTP Request"] PT["Path Translation Hook <br/>(Maps URL to Document Root)"] Auth["Authentication / Header Hooks"] CG["Content Generation Hook <br/>(Executes Script Handler)"] end
subgraph ModPerl["mod_perl (Exposes All Hooks)"] MP_PT["Can hijack other vhosts by overriding document roots"] MP_CG["Executes application logic"] end
subgraph ModPHP["mod_php (Safe Content-Only Hook)"] PHP_CG["Safely generates response payload for matched script"] end
R --> PT PT --> Auth Auth --> CG
PT -.->|"Interception risk"| MP_PT CG --> MP_CG CG --> PHP_CG ```
This structural difference transformed the commercial hosting market. Because `mod_perl` could not safely run multiple mutually untrusted virtual hosts within a single Apache daemon, and because hardware virtualization, virtual machines, and containers did not exist at the time, internet service providers (ISPs) had to provision separate physical bare-metal servers for each `mod_perl` customer at costs around $600 per month. In contrast, an ISP running `mod_php` could safely pack 3,000 customers onto a single machine. The dramatic cost difference led ISPs to drop `mod_perl` hosting, securing PHP's absolute market dominance.
Alongside `mod_php`, Rasmus instituted the architectural philosophy that defined PHP's runtime: the shared-nothing sandbox. In this execution model, memory, variables, and state are initialized cleanly at the beginning of an HTTP request and completely torn down at its termination, preventing server-side state leakage between requests. Any persistence must be explicitly managed by developers via external datastores. In that same vein, Rasmus rejected web-level multithreading entirely, asserting that concurrent shared-memory programming introduces unmanageable complexity: “I've always been firmly against any sort of multi-threading because it just gets too complicated: we as humans are not smart enough to write...”
- **CGI Overhead:** Traditional Perl required `fork()` and `exec()` per request, whereas `mod_php` executed in-process inside the Apache worker. - **The Mod_Perl Architectural Flaw:** Exposing the path translation hook permitted cross-vhost request hijacking on multi-tenant servers. - **Hosting Economics:** ISPs charged roughly $600/month for dedicated `mod_perl` bare-metal boxes, whereas 3,000 PHP tenants could be safely co-hosted on one box. - **The Core Architecture:** A strict shared-nothing lifecycle with complete memory teardown per request, coupled with a deliberate refusal to expose multi-threaded complexity to web developers.
[12:48](https://www.youtube.com/watch?v=iGOAQli7tGc&t=768s) Thread Safety, Segfaults, and the Multi-Process Model
Writing robust, multithreaded code becomes virtually impossible when linking together dozens of third-party C libraries and expecting every single one of them to maintain thread safety. While thread-safe architectures can be achieved within strictly constrained scopes, a general-purpose glue language like PHP inevitably fails under that model. Furthermore, in a multithreaded environment, memory corruption or a crash in one thread inevitably takes down all concurrent requests running in that same process space.
```mermaid flowchart TD accTitle: Apache Multi-Process vs Multi-Thread Concurrency accDescr: Diagram contrasting Apache's isolated worker processes with multithreaded shared memory failure modes.
subgraph ForkModel["Apache Prefork Architecture (PHP)"] direction TB P1["Worker Child 1 (Request A)"] -->|"Segfault occurs"| Crash["Worker Dies Silently"] Crash --> Respawn["Apache Master Respawns New Child"] P2["Worker Child 2 (Request B)"] -->|"Unaffected"| Success["Completes Cleanly"] end
subgraph ThreadModel["Multithreaded Architecture (e.g. HHVM)"] direction TB T1["Thread 1 (Request A)"] -->|"Memory Corruption"| Panic["Process Crash"] T2["Thread 2 (Request B)"] -.->|"Fate Shared"| Panic Panic --> TotalOutage["All Concurrent Requests Dropped"] end ```
Rasmus notes that even 25 years later at Etsy, where PHP handles massive scale, the system encounters one or two segmentation faults per week. When handling roughly one segfault every three billion requests, nobody needs to panic: Apache simply reaps the dead worker child and spawns a fresh one without disrupting anything else. This fault isolation makes the shared-nothing, multi-process architecture remarkably resilient compared to multithreaded engines like HHVM, where a single failure corrupts the entire worker runtime.
> “Even today 25 years later at Etsy where I work we run PHP and every now and then there's a segfault it's rare maybe one or two a week and I have no idea why they happen but I don't really care it's like once a one every three billion requests will cause a segfault and Apache just says okay we'll start another child who cares we move on that makes it robust” — Rasmus Lerdorf
[14:15](https://www.youtube.com/watch?v=iGOAQli7tGc&t=855s) Inventing the SQL LIMIT Clause and Early ISP Controls
Back in late 1994 and 1995, prior to the existence of MySQL, Rasmus relied on mSQL (Mini SQL), a tiny database engine built by David Hughes in Australia. While mSQL was an excellent datastore for early dynamic websites, its SQL dialect lacked basic features like joins and provided no mechanism to cap query result sets. On the slow networks of the era, running a `SELECT *` across a table with several hundred thousand rows forced the client to wait indefinitely for hundreds of megabytes of data to stream over the wire, even if the application only needed to display the very first record. To solve this, Rasmus arbitrarily invented the `LIMIT` clause syntax, patched it directly into mSQL, and had it merged upstream—an innovation that eventually propagated across the entire relational database ecosystem despite never being incorporated into ANSI SQL.
Alongside database efficiency, early internet service providers needed operational safeguards before they could safely host untrusted dynamic scripts. Features like `max_execution_time`, `memory_limit`, and safe mode were introduced so that shared hosting providers could run thousands of user scripts on a single server without a simple `while(true)` infinite loop pinning the CPU and bringing down the machine. Because `max_execution_time` tracked actual CPU seconds rather than wall-clock time, runaway jobs were safely killed, making PHP viable in the "Wild West" era of shared web hosting.
- David Hughes's mSQL was lightweight and ideal for dynamic sites, but lacked `JOIN` operations and result set boundary limits. - The `LIMIT` keyword was devised purely out of frustration with bandwidth bottlenecks on unconstrained `SELECT` queries and subsequently adopted by engines like MySQL and PostgreSQL. - CPU-time tracking for `max_execution_time` made it economically viable for early commercial ISPs to pack thousands of virtual hosts onto a single physical server.
[16:47](https://www.youtube.com/watch?v=iGOAQli7tGc&t=1007s) Case-Insensitive Functions and the Six-Month Lifespan Myth
Modern developers frequently question why PHP function names are case-insensitive. In the early days of the web, developers fought passionate religious battles over whether HTML tags should be written in lowercase, uppercase, or mixed case. Because PHP started as a template preprocessor meant to live harmoniously inside HTML documents, Rasmus intentionally made function tags case-insensitive so developers would not be forced into a specific casing convention that clashed with their markup preferences.
Around 1996 or 1997, when web standards coalesced around lowercase markup, Rasmus considered forcing functions to be case-sensitive. However, he backed away from the decision because he felt that breaking compatibility for a couple hundred live websites was too high a cost. Throughout this entire formative period, he operated under the persistent belief that PHP had at most six months of relevance left before a superior, properly engineered alternative emerged to replace it. Yet the competing products that appeared—such as Allaire ColdFusion—struck him as wrongheaded approaches to web architecture, leaving PHP as the only practical solution for his daily workflow.
> “Looking back now like I should have inconvenienced a couple of hundred sites at the time but I had no idea I had absolutely no idea I figured at every sort of at every point along the way I figured there was about six months of life left in PHP because that's about the amount of time I thought it would take for somebody to write something real that could replace it” — Rasmus Lerdorf
- Function case-insensitivity was implemented to align with divergent HTML authoring styles (`<TABLE>` vs `<table>`). - A breaking change was deliberately avoided in 1996/1997 to protect an installed base of only a few hundred sites. - Rasmus continually anticipated abandoning PHP for an external tool, but offerings like ColdFusion convinced him that other vendors did not understand how to solve web problems properly.
[18:54](https://www.youtube.com/watch?v=iGOAQli7tGc&t=1134s) Variable Dollar Signs and the Nortel Call Center Nightmare
PHP's variable syntax and scoping rules are rooted in real-world trauma rather than abstract language theory. While critics often dismiss the leading dollar sign (`$`) as an arbitrary or American-centric design choice, PHP’s explicit variable scoping rules were directly inspired by a debugging disaster Rasmus encountered while working as a co-op student at Northern Telecom (Nortel) in Toronto.
Nortel ran a mission-critical automated call distribution system that routed customer service calls across time zones for major clients like Air Canada. When East Coast call centers closed after hours, callers waiting in queue were forwarded to staffed desks on the West Coast, where it was three hours earlier. Every few months, the system inexplicably dropped every single caller holding in the queues, creating a business disaster for Air Canada. Senior engineers had failed to track down the cause for years, so the problem was handed to Rasmus as a co-op assignment—largely as a learning exercise, with no expectation that he would succeed.
To trace the execution path, Rasmus printed out the entire C codebase on tractor-feed dot-matrix printer paper, taped the wide pages along the walls of Nortel's hallways, and spent three and a half months crawling on floors and climbing chairs with colored highlighters after hours. The culprit was an accidental global variable name collision between two completely independent compilation units: one piece of code mutated the variable at a specific millisecond window, corrupting state in another module without any compiler warning.
Determined to never repeat that ordeal, Rasmus ensured that PHP functions could never implicitly mutate global state. In PHP, modifying an outer scope requires explicit declaration via the `global` keyword or direct access through the `$GLOBALS` superglobal array. He noted with concern that the introduction of implicit variable auto-capturing in upcoming PHP 7.4 short arrow functions threatens this strict isolation principle.
> “In the end after three and a half months it turned out to be a global variable collision two separate pieces of the code and completely unrelated had the same name for a variable and it was global changed in one place at exactly the wrong time would cause this other code to go crazy and the C compiler at the time had no way of informing us that that was happening” — Rasmus Lerdorf
> “The first time a bug appears because of auto capturing and arrow functions I'm gonna go kick Nikita.” — Rasmus Lerdorf
[22:44](https://www.youtube.com/watch?v=iGOAQli7tGc&t=1364s) The Reality of Register Globals and Magic Quotes
While features like `register_globals` and `magic_quotes` are widely ridiculed in hindsight, Rasmus argues that without `register_globals`, PHP would never have gained mainstream adoption. In an era before JavaScript and cross-site scripting (XSS) existed, dynamic server-side programming was incomprehensible to the average user. `register_globals` empowered non-programmers to create dynamic web forms by automatically converting form inputs (`name`, `age`) directly into accessible runtime variables (`$name`, `$age`). A beginner could write `if ($age > 19)` or `echo $name;` without understanding HTTP request methods, query string parsing, or data serialization.
In contrast, Rasmus admits that `magic_quotes` was born purely out of personal laziness. After building an extensive software application for the University of Toronto that spanned dozens of separate PHP files, he realized that user input interpolated into database queries exposed security flaws. Faced with the tedious chore of manually auditing and escaping every single query string across dozens of scripts, he took a shortcut: he added an automated runtime configuration flag to have PHP escape everything globally on his behalf.
> “Without register Globals we wouldn't be here honestly register Globals enabled users who had no idea how the web worked to build dynamic pages to put up an HTML form name age address as the field names and then add a tags that just said echo name or if age is greater than 19 without thinking about anything the fact that field names became variable names in PHP was the killer feature in the early days of the web” — Rasmus Lerdorf
> “Magic quotes was me being lazy I admit that one this was not a good solution but it took me a while to discover that I should probably be careful about letting user data into SQL queries” — Rasmus Lerdorf
- `register_globals` lowered the barrier of entry by binding HTML input fields directly to PHP variable names without manual parsing. - At the time `register_globals` was conceived, the browser landscape lacked JavaScript, DOM manipulation, and cross-site scripting vectors. - `magic_quotes` was implemented as a global toggle strictly so Rasmus could avoid editing dozens of individual source files written for the University of Toronto.
[24:57](https://www.youtube.com/watch?v=iGOAQli7tGc&t=1497s) Vertical vs. Horizontal Consistency in PHP
Rasmus addresses the perennial criticism of PHP’s function naming and argument order, such as the infamous inconsistency between needle-haystack and haystack-needle across standard functions. He explains that PHP’s consistency was designed vertically rather than horizontally because of the language's organic evolution. When various contributors authored extensions, they built thin wrappers over existing C libraries. For instance, the OCI8 functions interfacing with Oracle map almost one-to-one to Oracle's underlying C API functions, just as MySQL functions reflect MySQL's client library and string functions mirror the conventions of standard C `libc`.
Because argument orders and naming schemes were inherited directly from the underlying libraries PHP wrapped, achieving uniform horizontal consistency across radically different C APIs would have required an impossible degree of foresight. At the time, the web was expanding at an explosive rate and demanded practical tools immediately. Taking the time to coordinate and redesign every interface uniformly would have stalled PHP’s adoption entirely. As Rasmus summarizes: “If I had sat around worrying about horizontal consistency, we also wouldn't be here today.”
```mermaid flowchart TD accTitle: Vertical Consistency Architecture accDescr: Diagram showing how PHP's vertical consistency maps directly to underlying C libraries rather than enforcing horizontal consistency across modules.
subgraph PHP_Layer ["PHP Userland (Vertical Mapping)"] StringFunc["String Functions"] MySqlFunc["MySQL Functions"] OciFunc["OCI8 Functions"] end
subgraph Lib_Layer ["Underlying C Libraries"] LibC["LibC APIs"] LibMySQL["MySQL Client C API"] LibOCI["Oracle OCI C API"] end
StringFunc -->|"1:1 mapping"| LibC MySqlFunc -->|"1:1 mapping"| LibMySQL OciFunc -->|"1:1 mapping"| LibOCI ```
[26:27](https://www.youtube.com/watch?v=iGOAQli7tGc&t=1587s) Upgrading to PHP 7.3 and Quality-of-Life Syntax Improvements
Turning to modern PHP, Rasmus asks the audience if everyone is migrating to PHP 7.3, and is visibly crestfallen when several hands go up for PHP 5: “You're killing me man I was expecting maybe one or two hands to go up but the whole back of the room lit up.” For those catching up through 7.0, 7.1, 7.2, and 7.3, he highlights a sequence of practical language enhancements:
- **Flexible Heredoc and Nowdoc syntax**: The closing marker is no longer required to sit rigidly in the first column of a new line; it can now be indented, and whatever whitespace indents the closing tag is automatically stripped from each preceding line of content. - **Warning on `continue` targeting a `switch`**: Inside a loop, developers frequently write `continue` inside a `switch` statement expecting it to jump to the next loop iteration, whereas in PHP it actually behaves identically to `break`. PHP 7.3 issues a warning indicating that the developer almost certainly intended either a `break` or a `continue 2`. Rasmus advises: “If you see these and you did mean a break here, then just change it to a damn break.” - **References in `list()` assignments**: Reference assignments are now supported in both the classic `list(&$a, &$b)` syntax and the short bracket syntax `[&$a, &$b]`. - **Trailing commas in function calls**: PHP 7.2 added trailing comma support to multiple constructs, but overlooked argument lists; PHP 7.3 remedies this omission. - **Monotonic timing via `hrtime()`**: Prior to 7.3, timing code execution generally relied on `microtime()`, which depends on the system clock. System clocks are vulnerable to drift, manual administrative resets, and NTP adjustments that can freeze the clock, alter its rate, or step it backward. The monotonic timer guarantees a forward tick of precisely one second per second, making it the proper tool for profiling. - **`fpm_get_status()`**: A native function providing internal process pool metrics, allowing developers to build real-time status dashboards similar to Apache's mod_status scoreboard.
[29:47](https://www.youtube.com/watch?v=iGOAQli7tGc&t=1787s) Eliminating Boilerplate and Surviving the PCRE2 Migration
PHP 7.2 made `count()` emit a warning whenever it was invoked on a non-countable type (anything that is neither an array nor an object implementing `Countable`). Because PHP developers rarely have guaranteed types across wildly dynamic codebases, they resorted to verbose guards like `is_array($foo) || $foo instanceof Countable`. Rasmus jokes about dynamic typing habits: “In PHP you never know what the hell is in a variable because you've written code when you have methods that can return six different types based on all kinds of different things.” PHP 7.3 introduces `is_countable()` to streamline this check. Similarly, fetching the first or last key of an associative array previously forced developers to call `reset()` or `end()`, which moved the internal array pointer, failed on non-variable return expressions, and caused unexpected side effects. PHP 7.3 adds dedicated, side-effect-free helpers: `array_key_first()` and `array_key_last()`.
The most critical backward-compatibility pitfall in PHP 7.3 is the transition to the PCRE2 engine. While the `count()` change in 7.2 merely produced log noise, PCRE2 will outright reject regex compilation for invalid character ranges. For example, a character class containing `[a-\s]` was interpreted by PCRE1 as an invalid range; unable to resolve the range between `a` and whitespace, PCRE1 silently degraded the hyphen into a literal `-` character matching `a`, `-`, or `\s`. Under PCRE2, that pattern is treated as an illegal range, fails compilation, logs an `unable to compile regular expression` warning, and stops functioning completely. Rasmus emphasizes that developers must audit their error logs during upgrades: “This one breaks your application because it won't compile the regex and that regex will not do anything.” The fix is straightforward: prefixing the hyphen with a backslash (`[a\-\s]`) makes the pattern valid and portable across both PCRE1 and PCRE2.
- **Migration documentation backlog**: Upgrading from PHP 5 requires working through the migration guides for 7.0, 7.1, 7.2, and 7.3 sequentially, with 7.4 looming on the horizon. - **Extension upgrades**: Developers maintaining native C extensions must consult the internal upgrading notes, as core Zend engine APIs changed significantly across these minor releases.
[34:24](https://www.youtube.com/watch?v=iGOAQli7tGc&t=2064s) Compiler Optimizations: DCE, SCCP, and Escape Analysis
Rasmus spotlights the core compiler work spearheaded by Dmitry Stogov in Saint Petersburg, who implemented Dead Code Elimination (DCE), Escape Analysis, and Sparse Conditional Constant Propagation (SCCP) in OPcache. Developers can inspect these optimizations directly by passing runtime configuration flags to OPcache to dump the post-optimization bytecode:
```ini opcache.optimization_level=-1 opcache.opt_debug_level=0x20000 ```
When OPcache analyzes a function where a local variable is assigned a value (e.g., `$a = 1;`) but never read before the function simply executes `return 0;`, PHP 7.1 and earlier would still emit an `ASSIGN` opcode followed by a `RETURN`. In PHP 7.2 and 7.3, the optimizer recognizes that local variables have no side effects outside the function scope, eliminates the dead assignment entirely, and avoids writing redundant opcodes into shared memory.
The optimizations scale to more elaborate scenarios. If an execution path performs multiple string concatenations into an intermediate variable `$x`, but immediately overwrites `$x` with `0` and returns it, earlier engines generated opcodes for every concatenation and temporary storage assignment. In PHP 7.2 and 7.3, SCCP and DCE see through the entire sequence: the concatenations are bypassed, the assignment is dropped, and the entire function body is collapsed into a single `RETURN 0` opcode. Rasmus notes that PHP 7.3 extends this static analysis beyond scalar values into arrays and objects, checking parent scopes for potential side effects before safely discarding unused operations.
[37:25](https://www.youtube.com/watch?v=iGOAQli7tGc&t=2245s) Dead Code Elimination and Array Optimization in PHP 7.3
Rasmus explains the aggressive opcode optimizations introduced in PHP 7.3, specifically focusing on dead code elimination and side-effect detection. When an object is instantiated without a constructor or a destructor, and a property is set without invoking any custom setter, the engine determines that the entire sequence has zero observable side effects. As a result, the optimizer simply purges all intermediate opcodes and reduces the routine to returning the requested value directly. However, the presence of a destructor disrupts this optimization: even if the destructor body is entirely empty, the engine preserves the opcodes because it only checks for the existence of the method rather than introspecting whether it contains actual code.
```mermaid flowchart TD accTitle: Dead Code Elimination Decision Flow accDescr: Flowchart showing how PHP 7.3 optimizer eliminates opcodes based on constructor and destructor side effects.
Start["Instantiate Object"] --> CheckDtor{"Has Destructor / Side Effect?"} CheckDtor -- "Yes (Method exists)" --> KeepOps["Preserve Opcodes (Potential Side Effect on Scope Exit)"] CheckDtor -- "No" --> StripOps["Optimizer Eliminates All Instantiation Opcodes"] StripOps --> DirectReturn["Return Scalar Result Directly"] ```
The optimizer exhibits similar intelligence when evaluating array structures and complex branching logic. If an expression branches on a truthy or falsy value of an input but unconditionally yields the identical first element (such as index zero), PHP 7.3 discards all intermediate array building and condition checks, compiling the block into a single return instruction. Rasmus illustrates this with a convoluted, heavily nested block of code that the optimizer cleanly collapses into simply echoing one and returning four. He cautions the audience about misinterpreting dramatic benchmark gains:
> “If it's 30 40 % faster then it's the optimizer eliminating all your code basically deleting your code and saying you're an idiot all this code doesn't need to be here right so this is the real performance gain you can expect from 73.”
- Real-world upgrades across minor releases (such as from 7.1 or 7.2 to 7.3) should realistically yield around a 5% to 10% performance bump; extreme 30% to 40% improvements mean the compiler wiped out redundant, poorly structured application code. - Destructor detection operates as an existence check rather than deep AST validation: even an empty `__destruct()` prevents side-effect elimination because traversing its body would add another layer of optimizer overhead.
[39:59](https://www.youtube.com/watch?v=iGOAQli7tGc&t=2399s) Real-World Performance Trends and End-of-Life Versions
Reviewing longitudinal benchmarks run against the WordPress front page on his test hardware, Rasmus demonstrates the sustained compounding gains across PHP generations from 5.3 up through 7.3. Throughput on the WordPress homepage increased from 154 requests per second in PHP 5.3 to 498 in 7.0, climbing to 520 requests per second in modern releases. Over the same span, latency plummeted from 140 milliseconds under 5.3 down to 38 milliseconds. Concurrently, base memory requirements dropped drastically: serving WordPress required 140 megabytes on PHP 5.3, whereas PHP 7.3 handles the identical workload using only 15 megabytes. While noting that absolute metrics depend on the specific machine, he emphasizes that the upward and downward relative trajectories have remained constant.
Rasmus pivots directly to the critical state of production deployments, urging developers to abandon legacy versions. At the time of speaking, only PHP 7.2 and 7.3 receive active community maintenance. PHP 7.0 was released in 2015, which in web timelines constitutes antiquated technology, and it no longer receives even emergency security patches. Running obsolete branches when handling user information is an indefensible operational hazard:
> “And the for the folks still running PHP 5 it's just irresponsible honestly to be running code that old on anything that might be important I mean if it's if it's your blog or something fine no problem right but if it's something that's dealing with customer data or anything that is actually sensitive you can't be running code that's 10 plus years old you can't do it.”
[41:53](https://www.youtube.com/watch?v=iGOAQli7tGc&t=2513s) Static Analysis with Phan
Rasmus introduces static analysis through Phan, a project he originally created and subsequently handed off to maintainers whom he describes as smarter than himself—a recurring personal pattern of kicking off a tool just far enough to make it viable before letting others run with it. Phan integrates via Composer (`composer require phan/phan`) and relies on a straightforward configuration file. In typical project layouts consisting of `src/` and `vendor/`, the configuration scans `vendor/` to build a complete dependency and type map for external method signatures, but leverages an `exclude_analysis_directory_list` so that warnings are not reported for third-party libraries. First-time users should expect hundreds or thousands of reported issues, which can then be triaged using targeted error filters.
Phan checks a broad array of static conditions and supports rich type annotations far beyond native PHP typehints. Rasmus walks through an example function accepting three parameters: 1. A union type accepting `string|int`. 2. A typed array specified as `int[]`, ensuring that passing an array containing non-integer values triggers an analysis failure. 3. A shaped array requiring specific keys and value types, such as `'mode' => string` and `'max' => int`.
If a caller provides an array where a union scalar is expected, or omits the mandatory `'mode'` key inside the shaped array, Phan catches the discrepancy statically at build time without needing runtime test execution.
[44:48](https://www.youtube.com/watch?v=iGOAQli7tGc&t=2688s) Low-Overhead Sampling with phpspy
Shifting to runtime diagnostics, Rasmus presents `phpspy`, a zero-overhead sampling profiler developed at Etsy by an engineer named Adam. Inspired by profilers like `rbspy` (and `py-spy`), `phpspy` attaches to any running PHP process—whether managed via PHP-FPM, Apache's `mod_php` (`httpd`), or standalone CLI scripts—without modifying the engine or attaching heavy profiling hooks. By default, it samples the target at 99-millisecond intervals. It deliberately defaults to 99 milliseconds instead of an even 100 milliseconds to avoid lockstep harmonic timing bugs, since internal server operations often align cleanly to round hundred-millisecond boundaries.
The utility inspects target processes by reading kernel memory tables. Rasmus illustrates this by targeting a CLI script that executes a one-second `sleep(1)`. Probing every 200 milliseconds produces five consecutive stack traces showing `sleep()` called from `main()`, followed by a `No such process` termination response once execution finishes. When attached to an active PHP-FPM worker serving WordPress, the tool pulls the full runtime call stack.
```mermaid flowchart LR accTitle: phpspy Stack Profiling Architecture accDescr: Diagram illustrating how phpspy attaches to a running PHP process, samples stack traces and memory, and generates flame graphs.
subgraph Sampling ["Process Sampling"] PHPProc["PHP Process (FPM / CLI / mod_php)"] PHPSpy["phpspy (samples at 99ms)"] PHPSpy -.->|"Reads memory offsets"| PHPProc end
subgraph Output ["Trace Processing"] RawTrace["Stack Traces + Memory (-m)"] Collapse["stackcollapse (Perl)"] Flame["flamegraph.pl"] Visual["Interactive Flame Graph"]
PHPSpy --> RawTrace RawTrace --> Collapse Collapse --> Flame Flame --> Visual end ```
Running `phpspy` with the `-m` flag extracts memory utilization for each stack frame. While the numerical collection is fully functional, Rasmus issues an open call for community contributions to build visual tooling, such as integration with `perf` or `callgrind`, to make memory visualization effortless. For execution time profiling, `phpspy` bundles standard Perl scripts (`stackcollapse` and `flamegraph.pl`) to generate interactive SVG flame graphs, which Rasmus demonstrates using a trace of Phan analyzing its own codebase.
At Etsy, `phpspy` solves persistent operational blindspots surrounding long-running asynchronous worker queues:
> “We have a Gearman pool of servers that handle Gearman jobs some of these are quite long-running we also have servers doing cron jobs and again some of these runs for quite a while and sometimes they run a lot longer than we think they should and it's hard to know what the heck they're doing because we tried like on our development servers and it never runs for more than six minutes or something and then in production this thing has been running for 40 minutes what's it doing right we can't replicate it but with PHP spy we can hop on the production server attached to the running process without slowing it down and see what it's doing where is it spending its time.”
- **Zero-compilation requirement:** `phpspy` does not require special compiler flags, debug symbols, or custom extensions; it works seamlessly against fully stripped, heavily optimized binaries compiled with `gcc -O3`. - **Kernel-level memory inspection:** The tool requires `root` privileges because it relies on hardcoded struct offsets within the running process memory to locate Zend executor globals (`EG` globals) for specific PHP minor versions (e.g., PHP 7.3).
[49:28](https://www.youtube.com/watch?v=iGOAQli7tGc&t=2968s) Profiling Variables with phpspy and an Open Call for Contributors
Continuing his discussion of phpspy, Rasmus explains how the tool inspects memory at specific offsets to see what is actively changing inside a running PHP process. Beyond call stacks, phpspy includes a feature that lets developers spy directly on a specific variable: you can configure it to inspect memory every 99 milliseconds and report the variable's value, effectively tracking its mutations over time. Rasmus emphasizes that while the backend works remarkably well, there is enormous potential for contributors to build richer front-end user interfaces and visualization tooling around this data.
The project’s author, Adam Saponara, has concentrated almost exclusively on the low-level backend logic and actively dislikes public speaking. Rasmus uses this as an open invitation to the audience, noting that building a front-end wrapper for phpspy is practically a golden ticket to speaking at developer conferences. As Rasmus puts it: “Adam has mostly been focusing on the backend part. He also hates public speaking, so if you want a project where you can have pretty much a guaranteed accepted conference talk, come contribute to phpspy, add the cool front-end support for some of this stuff, and submit the talk, and I guarantee you it will be accepted because it's really cool and Adam's not going to mind—he would love someone else to talk about phpspy for us.”
[50:24](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3024s) PHP 7.4 Features: Typed Properties, Arrow Functions, and Weak References
Turning toward the upcoming PHP 7.4 release, Rasmus reviews several major language additions, starting with typed properties. He quips that typed properties are wonderful “if you don't care about performance,” though the team hopes to develop optimizations to mitigate the overhead. Every property write requires an implicit type check. Rasmus explains that this runtime check is the exact reason PHP will not introduce typed standard local variables: in a tight loop like `while ($i++)`, checking types on every single iteration would destroy execution speed. Because developers rarely make loop iterators into class properties (`$this->i++`), property writes occur far less frequently, keeping the performance hit acceptable.
Rasmus also touches on several other quality-of-life additions in PHP 7.4: - **Arrow functions:** Short closures automatically capture variables from the parent scope by value, can be nested, and support full parameter and return type declarations. - **Custom object serialization:** New `__serialize()` and `__unserialize()` magic methods replace the error-prone and side-effect-laden `__sleep()` and `__wakeup()` mechanisms, giving classes complete control over payload formatting. - **Null coalescing assignment operator:** The `??=` shorthand is introduced to streamline conditional defaults. - **Weak references:** Addressing PHP’s reference-counting garbage collector. Normally, an object is freed when its reference count drops to zero. In caching architectures, storing an object reference directly in a cache prevents it from being collected even if the application has finished using it. Weak references allow caches to point to objects without incrementing their reference counter, letting memory free cleanly when primary references leave scope.
[53:46](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3226s) OPcache Preloading
Rasmus highlights OPcache preloading as one of the most powerful new additions to PHP 7.4. Inspired by Java’s HotSpot VM, preloading allows designated user-space PHP files to be compiled directly into memory at server startup, making functions and classes permanently available to all subsequent requests as if they were internal C-level functions. The trade-off is deployment ergonomics: because the files are only read on server initialization, hot-reloading code via disk stats is no longer possible; deploying new code requires restarting the process pool or using complex cache-clearing mechanisms.
In traditional execution, OPcache stores bytecode in shared memory, but each request still incurs overhead to resolve opcodes into the local request scope and trigger autoloaders. Preloading eliminates this per-request overhead entirely. Setting `opcache.preload` in `php.ini` points to a bootstrap script (such as `preload.php`) that calls `opcache_compile_file()` on chosen source files. When the web request runs, classes like `Class A` instantiate immediately without triggering `spl_autoload_register`. A side effect is that duplicate class names across different directories can no longer coexist in the preloaded set; trying to preload two classes of the same name triggers a fatal redefinition error.
```mermaid flowchart TD accTitle: OPcache Preloading Workflow accDescr: Diagram showing how opcache.preload compiles classes on server startup to bypass the autoloader during web requests.
subgraph Startup["Server Startup"] A["php.ini: opcache.preload"] --> B["preload.php"] B --> C["opcache_compile_file()"] C --> D["Classes registered as internal memory"] end
subgraph Request["Web Request Execution"] E["new A()"] D -.->|"Instant availability"| E E --> F["Constructor executes"] E -.->|"Bypassed entirely"| G["spl_autoload_register()"] end ```
[56:32](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3392s) Foreign Function Interface (FFI) and C Integration
Foreign Function Interface (FFI) allows PHP scripts to load shared libraries (`.so` or `.dll` files) and invoke arbitrary C functions directly without writing custom C extensions or compiling PHP modules. Rasmus demonstrates a basic example that binds to `libc.so.6` using a C header prototype for `printf()`, enabling PHP to call libc's `printf` directly from an FFI object—though he admits that specific test is “completely useless because PHP already has a printf function that does exactly that.”
To demonstrate a realistic use case, Rasmus imported `gifenc`, a lightweight C library for creating animated GIFs found on GitHub. By taking the library’s original C header file (`gifenc.h`), adding two lines defining an FFI scope and pointing to the compiled shared object, PHP loads the library and exposes functions like `ge_new_gif()`, `ge_add_frame()`, and `ge_close_gif()`. However, Rasmus cautions that working with FFI still requires understanding C data types and memory representations:
- Scalar C arguments like `int`, `long`, or `char *` map cleanly to PHP integers and strings. - C pointer arguments, such as `uint8_t *` for an RGB palette, cannot be passed as basic PHP arrays. - Developers must use `FFI::new("uint8_t[12]")` to allocate genuine C-level memory structures and populate color values manually before passing the pointer. - By looping through frame buffers and calling `ge_add_frame()`, PHP can generate a fully functional animated GIF directly via raw C memory calls.
[01:00:09](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3609s) Combining Preloading with FFI for Composer-Driven Extensions
Rasmus connects preloading and FFI into an architectural breakthrough. Executing `FFI::load()` dynamically during an HTTP request is computationally expensive: parsing C headers, resolving symbols, and binding types per-request is “deadly slow.” However, executing FFI bindings inside an `opcache.preload` bootstrap moves that compilation cost entirely to server startup. All C bindings and types are compiled once and persist in memory across the entire life of the PHP worker.
This combination allows PHP developers to replace thin, hard-to-maintain C extensions with native PHP packages. C developers are only needed to produce the initial header file and identify required pointer types, while standard PHP developers can write all surrounding data marshaling, loops, and object-oriented wrappers. Furthermore, because these wrappers are ordinary PHP code, they can be distributed and versioned effortlessly via Composer instead of requiring system-level compilation through PECL. As Rasmus summarizes: “I can see a whole bunch of our very thin extensions that just wrap C libraries, I can see these being converted to preloaded FFIs that you can just Composer-install directly, because they're really just PHP scripts.”
[01:01:21](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3681s) Broadening Extension Maintenance and 25 Years of Memories
Wrapping up the technical side of extending PHP, Rasmus highlights how enabling developers to make small changes to extensions directly in PHP and manage them via Composer can fundamentally expand the contributor pool. Opening up extension maintenance to everyday PHP users lowers the barrier to entry, meaning people no longer need deep C expertise just to tweak or maintain basic functionality. Rasmus reflects that this shift “will increase or broaden the users, the amount of users that can help maintain extensions, and I think it can kind of change the world for us.”
With his remaining presentation time slipping away, Rasmus transitions into personal stories and memories from the past quarter-century. He recalls that these 25 years of PHP also encompassed the birth and upbringing of his son, Karl, who was born 17 years earlier. Showing an old photograph of himself hacking on PHP on an old IBM ThinkPad—decorated with an Apple sticker despite him never actually making the switch to Mac—he points out a tiny baby Karl at just two or three days old.
Karl grew up immersed in open-source conferences. Rasmus fondly recounts taking Karl as a toddler to events like LinuxTag, where the boy had an uncanny knack for locating power switches. Dressed in a little PHP shirt, Karl would run from booth to booth on the exhibition floor, eagerly pressing the power buttons and shutting down live demo servers. While his sheer cuteness and PHP attire kept booth staffers from getting too furious, Rasmus admits there were plenty of grumbling engineers when Karl would circle right back around to turn the servers off a second time. Fast forward to the present: Karl is 17 years old, has hair down to his elbows, drives, and plays video games in the car. Seeing his son drive up to pick him up makes Rasmus feel truly old, underscoring just how much time has passed since PHP began.
[01:03:20](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3800s) Old-School Hackers, Photoshopped Suits, and Arthur C. Clarke
Rasmus looks back through visual snapshots from his global travels over the last 25 years. He recalls visiting Australia annually for hacker gatherings, displaying a photo from the era of bulky CRT monitors before LCD panels existed. The group shot features prominent figures like Andrew Tridgell—widely known for creating rsync and Samba—alongside Linus Torvalds and a crowd of other Australian hackers.
His travels also produced plenty of absurd moments. In India, conference organizers apparently felt their keynote speakers needed to project a formal, corporate image. Rather than asking him to wear business attire, they took a photograph of Rasmus, digitally photoshopped him into a formal suit, and plastered giant posters of him looking distinguished all across the city. Rasmus laughs at the memory of arriving in town, seeing these massive billboards of himself in an outfit he has never owned, and wondering what on earth had happened.
Another surreal highlight came during a PHP conference in Sri Lanka. Rasmus asks the audience if they can recognize an elderly man sitting in the front row of the photo. It was the legendary science fiction author Sir Arthur C. Clarke, who lived in Sri Lanka for decades. Clarke attended the conference, sat directly up front, asked questions, and remained completely engaged throughout the talk. Rasmus reflects on how incredible it felt to teach PHP directly to the creator of *2001: A Space Odyssey*.
[01:04:51](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3891s) Sahana, Real-World Impact, and the Color of the Hammer
The visit to Sri Lanka took place in 2005, shortly after the catastrophic Indian Ocean earthquake and tsunami of December 2004 that devastated coastal communities across South Asia. In the wake of that disaster, a university student and a Sri Lankan government worker teamed up to develop Sahana, an open-source disaster management system built entirely in PHP. When Rasmus visited, he spent time consulting with the team on how they could leverage PHP to optimize the system.
Sahana was designed as a rapid-deployment "disaster relief in a box" package that can be spun up on a server in roughly three minutes. It provides coordinated modules to track humanitarian aid and locate displaced people: - When a plane full of supplies, such as diapers or medical kits, lands at an airport, ground volunteers log the shipment into an inventory tracker indicating exactly which hangar or warehouse it was moved to. - Through a lightweight web interface and mobile applications, rescue workers register survivors at shelters (e.g., recording a person's name and assigning them to shelter number three). Family members searching online for missing relatives can query the database to find out if their loved ones have been located and where they are staying.
```mermaid flowchart TD accTitle: Sahana Disaster Management Flow accDescr: Diagram illustrating how Sahana coordinates disaster relief logistics and missing person tracing.
subgraph ReliefLogistics["Relief & Supply Coordination"] A["Aid Delivery (e.g., Cargo Flight)"] --> B["On-the-Ground Volunteers"] B --> C["Sahana Inventory Module<br/>(e.g., Diapers in Hangar 3)"] end
subgraph MissingPersons["Missing Persons Registry"] D["Rescue Worker on Mobile App"] --> E["Register Survivor<br/>(Name + Shelter Assignment)"] E --> F["Sahana Central Database"] G["Family Online Search"] -->|"Query Relative Name"| F F -->|"Confirmation & Location"| G end
ReliefLogistics -.->|"Spin up in 3 minutes"| H["Deployed in 50+ Global Disasters"] MissingPersons -.->|"Spin up in 3 minutes"| H ```
Sahana has since been deployed in more than 50 major disaster zones worldwide, earning public praise from officials such as the Philippines' Secretary of National Defense. For Rasmus, this real-world application provides a crucial sense of perspective that shields him from developer drama:
> “Knowing that PHP has literally probably saved someone's life makes all that online grief completely irrelevant.”
He stresses that the technical disputes dominating online forums are petty compared to the actual problems software can solve: “Arguing about the color of the hammer used to build that thing, it's just moronic and all these flames about the technologies and stuff, we can't lose track of what we're doing here, why we're programming.”
[01:08:15](https://www.youtube.com/watch?v=iGOAQli7tGc&t=4095s) Burnout, Staying Motivated, and Focusing on What You Build
Rasmus observes a recurring trend across tech conferences: many developers who were active a decade ago are no longer in the audience because they burned out, left engineering, or shifted into middle management. While stepping into management is a natural and rewarding career path for some, Rasmus points out that many exceptional programmers end up becoming ineffective managers simply because they feel exhausted trying to keep up with the relentless pace of technological change. In his view, claiming it is too hard to keep up is often just code for having lost interest and motivation, especially as family commitments grow.
To sustain a multi-decade career without burning out, developers need an enduring passion that transcends specific technologies. He challenges the younger attendees in the room to consider whether they will still want to be coding when they are 50, 60, or 70 years old. If they do, they must remain focused on the final product rather than the instrument used to produce it:
> “I'm sure there are all kinds of geek arguments about paintbrushes, what's the best paintbrush that painters might have internally, doesn't matter, what people remember are the actual paintings, right?”
He draws another parallel to music, asking the audience if anyone knows who built Wolfgang Amadeus Mozart’s piano. While historical instrument purists might care, the world remembers the timeless music Mozart composed, not the specific piano manufacturer. The same principle applies to programming: software tools are merely instruments to solve meaningful problems.
[01:10:27](https://www.youtube.com/watch?v=iGOAQli7tGc&t=4227s) Programming to Program Less: Means to an End
Rasmus candidly shares his own self-assessment as a software developer, placing himself squarely in the middle of typical developer archetypes. He admits that he considers himself a mediocre coder who does not even particularly like programming for its own sake. The entire reason he created PHP in the first place was that existing tools in 1994 were too complex, tedious, and ill-suited for web tasks. Ironically, his attempt to avoid tedious programming led him on a 25-year journey:
> “So in order to program less I spent the next 25 years programming something that would let me program less, it made no sense, but still it did allow me to build things along the way that actually affected people's lives and that still keeps me going.”
He expresses deep gratitude for the contributors who love coding purely for the joy of writing code. Unlike those developers who relish the programming journey regardless of the destination, Rasmus views coding the same way he views air travel: he hates flying and dislikes sitting in a cramped airplane, but he spends his life on planes simply because he wants to reach his destination. Similarly, code is just a vehicle to create useful tools that make a real difference.
After reminding the audience that grand ideas require grounding in reality to see if they can truly work, Rasmus apologizes for running slightly over time, points to the URL where his slides are hosted, and concludes his 25-year retrospective to enthusiastic applause.
## Notable quotes > [01:04:51](https://www.youtube.com/watch?v=iGOAQli7tGc&t=3891s) Knowing that PHP has literally probably saved someone's life makes all that online grief completely irrelevant. — Rasmus Lerdorf
> [01:08:15](https://www.youtube.com/watch?v=iGOAQli7tGc&t=4095s) I'm sure there are all kinds of geek arguments about paintbrushes, what's the best paintbrush that painters might have internally, doesn't matter, what people remember are the actual paintings, right? — Rasmus Lerdorf
## Mentioned Rasmus Lerdorf, Dmitry Stogov, Nikita Popov, David Hughes, Adam Saponara, Karl Lerdorf, Andrew Tridgell, Linus Torvalds, Sir Arthur C. Clarke, Wolfgang Amadeus Mozart, PHP, Gopher, Mosaic, Perl, CGI.pm, Yacc, Lex, LAMP stack, Oracle, Apache, mod_php, mod_perl, Etsy, HHVM, mSQL, MySQL, PostgreSQL, Allaire ColdFusion, Northern Telecom (Nortel), Air Canada, University of Toronto, OCI8, LibC, PCRE1, PCRE2, OPcache, WordPress, Phan, Composer, phpspy, rbspy, py-spy, PHP-FPM, Gearman, HotSpot VM, FFI, gifenc, PECL, LinuxTag, IBM ThinkPad, rsync, Samba, Sahana
## Video description PHP has been around for almost as long as the Web. 25 years! Join me for a fun look at the highlights (and lowlights) of this crazy trip. But I will also be trying to convince you to upgrade your PHP version. The performance alone should be enough, if not, I have a few other tricks up my sleeve to try to win you over. Performance optimization, static analysis, zero-cost profiling, dead code elimination and escape analysis are just some of the concepts that will be covered.
Next edition: May 14-15th 2020 |https://www.eventbrite.it/e/phpday-2020-tickets-61863983841
Keep in touch! Subscribe to our newsletter http://eepurl.com/rCZZT Follow @phpday on Twitter and Facebook
[Source](https://www.youtube.com/watch?v=iGOAQli7tGc)