Rasmus Lerdorf - 25 Years of PHP - phpday 2019

Rasmus Lerdorf - 25 Years of PHP - phpday 2019 — GrUSP

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>&lt;!--tag cos input--&gt;</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)

中文简报

Rasmus Lerdorf回顾PHP走过的25年:phpday 2019演讲 Rasmus Lerdorf回顾了PHP的起源,详细讲述了最初为Mosaic浏览器构建的简单C语言模板引擎,如何凭借Apache的mod_php多进程模型以及无共享执行架构等务实设计,逐步演化为占据主导地位的Web语言。他深入剖析了PHP 7.3和7.4的现代性能提升,重点介绍了OPcache中的死代码消除、Phan静态分析、基于phpspy的零开销采样分析、预加载以及外部函数接口(FFI)绑定。Lerdorf敦促听众放弃已停止支持的PHP 5和早期7.x分支,并在演讲最后对软件实用主义作了哲学层面的辩护,主张工程师应专注于构建解决现实问题的方案,而非纠结于开发工具的争论。 PHP于1994年诞生时并非一门独立的编程语言,而是一个极简的C语言API与模板层,旨在通过将HTTP头、Cookie及GET/POST输入从后端逻辑中抽象出来,以简化Web开发。 (2:37) 在早期Web托管经济模式中,mod_php的表现优于mod_perl,因为其严格的无共享执行沙箱让互联网服务提供商能够安全地在单台物理服务器上容纳3000个租户,而mod_perl则需要昂贵的专用硬件。 (9:32) Rasmus Lerdorf在1994至1995年为David Hughes的mSQL工作期间发明了关系型SQL的“LIMIT”子句,引入了查询边界以防止慢速网络环境下发生失控的SELECT查询。 (14:15) OPcache中的现代优化手段(如死代码消除、稀疏条件常量传播)以及PHP 7.4引入的特性(如OPcache预加载和FFI)大幅提升了性能,并实现了通过Composer分发C语言包装器。 (34:24) Lerdorf强调,与现实层面的成果相比,软件工程中关于工具选择的争论微不足道;他以Sahana等应用为例,指出其在50多个灾区提供了挽救生命的灾难救援支持。 (64:51)

Reading summary

Rasmus Lerdorf reflects on 25 years of PHP, arguing that the language succeeded by prioritizing practical web integration, hosting economics, and real-world utility over theoretical elegance or syntactic purity. Accidental Architecture and Shared-Nothing Isolation (2:37) PHP began in 1994 not as a programming language, but as a C templating layer intended to separate web presentation from business logic. After users resisted writing backend C code, Lerdorf incorporated Yacc and Lex to handle basic arithmetic precedence following the failure of a naive left-to-right parser. Rather than refining language syntax, design decisions responded to immediate operational constraints: arbitrary additions like the SQL LIMIT clause addressed network bottlenecks in mSQL, while function case-insensitivity accommodated competing HTML styling habits. Language features such as register_globals lowered entry barriers for non-programmers, and explicit variable scoping rules were established to prevent the catastrophic global collisions Lerdorf experienced while debugging call-center software at Nortel. Hosting Economics and Multi-Process Resilience (9:32) PHP gained a dominant market share over competitors like Perl largely due to server integration architecture. While mod_perl exposed extensive Apache request hooks—including the path translation hook, which created security risks that prevented safe multi-tenancy and forced internet service providers to charge around $600 monthly for dedicated physical servers—mod_php hooked only into the content-generation phase. This allowed hosting providers to safely isolate roughly 3,000 tenants on a single bare-metal server. Operational safeguards such as memory limits and tracking actual CPU seconds in max_execution_time kept runaway scripts from crashing multi-tenant hosts. Modern Runtime Optimization and Tooling (34:24) Modern releases delivered steep performance improvements: longitudinal benchmarks running the WordPress front page showed throughput increasing from 154 requests per second in PHP 5.3 to 520 in modern iterations, while latency dropped from 140 milliseconds to 38 milliseconds and memory consumption fell from 140 megabytes to 15 megabytes. Compiler enhancements spearheaded by Dmitry Stogov introduced Dead Code Elimination and Sparse Conditional Constant Propagation in OPcache, collapsing redundant logic while accounting for potential side effects such as the presence of class destructors. Ecosystem Evolution in PHP 7.4 (50:24) PHP 7.4 introduced features aimed at modernizing extension maintenance and execution ergonomics, including typed properties, arrow functions, and weak references for memory management in caching layers. OPcache preloading borrows from Java's HotSpot virtual machine to compile userland classes directly into memory at startup, bypassing autoloader overhead during HTTP requests at the cost of requiring process restarts on deployment. Combining preloading with the Foreign Function Interface (FFI) allows developers to bind C shared libraries at startup and distribute lightweight wrappers directly through Composer, lowering the barrier for community maintenance without compiling native C extensions through PECL. Tools as Instruments for Real-World Problems (64:51) Reviewing 25 years of development, Lerdorf characterizes himself as a pragmatic programmer who treats code merely as an instrument to reach an outcome rather than an art form. He cites humanitarian systems like Sahana—a PHP-based disaster relief application deployed across more than 50 disaster sites following the 2004 Indian Ocean tsunami—as proof that software's value rests entirely on the problems it resolves. For Lerdorf, focusing on the end impact rather than debating tool aesthetics is what prevents long-term developer burnout. Lerdorf emphasizes that software development tools are ultimately disposable means to practical ends, urging engineers to maintain long-term careers by grounding abstract architectural debates in tangible, real-world utility.

精炼阅读摘要

Rasmus Lerdorf 在回顾 PHP 诞生 25 周年的演进历程时指出,PHP 从未以纯粹的语言理论为先导,而是始终坚持解决实际工程瓶颈的实用主义哲学。从早期的模板引擎演化到现代高性能运行时,其每一次关键决策都围绕着降低使用门槛、保障托管安全性以及为现实世界创造价值而展开。 意外的语言设计与务实优先原则 (2:37) PHP 最初被设计为一套纯粹的 C 语言 Web 模板引擎,初衷是将业务逻辑与 HTML 表现层彻底分离,通过自定义标签将动态参数压入堆栈并调用底层 C 函数。然而,早期用户完全不愿手写 C 语言代码,不断要求在模板内引入逻辑判断、循环与数学计算,迫使 Lerdorf 逐步加入编程语言特性。由于早期手写的从左至右状态机无法正确处理运算符优先级(例如将 1 + 2 * 3 误算为 9),他随后通过学习 Yacc 和 Lex 重构了解析器。 在语言演进过程中,Lerdorf 坚决将底层基础设施的整合能力置于语法美感之上。为了解决早期网络带宽下大表查询的传输瓶颈,他在 mSQL 中发明并合并了后来被主流数据库广泛采纳的 LIMIT 语法;为了降低非程序员构建动态网站的门槛,他引入了将表单输入直接转为变量的 register_globals;函数命名与参数顺序则采取“纵向一致性”,直接镜像底层所封装的 libc、MySQL 和 Oracle OCI C 接口,以极低的封装成本换取快速交付能力。 共享无状态架构与主机托管经济学 (9:32) 在与 Perl 等先发语言的竞争中,mod_php 的集成机制成为 PHP 占领市场的决定性突破。传统的 CGI 脚本需要为每个请求执行昂贵的 fork() 与 exec() 操作,而内嵌于 Apache 进程的 PHP 能以极低开销执行。相比之下,mod_perl 因过度暴露 Apache 的生命周期钩子(特别是路径转换钩子),在多租户服务器上存在恶意用户劫持其他虚拟主机根目录的致命安全风险,导致网络服务提供商(ISP)必须为每个客户配置每月约 600 美元的独立物理机;而 mod_php 仅挂接内容生成阶段,允许 ISP 在单台物理机上安全承载 3000 个虚拟主机租户,从商业成本上奠定了统治地位。 在此基础上,PHP 确立了严格的“无共享沙箱”(Shared-Nothing)生命周期模型:每个请求在结束时彻底销毁内存与上下文状态,杜绝跨请求状态泄漏。Lerdorf 始终坚决反对在 Web 层引入多线程,坚持采用多进程预派生模型(Apache Prefork)。这种设计提供了极高的容错隔离能力:以高负载运行 PHP 的 Etsy 为例,即便系统每 30 亿次请求出现一两次偶发段错误,Apache 也能直接静默销毁并重启子进程,完全不影响并发流量;而在多线程模型中,单点内存破坏往往会导致整个服务进程彻底崩溃。 现代编译优化与生产级诊断实践 (34:24) 自 PHP 7.0 以来,核心引擎经历了深度架构优化。Dmitry Stogov 主导的 OPcache 编译器引入了死代码消除(DCE)、稀疏条件常量传播(SCCP)与转义分析,能够识别没有外部副作用的局部变量赋值、冗余字符串拼接及特定对象生命周期,并将其字节码直接坍缩为单一返回值。在纵向基准测试中,WordPress 首页的请求吞吐量从 PHP 5.3 的 154 req/s 提升至 7.3 的 520 req/s,延迟从 140 毫秒锐减至 38 毫秒,内存占用从 140MB 降至 15MB。Lerdorf 强调,生产环境中继续运行已停止维护的 PHP 5 或 7.0 处理敏感数据是不可接受的操作隐患。 在代码诊断与升级维护方面,PHP 7.3 升级至 PCRE2 正则引擎,会直接拒绝非法字符区间(如未转义的 [a-\s] 会导致编译失败并中断运行),需要开发者严密监控错误日志。为解决动态代码库的类型推断难题,Lerdorf 倡导使用静态分析工具 Phan;同时介绍了 Etsy 研发的低开销采样分析器 phpspy。phpspy 无需重编译或开启调试扩展,通过读取内核内存偏移量以 99 毫秒间隔(避开百毫秒整数谐波)采样进程状态,用于在生产环境中无损排查长耗时后台任务与内存瓶颈。 预加载与FFI驱动的扩展生态演进 (53:46) 在 PHP 7.4 的新特性中,OPcache 预加载(Preloading)与外部函数接口(FFI)为系统架构带来了质变。预加载借鉴了 Java HotSpot VM 的设计,允许在服务器启动阶段通过引导脚本将指定的类与函数一次性编译常驻于共享内存中,使得后续所有 Web 请求无需再通过自动加载器(spl_autoload_register)解析代码即可直接调用,代价是更新代码必须重启进程池。 将预加载与 FFI 结合,彻底打破了 C 扩展的开发门槛。在常规 HTTP 请求中动态解析 C 头文件性能极慢,但若将其置于服务启动的预加载阶段,C 动态库与符号绑定仅需编译一次即可常驻内存。这一机制使得广大 PHP 开发者无需具备资深的 C 扩展编译经验,仅需基于原生 C 库头文件编写 PHP 胶水层,即可通过 Composer 分发和维护高性能扩展包,有望显著扩大扩展生态的维护者群体。 工具本体论与抵抗工程师职业倦怠 (64:51) Lerdorf 坦言自己并非出于对编程本身的狂热而写代码,创建 PHP 的初衷仅仅是为了“更少地编程”以摆脱繁琐任务。面对技术社区中旷日持久的语言优劣之争,他认为争论“画笔的好坏”毫无意义,软件工程的价值终究体现在其最终构建的成果上。2004 年印度洋海啸后,斯里兰卡团队基于 PHP 迅速开发出开源灾害管理系统 Sahana,随后在全球 50 多个灾区成功协调救援物资调配与失散亲属搜寻,这种拯救生命的现实影响让一切线上的技术抨击变得微不足道。 针对大量开发者在从业数十年后陷入职业倦怠并勉强转向中层管理的现状,Lerdorf 认为保持长期职业动力的关键在于将热情维系在应用成果而非特定工具上。就如世人铭记的是莫扎特的传世乐章而非钢琴制造者的工坊,工程师若希望在五六十岁仍保持探索动力,必须将代码视为解决现实问题的工具载体,始终聚焦于软件所带来的社会与业务价值。 PHP 历经 25 年的演化历程表明,一门工程工具的持久生命力并非取决于学术意义上的语法纯粹性,而取决于对现实工程约束、多租户运营成本和生态准入门槛的务实权衡。Lerdorf 的回顾提醒开发者,技术工具终究是达成目的的手段,唯有紧密连接真实业务并解决实际问题,软件研发才能获得超越技术迭代本身的持续意义。

Source quotes

[64:51] Rasmus Lerdorf: Knowing that PHP has literally probably saved someone's life makes all that online grief completely irrelevant. [68:15] Rasmus Lerdorf: 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?

Original transcript

[0:00] [Music] [0:20] that's where I'm from every now and then [0:23] people ask oh that's hard to see down [0:24] there isn't it [0:25] but I am from northern Greenland place [0:28] called Curtis walk on the Island of [0:31] disco in the middle of disco Bay and [0:36] born in the 60s I'm old [0:40] that's the keynote yesterday was saying [0:41] we're all getting older I'm sorry [0:43] leading the pack here I think almost [0:45] there might be one or two older in the [0:47] room but not many this is me still me [1:05] family my parents on the dogsled it's a [1:11] pretty crazy place to grow up this was [1:12] the house that's the view in the summer [1:18] time of the house and the backyard and [1:22] front yard I guess me hacking more [1:32] hacking getting older still living in [1:34] northern Greenland very very crazy place [1:37] so this is before the 25 year starts but [1:40] there's a sort of the getting there then [1:43] in the 80s started hacking on actual [1:45] computers although not sure you can call [1:48] this a real computer and had us out it [1:50] had 1024 bytes of memory 1k native that [1:55] big box on the back was a 16 K memory [1:57] expansion crazy completely crazy [2:00] compared to what my son has today to [2:03] play with and hack on it's nuts like 20 [2:08] modems does that know them I mean this [2:11] was me growing up this was my internet [2:13] if you will there was nothing 80s or 90s [2:17] we started getting closer with gopher [2:19] when I was in the university I used [2:21] gopher reading research papers at the [2:24] bottom of the research papers you could [2:25] scroll down with the cursor keys and [2:27] click on links to other research papers [2:30] that was as close to the web as I ever [2:32] saw in university after I graduated [2:37] University in October 1994 mosaic was [2:42] released first graphical web browser and [2:44] here the 25 year counter starts for me [2:49] this changed everything right and not [2:53] just for me for everybody and it wasn't [2:55] just me that could see that this would [2:57] change things everybody around at the [2:58] time playing with this stuff and having [3:02] had uucp addresses and playing with [3:04] Usenet and bulletin boards it was very [3:08] easy to see that this was going to [3:09] change the world so I started hacking on [3:11] this stuff right away the web looked [3:15] like this CGI pins written in C not a [3:19] pretty sight and not something you'd [3:21] want to maintain having HTML inside your [3:25] C programs was not a nice thing to have [3:31] lots of people starting using CGI p.m. [3:35] Perl module for writing CGI programs and [3:39] I didn't like this any better still [3:43] programming your HTML in some other [3:46] language which to me made it impossible [3:50] to separate the business logic from the [3:52] templating and the look and feel the [3:54] layout of the page and I wanted those [3:56] two separate which people especially saw [4:00] that the non PHP types tend to chuckle [4:02] at because PHP is quite well known for [4:04] mushing it all together that wasn't the [4:07] original intent my intent was to have [4:11] very very simple templating so that's [4:14] the same example written in Perl and [4:16] then C here would look look like this in [4:19] the PHP template link system right it [4:23] looks like HTML with just a few tags [4:25] here and there we need the dynamic [4:27] content from the form submit [4:32] my grand scheme was to write a capi for [4:36] the web so abstract away all the web [4:39] specific things that you needed to know [4:42] to get your business logic up online and [4:48] the idea was that you would create these [4:51] template tags you would add your tags to [4:55] the templating system by writing small C [4:57] functions so here's an example of like a [5:00] cosine function that you might want to [5:02] add it was stack based so the tag would [5:07] pass with the the templating system [5:09] would read this find this tag and see a [5:11] okay this is tag name Coast there's an [5:14] argument input it would pop D I'll push [5:17] the input argument on to the stack in [5:19] the C code we pop off and the arguments [5:22] from the stack call whatever function [5:26] and then push the result back on to the [5:28] stack and that's how it would work and [5:29] you wouldn't need to know anything about [5:32] how to parse cookies or HTTP requests [5:34] get method variables post variables all [5:36] that stuff was taken care of for you all [5:38] you had to do was write so the core [5:41] piece of your business logic in C and [5:43] then expose that business logic to your [5:46] template existant much like you do and [5:49] things like smarty and things where you [5:51] assign values to variables and expose [5:53] that to a templates except you were [5:54] assigning it from C and this is how I [5:58] like to solve the web problem back then [6:00] and I did figure other people might like [6:03] to solve it this way too I was [6:06] completely wrong nobody wanted to write [6:09] C code and it was a bit distressing to [6:14] me at the time actually I was trying to [6:17] convince people people would email me [6:20] and they would say this PHP thing is [6:23] cool you have all these tags built in [6:25] and I included a whole bunch of demo [6:28] applications and tags and things and [6:31] they would say well we need and we also [6:34] need a tag that does this we can't [6:36] figure out how to do this I would stroke [6:37] this so easy this is the C code to do [6:39] that and they would say thank you and [6:41] then so now we need this one we can't [6:44] figure how to do this one [6:45] I would do it and they would they would [6:46] trick me into building their site [6:47] basically and it just kept going and [6:50] going and then people started asking for [6:53] more and more logic in the templating [6:56] system so recursion things like that [7:00] that I didn't really see any need for in [7:02] a templating system and I wasn't all [7:07] that good at writing a language parser I [7:10] mean the templating system was pretty [7:11] simple it was just a state machine [7:12] you're either inside the template tag or [7:14] you weren't and it was very very simple [7:18] in the beginning you couldn't do math [7:20] you couldn't do anything in the template [7:22] system but people starting asking for [7:23] stuff like that like just math itself [7:25] it's really really hard if you're [7:29] programming it right because I was [7:31] parsing it I was wasn't using yak or [7:33] lakhs or anything I was just parsing it [7:35] left to right and you get one plus two [7:38] times three you can't do that [7:41] left-to-right you get the wrong answer [7:43] okay you have to do the multiplication [7:45] before the addition and the whole thing [7:47] just kind of gets really complicated [7:48] really really quickly when you're just [7:51] trying to build a state machine in your [7:52] head that parses an entire language but [7:58] it was very obvious that people [8:00] preferred just working in the template [8:02] existence and I shifted the focus [8:05] completely away from necessarily I mean [8:09] I got the language working I read a book [8:11] on yak yak and Lex and kind of figured [8:15] out how to build a somewhat usable [8:18] parser work with offload like the math [8:21] handling yak and Lex could take care of [8:23] all that for me for the most part so I [8:25] got a parser that kind of sorta worked [8:28] okay and then I worked a lot on the [8:31] ecosystem in the early days making sure [8:35] that all the different pieces could talk [8:36] to each other because really what you [8:38] need you need a robust system where you [8:43] can talk to all the different things [8:45] that you need to talk to you don't [8:47] necessarily need a beautiful language to [8:50] program in you can have them best [8:53] language in the world and if it doesn't [8:55] talk to your oracle database where all [8:56] your data is [8:58] there's absolutely no point right and [9:02] that's really what I focused on I [9:04] focused on making sure that the four [9:06] pieces that are critical so a pipe web [9:09] application would work well together so [9:11] an operating system a web server [9:13] scripting language and some kind of [9:17] back-end datastore a shared datastore [9:20] and it really wasn't an accident lamb [9:23] came around and it wasn't just me I mean [9:24] I I got the ball rolling but there were [9:26] lots of people that helped out in [9:28] getting the whole ecosystem running well [9:32] and some of the things over the years [9:35] like initially mod PHP was the big one [9:38] embedding PHP into Apache was huge [9:42] because other languages especially back [9:45] then were faster and better but they all [9:48] ran as CG is Perl was way faster than [9:52] the early PHP but not once you embed PHP [9:57] into Apache by the time used fork and [10:00] exec a Perl process and wait for the [10:02] interpreter to fire up on every single [10:05] request PHP was already done the fact [10:08] that by the time Perl got started it was [10:10] really fast didn't help them because [10:12] their overhead were so high [10:14] being CGI it took them a couple years [10:18] but the mod Perl eventually came around [10:20] they figured out hey we need to do this [10:21] - we need to embed Perl into Apache and [10:25] they completely messed it up because [10:28] they made it way too powerful I only [10:32] hooked the content generation hook in [10:34] Apache which is when the patchy has [10:37] figured out where's the document route [10:38] and where's the script and everything [10:39] then it would call PHP and say okay for [10:43] this particular file the handler is PHP [10:45] run PHP and send the content back with [10:49] mod Perl you could hook all the [10:52] different request hooks in Apache [10:54] including the path translation hook [10:57] which is the hook that says for this [10:59] particular request [11:00] this is the document route that meant [11:03] that if you are on the Virtual host on [11:06] an Apache server and you had mala [11:08] parallax's you could steal the request [11:10] from every [11:11] the virtual host if he wanted to simply [11:13] by hooking the path translate hook and [11:15] pointing everything to your document [11:16] route and that meant that ISPs could not [11:21] offer mod Perl as a shared virtual host [11:25] alongside other clients in a single [11:29] Apache instance so if you came to a nice [11:32] piece that I would like mod Perl they [11:35] would say okay that'll be six hundred [11:37] dollars a month because back then we [11:39] also didn't have VMs containers anything [11:41] like that so you had to have a separate [11:44] physical bare metal box for more mod [11:46] Perl whereas on PHP you could put three [11:50] thousand customers on one machine versus [11:54] one mod Perl customer so it died ISPs I [12:00] mean ISPs would offer it but nobody [12:02] would want to pay a hundred times more [12:05] for Perl verses PHP I also pushed really [12:11] hard for a long time in the beginning [12:13] for the whole concept of a shared [12:15] nothing perfect sandbox model where we [12:18] fire everything up and take tear [12:22] everything down after request no state [12:25] is stored in PHP server side if there is [12:29] any sort of state on a per machine basis [12:32] that's something that you did as [12:34] application developers and also [12:38] multi-threading I've always been firmly [12:41] against any sort of multi-threading [12:43] because it just gets too complicated we [12:46] as humans are not smart enough to write [12:48] complex multi thread safe code and when [12:52] you link in dozens and dozens and dozens [12:54] of third-party libraries and expect them [12:56] all to be thread safe there's just no [12:58] way if the scope is limited enough you [13:02] can write thread safe code but for [13:04] something like a general purpose glue [13:06] language like PHP there's just [13:08] absolutely no way you can get that right [13:09] and also if you have multiple threads if [13:15] one screws up which it will it will take [13:18] down all the other concurrent threads [13:21] even today 25 years later at Etsy [13:25] where I work we run PHP and every now [13:28] and then there's a segfault it's rare [13:30] maybe one or two a week and I have no [13:33] idea why they happen but I don't really [13:35] care it's like once a one every three [13:38] billion requests will cause a segfault [13:41] and the pachi just says okay we'll start [13:43] another child who cares we move on [13:46] that makes it robust if we're in a [13:50] multi-threaded server and one child dies [13:53] or causes any sort of memory corruption [13:55] that entire group of concurrent [13:59] connections are gonna die as well which [14:01] is not a good thing h/h VM stepped into [14:05] that one as well because they they do [14:08] multi-threaded concurrent requests model [14:15] are the things I worked on in the sort [14:18] of the ecosystem bucket was the SQL [14:21] lipid clause because I was using a [14:25] database called M SQL this was pre MySQL [14:29] 1990 late 94 95 or so I was using mini [14:34] SQL super smart guy named David Hughes [14:37] in Australia had written this tiny [14:39] little database that was perfect for the [14:42] web its SQL was quite limited it didn't [14:47] have I don't think it even had joins [14:50] back in the early days but just as a [14:53] very simple datastore that was perfect [14:57] for simple web SQL queries it was [15:00] awesome but it had no way of limiting [15:02] the number of results you got back from [15:05] a query so if you made the fatal mistake [15:07] of doing a select star on a table that [15:09] had a couple hundred thousand rows in it [15:12] and because we didn't have any sort of [15:15] 10-gig [15:15] network cards back then you were waiting [15:17] for awhile for that entire result set to [15:20] come across and if you only need it the [15:22] first one it's really sucked waiting for [15:26] 400,000 rows and then just showing the [15:29] first one right so it was super obvious [15:31] to add some kind of limiter to these SQL [15:34] queries so I arbitrarily [15:38] the limit and patched it in got it [15:40] accepted upstream in the thing and that [15:44] has caused limit now to propagate [15:47] through many many databases I find kind [15:50] of interesting and it's not standard at [15:52] all there's an ansi SQL standard there's [15:55] no sign of limit in the in the standard [15:57] still also on the isp side like maximum [16:03] execution time memory limit and safe [16:06] mode helped ISPs feel a little bit [16:09] better about offering PHP because they [16:11] could say well even if you write a while [16:13] true PHP script that kind of hurts the [16:17] server but because there's maximum [16:19] execution time with just CPU time based [16:22] after that menu CPU seconds it'll just [16:25] get killed off so it was somewhat ok for [16:29] an isp to put thousands of PHP users on [16:32] the same server still not ideal but in [16:36] the early days of the web it was very [16:37] sort of Wild West you kind of hope for [16:41] the best that would just about [16:43] everything you were doing some of the [16:47] things over the years that people keep [16:49] asking me about I case-insensitive [16:52] function names it doesn't make a whole [16:57] lot of sense today but for all of these [17:00] decisions you have to take the context [17:02] in mind this is from 25 years ago this [17:06] one when the web first started there was [17:09] a huge religious battle on whether HTML [17:11] tags should be upper case lower case or [17:13] even mixed case because my templating [17:17] system wanted to fit in this world and I [17:20] didn't want to take sides I wanted [17:23] everybody no matter what their religion [17:24] was to be able to use PHP templates [17:26] these tags which were essentially just [17:29] function names in the early days there [17:32] was no point making them case sensitive [17:34] because then people would complain that [17:36] they couldn't fit into their style that [17:38] they were used to in their HTML and that [17:40] has just stuck now in HTML when [17:44] everybody did finally sort of get to [17:47] lowercase [17:49] I probably should have switched it but I [17:52] remember thinking about doing it [17:55] 97 maybe 96 and I remember thinking this [17:59] will affect hundreds of sites oh man I [18:03] can't [18:03] inconvenience hundreds of sites looking [18:07] back now like I should have [18:09] inconvenienced a couple of hundred sites [18:11] at the time but I had no idea I had [18:15] absolutely no idea I figured at every [18:18] sort of at every point along the way I [18:20] figured there was about six months of [18:22] life left in PHP because that's about [18:25] the amount of time I thought it would [18:26] take for somebody to write something [18:28] real that could replace it but that also [18:31] would work for me [18:32] and I kept waiting for something to come [18:34] along that I could use that would work [18:36] for me and nothing did idiots came out [18:40] with stuff like cold fusion and another [18:42] thing is I looked at God what the hell [18:44] this isn't how you solve the web problem [18:46] and then and cold fusion became popular [18:49] even like wow this is this is just a [18:52] weird world we're in I guess I'm stuck [18:54] with this naming inconsistencies there [18:59] aren't actually any the naming in PHP is [19:02] perfectly consistent just not the way [19:05] you expect dollar signs people have [19:12] complained a bit I even have people [19:14] saying why dollar this is very American [19:16] centric come on [19:22] Global's this is actually one of the [19:26] better decisions I think very few [19:28] languages do it this I'm not sure any [19:30] languages actually handle Global's the [19:32] way PHP does this came out of a huge [19:36] debugging debacle I had pre PHP I was at [19:41] a company called Nortel in Toronto as a [19:45] co-op student and I was given the task [19:48] of tracking down a really complicated [19:52] bug that would take down this automatic [19:54] call distribution system every couple of [19:57] months this was a system that would [19:58] distribute calls geographically across [20:00] Canada for for the [20:02] main customers Air Canada so if people [20:05] called in after hours on the East Coast [20:06] the calls would get routed to support [20:09] people Manning the phones on the West [20:11] Coast because it was three hours earlier [20:12] out there so they had these queues you [20:16] sit there on hold waiting in these call [20:18] queues and every couple of months the [20:21] system would just drop every call out of [20:23] the queue which Air Canada was quite [20:25] unhappy about understandably but nobody [20:30] could figure out why every couple of [20:32] months this would happen [20:34] they tried finding it for years and it [20:38] just they didn't see it [20:41] so that was my task as a co-op student [20:43] and it was kind of a joke there was a [20:45] fix this like good luck they didn't [20:49] think I would get anywhere they figured [20:50] I would learn the system from trying to [20:52] track it down but anyway I printed out [20:54] the source code on this huge wide the [20:57] white dot matrix pages we had back then [21:00] taped it to the walls of all the [21:02] hallways in northern telecom there and [21:04] at after-hours I always put on the floor [21:07] and I would have these highlighters [21:09] different colored highlighters and I'd [21:11] be crawling around on the floor and on [21:12] the walls I thought sure I could stand [21:14] on to reach the higher things and I [21:16] would just sort of manually debug [21:18] everything and try to track down the [21:20] flow of this thing and it was nasty and [21:23] in the end after three and a half months [21:25] it turned out to be a global variable [21:27] collision two separate pieces of the [21:31] code and completely unrelated had the [21:33] same name for a variable and it was [21:36] global changed in one place at exactly [21:38] the wrong time would cause this other [21:41] code to go crazy [21:42] and the C compiler at the time had no [21:46] way of informing us that that was [21:47] happening and it was just crazy and then [21:52] I started adding variables and scope to [21:54] PHP I remembered that there's no way [21:56] that in PHP I'm gonna be spending three [21:59] and a half months tracking down [22:00] something like this that's [22:02] so in PHP if you were kind of step on [22:05] the global you have to damn well declare [22:07] the fact inside the method or a function [22:09] that you're going to step on the global [22:11] so you have the dollar Global's array [22:13] with a huge capital letters this is a [22:15] global or [22:16] have to declare this all the function [22:17] global right so you can't accidentally [22:19] step on the global in PHP let's change a [22:24] little bit now with the Auto capturing [22:26] of the arrow functions that's coming [22:28] which worries me a little bit the first [22:31] time a bug appears because of auto [22:34] capturing and arrow functions I'm gonna [22:36] go kick Nikita register Global's without [22:44] register Global's we wouldn't be here [22:46] honestly [22:47] register Global's enabled users who had [22:51] no idea how the web worked to build [22:54] dynamic pages to put up an HTML form [22:57] name age address as the field names and [23:03] then add a tags that just said echo name [23:07] or if age is greater than 19 without [23:10] thinking about anything the fact that [23:12] field names became variable names in PHP [23:15] was the killer feature in the early days [23:18] of the web where people didn't even have [23:20] to think about how it worked it just [23:22] worked also context there was no Java [23:27] Script you couldn't do cross side [23:30] scripting you couldn't do any of the [23:31] things that in later years you could do [23:36] with register Global's turned on magic [23:42] quotes magic quotes was me being lazy [23:45] I admit that one this was not a good [23:47] solution but it took me a while to [23:50] discover that I should probably be [23:51] careful about letting user data into SQL [23:54] queries I had already written this big [23:56] system for the University of Toronto and [23:59] I had dozens of PHP files and say ah man [24:03] I have to go through and then filter all [24:04] my SQL stuff and all my input data [24:07] forget it I'll just do it once and I'll [24:09] turn on the flag turn on magic quotes [24:12] and have PHP do it for me because I was [24:14] too lazy to edit my my files so yeah [24:17] that's I don't have a good excuse for [24:19] that one other than laziness but it also [24:21] comes back to my six month thing I [24:23] always thought I was six months away [24:24] from the end of life of PHP right this [24:27] was a tool primarily for me [24:29] other people started using but whatever [24:31] I mean once that new thing came along [24:34] that fixes all the problems we would all [24:37] switch to that I could never have [24:39] imagined I'd still be talking about this [24:41] thing 25 years later so on the [24:46] consistency thing on saying that hey [24:49] it's perfectly consistent do you realize [24:53] that every single array function is [24:54] needle haystack and every single string [24:57] function is haystack Neil perfect [25:00] consistency right so the consistency in [25:03] PHP is vertical not horizontal because [25:07] of the way it grew organically right so [25:10] different people wrote the various [25:13] extensions so when you're talking to the [25:15] Oracle database using OCI 8 the [25:18] functions that talk to Oracle from PHP [25:20] are almost a one-to-one mapping of the [25:23] underlying C library functions or the [25:25] API functions provided by Oracle same [25:28] with the MySQL functions and the other [25:29] database functions and they all across [25:32] PHP even the string functions are direct [25:34] one-to-one mapping of Lib C functions [25:36] right so the argument order and the [25:39] names come from the underlying libraries [25:42] that were wrapping where PHP is a very [25:44] thin wrapper basically just exposing [25:47] these C libraries directly to you [25:50] getting horizontal consistency across a [25:54] diverse set of underlying libraries [25:57] would have taken a hell a lot of [26:00] planning and organizing and sort of [26:03] predicting the future the web was moving [26:07] so fast there's just no way that that [26:10] would happen we needed a tool right here [26:13] and now the web was growing like that [26:15] and if I had sat around worrying about [26:20] horizontal consistency we also wouldn't [26:23] be here today [26:27] all right a little bit more current [26:30] stuff 73 hopefully everyone in this room [26:32] have at least looked at 73 [26:36] hopefully you're in the middle of [26:37] migrating everything into 73 does anyone [26:41] in here still running php5 [26:48] you're killing me man I was expecting [26:54] maybe one or two hands to go up but the [26:57] whole back of the room lit up okay [27:01] anyway so in 73 also in seven zero for [27:04] you folks in 71 and 72 there are some [27:06] nice cool new features but in 73 we've [27:09] made hair Doc's look a little nicer [27:11] because the ending tag doesn't have to [27:13] be on the in the left column so whatever [27:16] that's indented by is the same [27:18] indentation you'll see in the output so [27:20] if it's in four spaces then four spaces [27:22] will be removed from the content [27:25] continue in switch continue is probably [27:29] wrong if it's a continue inside the [27:31] switch that's inside the loop people [27:34] might expect that that continue will [27:35] continue the loop it doesn't it acts [27:38] just like a break when you do a continue [27:40] in the switch so PHP seven three has a [27:42] warning that says this should probably [27:45] be a continued to it either should be a [27:47] break or continue to so if you see these [27:51] and the and you did mean a break here [27:53] then just change it to a damn break list [27:58] references both the long stint X in the [28:00] shorts to detects now support references [28:04] trailing comma allowed in function calls [28:07] now we had kind of forgotten that and [28:10] there in 72 we added [28:12] trailing commas support to most things [28:13] but we didn't add it to this one it's [28:17] also a new monotonic timer function if [28:19] you're doing any sort of timing in your [28:20] PHP scripts currently 373 you're going [28:25] to be relying probably on micro time to [28:28] do this timing which is pretty broken [28:31] because micro time relies on the system [28:34] clock if you have ntpd running ntpd can [28:39] speed up slow down stop even make your [28:42] clock go backwards why actually I don't [28:44] think antipathy you can could make it go [28:45] backwards but it can make it stop for a [28:46] little while your system administrator [28:48] can arbitrarily change the system clock [28:50] and make it go backwards so if you're [28:53] timing something and your end time is [28:56] before your start time things get weird [28:59] right and all just the fact that ntpd [29:03] can slow down the clock a little bit [29:05] just to sync it with the NCPD time also [29:09] means that your timing is not gonna be [29:11] right the monotonic timer function will [29:15] always click forward one second per [29:17] second and this is really what you [29:19] should be using to time things there's a [29:25] cool new fpm get status function so you [29:28] can write very pretty dashboards [29:31] kind of like the apache scoreboard where [29:34] you can see what each request is doing [29:35] you know in apache you can do like a [29:37] status slash status and get the [29:39] scoreboard you can now write something [29:41] similar if you're running fpm it's [29:47] countable one of the big changes in PHP [29:49] 7 - that makes upgrading really really [29:54] difficult sometimes is that count [29:56] complains if it's called on things that [30:00] aren't countable so if it's not an array [30:01] or not an object that implements the [30:04] countable interface it complains we saw [30:09] that a lot of people were calling is [30:11] array or instance of countable to try to [30:14] figure out if foo is countable now your [30:17] code you really should know what type of [30:20] variable you might be dealing with here [30:23] but that's not really the PHP way in PHP [30:27] you never know what the hell is in a [30:28] variable because you've written code [30:30] when you have methods that can return [30:32] six different types based on all kinds [30:35] of different things and so you don't [30:38] know so you have to check can I actually [30:40] count this so there's a newest countable [30:45] function in PHP 73 that just reduces [30:48] this boilerplate to something a little [30:50] less [30:54] also to avoid the reset usage like [30:58] people will call reset to get the first [31:01] key of an associative array and that [31:05] also moves the array pointer which means [31:07] that you can't call it on something that [31:10] doesn't have storage you've probably [31:12] tried to do like a reset on a function [31:14] call that returns an array and you end [31:16] up getting an error right with a Reiki [31:19] first nor a key last you can now get the [31:21] first and last keys very quickly without [31:23] any side effects there's a whole bunch [31:28] of cool DCE and sccp optimizations in in [31:33] 73 which I'll talk about in a bit some [31:36] other changes the big one here from a [31:41] sort of a stuff that will break your [31:43] code is the pcre to upgrade it should be [31:49] rare [31:49] the main difference well there are [31:51] actually quite a few differences between [31:52] 1 and 2 but in pcre - the main one that [31:56] you will likely hit are invalid [31:59] character classes you know how you in [32:01] character class you have sort of in [32:02] square brackets a - Zed for example and [32:06] that means all the letters from a does [32:08] that if you have a - backslash S so a - [32:17] whitespace what does that mean who knows [32:21] and in peace fury 1 it says we don't [32:23] know what this is so that - in the [32:25] middle must mean a literal so this is a [32:28] a - and white space in pcre 1 which [32:32] makes some sense right because it's in [32:34] an invalid character class so it's not [32:36] actually going to be a class it's not [32:39] going to be arranged in pcre - I've said [32:43] while you try to build a range this is [32:45] an invalid range this is an error and it [32:48] won't compile the regular expression for [32:49] you and you'll see a big warning in your [32:51] error log if you have a look at your [32:53] error log which I don't think many [32:54] people do you'll see a big warning [32:57] unable to compile regular expression and [32:59] your code will break the count thing in [33:03] 72 is [33:05] noise in the errorlog it actually still [33:07] returns the same value so it doesn't [33:09] break your application this one breaks [33:11] your application because it won't [33:12] compile the records and that wreckage [33:14] will not do anything right so when you [33:18] do the upgrade 273 make sure you scan [33:21] your error log and your unit tests and [33:23] everything for invalid or errors from [33:26] pcre saying it couldn't compile your [33:28] regular expression and most of the time [33:30] all you have to do is go in and add a [33:32] back slash in front of that - to make it [33:36] a literal because that's how it worked [33:39] before in PCR 81 it was treated as a [33:41] literal - if you had a back slash to it [33:44] it'll be valid in both PCR you want in [33:47] PC or you to and it'll do the same thing [33:50] read the migration document if you have [33:53] extensions read the upgrading internals [33:56] document that helps you figure out what [33:58] you need to fix in your extensions for [34:01] the folks still on PHP 5 you know a lot [34:04] of these to read right so there's [34:06] migration 7 0 71 72 73 if you wait a few [34:12] more months you'll have another one to [34:13] read 74 it gets harder and harder the [34:17] longer you wait alright 73 Dimitri in [34:24] Saint Petersburg has been having lots of [34:26] fun with DCE escape analysis nests CCP [34:29] sparse conditional constant propagation [34:31] sounds very complicated but it's [34:33] actually not complicated at all it's [34:35] kind of fun you can dump up codes after [34:40] the optimization pass with a tricky [34:44] little set of settings like this our [34:46] cache optimization level - once to turn [34:49] on all the bits and set it to hex to [34:52] 20,000 it'll spit out the opcodes after [34:58] the optimization run and you will see [35:00] for a simple script like this that just [35:01] has a function and because of the [35:04] Global's and PHP this is a local [35:06] variable there can be absolutely no side [35:07] effect from setting a equals 1 and since [35:10] we don't use dollar a in anywhere and [35:11] just return 0 this is useless this [35:15] assignment serves no purpose whatsoever [35:16] in PHP [35:18] one and earlier we still create the [35:22] opcodes for it so we have the assign [35:23] opcode that assigns one $2 a and we [35:26] return 0 7 2 & 7 3 [35:29] the optimizer sees this as being [35:31] redundant and doesn't even generate the [35:34] opcodes which means they don't get [35:36] cached in our cache and that's really [35:38] where you're executing from [35:39] so essentially it's just deleting that [35:41] line of code and that never gets run [35:43] which also means your code runs slightly [35:45] faster because there's one less off code [35:46] to step through more complicated things [35:52] so here are the CB lines it's basically [35:55] just saying where the inputs the input [35:57] arguments are stored these aren't like [36:00] executable RF codes is just saying these [36:01] are stored in these four places then [36:06] seven one will happily concatenate do [36:09] the concatenation s1 and s2 s3 and s4 [36:11] and then they concatenate there's result [36:14] together here t6 and t7 get concatenated [36:17] together so now we have the final dollar [36:19] X then we overwrite dollar X probably [36:23] right t5 to X then we overwrite it with [36:24] 0 and we return X 72 and 73 see through [36:30] all this mess and see that hey all this [36:33] concatenation gets overwritten in the [36:34] very next line plus X is always 0 so we [36:38] don't even need X right so it replaces [36:41] all this mess just with a return 0 [36:43] opcode no come Katz no creating a [36:47] variable X nothing that stuff never [36:49] happened and try the trick it stuff like [36:53] this it figures it out still so here [36:57] we're only in committing a we're also [36:58] setting B so that result but we're since [37:00] we don't use it the B part gets [37:03] eliminated in 7 3 it has gotten smarter [37:10] with array stuff so in 7 - it couldn't [37:13] figure out arrays like this more and [37:17] also objects so in 7 3 it looks up one [37:23] level to see off to test for side [37:25] effects so if you instantiate an object [37:26] like this if there's no whole destructor [37:29] and no constructor [37:31] then there's absolutely no side effect [37:33] possible from a instantiating dollar a [37:35] hear and even setting a property [37:38] there's no setter up here either so the [37:42] opcodes just removes everything and it [37:45] just returns X if in that same example [37:51] we added the structure now you can see [37:54] that it did not remove those opcodes [37:56] anymore because now there could possibly [37:58] be a side effect once dollar a fall saw [38:02] the scope and this structure is called [38:03] there could be a side effect there even [38:06] though in this case the structure is [38:08] empty it doesn't actually check because [38:11] that would be another level to check it [38:12] doesn't actually check if the [38:14] destructors MSA just checked if it's [38:15] there also it's smart about the raise [38:21] now in 73 so here if you kind of follow [38:25] this it doesn't matter if X is true or [38:26] false e we're only ever returning the [38:30] first element of the array so all this [38:34] stuff gets replaced with just to return [38:37] 0 because the optimizer sees that no [38:39] matter what the input is the output is [38:42] always 0 so everything in between can go [38:46] away since there are no side effects and [38:48] you can delete all that code and you can [38:55] go kind of crazy you have code like this [38:56] right the optimizer tells us that all [39:00] this does is echo one return for you can [39:04] try to try to make your way through it [39:06] and validate the fact that it will [39:08] always only echo one return for that's a [39:13] lot of op codes that have been [39:15] eliminated so like I told and most [39:20] people don't talk too much about how [39:23] much faster your code is under PHP 73 [39:26] because if it's drastically faster under [39:29] 73 you've written code like this right [39:33] it should be 5% maybe 10% faster if you [39:38] stretch it over like 7 1 7 2 it should [39:42] not be like 30 40 % faster [39:45] if it's 30 40 % faster then it's the [39:47] optimizer eliminating all your code [39:49] basically deleting your code and saying [39:51] you're an idiot all this code doesn't [39:54] need to be here right so this is the [39:59] real performance gain you can expect [40:01] from 73 the last bar here right so going [40:06] all the way back to 5/3 this is an [40:09] requests per second 154 requests per [40:11] second for the front page of WordPress [40:13] 498 vs. 520 today for it and latency has [40:20] also been dropping nice the hundred and [40:22] 40 milliseconds using PHP 5/3 down to 38 [40:26] now no seconds on my test box so the [40:29] actual absolute numbers don't matter but [40:31] the the relation does matter right [40:34] things have gotten faster every single [40:36] version we get a little bit faster and [40:40] memory has shrunk quite a bit running on [40:43] 5 3 we need 140 Meg's today we need 15 [40:46] makes to serve up WordPress [40:53] version support this is where we are if [40:56] you're running anything other than PHP [40:57] 72 and 73 you're behind and you need to [41:02] upgrade if you're still running 7-0 [41:07] do you realize PHP 7 was released in [41:10] 2015 an internet on the web that's old [41:14] its old code PHP 7-0 is no longer [41:18] supported in any way whatsoever not even [41:21] security fixes are being done so if [41:24] you're still there and the for the folks [41:25] still running PHP 5 it's just [41:29] irresponsible honestly to be running [41:32] code that old on anything that might be [41:34] important I mean if it's if it's your [41:36] blog or something fine no problem right [41:38] but if it's something that's dealing [41:40] with customer data or anything that is [41:43] actually sensitive you can't be running [41:46] code that's 10 plus years old you can't [41:50] do it [41:53] all right static analysis one of my side [41:58] projects that I started and hand it off [42:01] to someone smarter than me which is sort [42:03] of my pattern I start things and I get [42:07] them going I get in just to the point [42:08] where they're useful enough for someone [42:10] else to continue it as opposed to [42:12] completely starting their own thing [42:16] easy-to-install [42:18] Composer require the fan fan very simple [42:22] config file if you have a standard sort [42:24] of composer set up with a source [42:26] directory in the vendor directory you [42:27] can tell it this is my source directory [42:30] and my vendor directory scan it but [42:33] don't report errors for that one so this [42:35] is the exclude analysis directory list [42:37] so it'll still be part of so that the [42:40] map you could because you need all the [42:41] dependencies you need all the types from [42:43] those because you're calling in to them [42:45] but you don't want to hear about any [42:47] errors in other people's code and then [42:49] you run vendor bin fan if you've never [42:51] done it before you're gonna get hundreds [42:53] if not thousands of errors reported [42:55] about your code you can add some filters [42:59] and say I don't want to know about this [43:02] type of error there's a whole bunch of [43:04] different filters available [43:05] a checks a ton of things these days this [43:10] is just a very small list of things that [43:12] we'll check as a quick example have a [43:16] class like this with a function that [43:18] takes three arguments the first one [43:21] takes either a string or an integer [43:23] called Union here the next one takes an [43:26] array and in the native type in PHP you [43:29] can just say it's an array with fan you [43:32] can give it a more specific type you can [43:33] say this is an integer array and fan [43:36] will check that it's never passed [43:37] something that's not an integer in that [43:39] array and then the last one that's a [43:41] shaped array and that's actually saying [43:43] this array must have a key named mode [43:47] with a value that's a string and the key [43:50] name max with a value that's an integer [43:52] I forget something that doesn't match [43:54] this definition of the function fan will [43:57] complain so here these first three calls [43:59] are okay we have string integer array [44:02] and they're shaped array that matches [44:04] this time we have an integer which is [44:07] fine as well because this is either [44:08] string or int and this one is fine what [44:14] did I even change here doesn't then this [44:19] one is not fine the first argument is an [44:20] array right and that's not part of the [44:25] Union so fan complain saying that the [44:27] argument 1 is an array but the function [44:29] takes integer string [44:31] another example here here are the shaped [44:34] array is missing the mode element so it [44:38] complains about that so these are some [44:40] of the things that you can expect to see [44:42] running fan another tool much newer than [44:48] fan fan is three years old now I think [44:50] four years old maybe lower head [44:54] profiling is a cool new thing that we've [44:58] worked on at Etsy guy named Adam super [45:01] smart guy wrote this thing it's a little [45:03] bit like our bee spy I think there's a [45:06] PI spy as well you run it like this you [45:11] can attach it to any PHP process whether [45:14] it be a PHP fpm whether there's httpd [45:17] with mod PHP so PHP is running its [45:19] htpb doesn't matter or just a standalone [45:21] PHP process and the sampling frequency [45:26] by default is 99 milliseconds I think if [45:31] you don't specify it 99 not a hundred [45:34] because if you set it to exactly a [45:36] hundred there can be some timing issues [45:39] where you happen to exactly miss [45:41] something because things tend to happen [45:44] in hundreds of milliseconds as opposed [45:47] to every 99 milliseconds so by [45:49] offsetting it slightly you're more [45:51] likely to not run into any sort but you [45:53] can also change it yourself [45:54] in this case I've said it to a lot of [45:57] nanoseconds that's 200 milliseconds and [45:59] I'm checking a script that's just [46:01] sleeping for one second so every 200 [46:04] milliseconds I'm asking PHP what are you [46:06] doing what are you doing what are you [46:07] doing what are you doing what do you [46:08] think and it comes back every time with [46:10] a little back trace telling me I'm in [46:13] I'm sleeping and I was called from Maine [46:16] right because this runs for one second [46:18] then we check every 200 milliseconds we [46:20] get five answers and then we get a no [46:24] such process at the end because PHP has [46:26] stopped here's an example of attaching [46:32] to a PHP fpm process that's currently [46:35] serving WordPress and you can see that [46:38] the what are you doing response is a lot [46:41] more complicated now the stack trace is [46:43] much deeper you can also get the memory [46:47] usage from each frame if you pass minus [46:50] m and here if anybody wants a project to [46:55] contribute to it'd be great to have some [46:59] support for perfer call grind or some [47:02] other way of visualizing the memory here [47:04] there will be a nice one too to add [47:07] support for it sits on the to-do list [47:09] just nobody's gotten to that part yet we [47:12] have the numbers the hard part has been [47:14] done we're getting the numbers out of [47:15] every stack frame but we need to [47:16] visualize it somehow for the straight [47:21] what are you doing how much time are you [47:23] spending in places we have output we [47:25] have a flame graph that you can generate [47:27] there are some scripts that come with [47:29] PHP spy one is a stack collapse the [47:31] other is flame graph which are pearls [47:33] craft of all things just kind of cool [47:36] and what you get out of this is a flame [47:38] graph that looks like this so this is me [47:40] running fan sorry running PHP spy on fan [47:46] so if i zoom into some of this I can see [47:49] like here and analyze and get updated [47:53] context calls into this other thing [47:55] which visit statement list which calls [47:58] in to analyze and get updated context [48:00] again and up the tree we can go we can [48:03] follow it all the way up we use this [48:05] thing at Etsy at ton we have a gear man [48:09] pool of servers that handle gear man [48:12] jobs some of these are quite [48:14] long-running we also have servers doing [48:16] cron jobs and again some of these runs [48:18] for quite a while and sometimes they run [48:21] a lot longer than we think they should [48:22] and it's hard to know what the heck [48:25] they're doing because we tried I like on [48:28] our development servers and it never [48:30] runs for more than six minutes or [48:32] something and then in production this [48:33] thing has been running for 40 minutes [48:35] what's it doing right we can't replicate [48:37] it but with PHP spy we can hop on the [48:39] production server attached to the [48:41] running process without slowing it down [48:42] and see what it's doing where is it [48:46] spending its time on PHP spies magic [48:50] because you don't have to compile PHP in [48:52] any sort of special way you don't have [48:54] to have debug symbols you don't have to [48:55] have anything you can have a completely [48:57] stripped optimized GCC - o3 compiled [49:00] binary and it'll still give you this [49:03] output and it does it by simply looking [49:07] at the kernel memory you have to run to [49:09] this route which is it gets a bit of a [49:13] problem for something but it's because [49:16] it needs to look at the kernel basically [49:18] it knows the offsets for the different [49:19] versions of PHP so it knows where the eg [49:22] Global's live for example the executed [49:24] Global's live in memory for PHP 73 right [49:28] that's another certain offset and it [49:30] knows where all these places are so it's [49:32] just looking at memory and seeing what's [49:33] changing it also has an option to spy on [49:37] them variable so you can track you can [49:40] set every ninety nine milliseconds tell [49:42] me the value of this variable and you [49:44] can track how that's changing over time [49:46] so so there's a lot of front-end stuff [49:50] that could be added to this to make it [49:52] even cooler Adam has mostly been [49:55] focusing on the backend part he also [49:57] hates public speaking so if you want a [50:01] project where you can have pretty much a [50:03] guaranteed accepted conference talk for [50:05] come contribute to PHP spy add the cool [50:08] front end support for some of this stuff [50:11] and submit the talk and I guarantee you [50:13] it will be accepted because it's really [50:15] cool and Adams not going to mind he [50:18] would love someone else to talk about [50:20] PHP spy for you for us all right [50:24] peach b7 for coming out leave those here [50:27] type properties yeah if you don't care [50:32] about performance you can find but I [50:34] mean hopefully we'll come up with ways [50:36] of counteracting the performance hit [50:39] that this is gonna take there is some [50:42] obviously this is also why we're not [50:46] gonna do it for standard variables [50:48] because every single time you modify one [50:50] of these we have to have a type check so [50:52] think of a loop in the reader while I [50:55] plus wild dollar I plus plus write this [50:57] thing every time through the loop we're [50:59] modifying the variable for properties [51:01] that's less of a problem presumably [51:04] you're not doing while daughter this I I [51:06] plus plus right hopefully not people [51:11] typically don't make iterators property [51:15] of their classes right so you tend to [51:18] write less to them which is why the [51:19] performance hit on this put on [51:20] properties isn't as big as it would be [51:22] typing regular variables arrow functions [51:28] recently accepted these two are similar [51:33] or identical so you can see why is auto [51:37] captured here from the other scope you [51:40] can have nested arrow functions you can [51:43] also put types in if you wanted to you [51:45] can add a type here you can put colon [51:46] return type as well on it pretty simple [51:54] serialization has always been an issue [51:56] in PHP there are various problems with [51:59] the [52:00] wake up and sleep and wake up things [52:02] magic methods sterilize and unsterilized [52:06] gives you a way of controlling exactly [52:08] how your class is going to be serialized [52:09] and when it uncie realizes how it's [52:11] going to answer allies instead of [52:13] relying on some of the weird side [52:16] effects that you end up with in the [52:17] current mechanism it's a new null [52:21] coalescing assignment operator coming so [52:24] these two are equivalent weak references [52:31] PHP is reference counted which means [52:34] when a variable goes out of scope there [52:37] are no more references to that [52:38] particular piece of memory it gets freed [52:43] in the sense that it's available for for [52:45] reuse within PHP if you have something [52:50] like a cache system or anything where [52:52] you want to you want to avoid stopping [52:57] something from being collected or being [53:00] referenced counted if you have a weak [53:03] reference it doesn't count as a [53:05] reference so they say a equals something [53:07] that comes back from your database for [53:09] example and you in the cache it and you [53:11] said B equals a reference to this and [53:12] now you have a reference count of two [53:14] then you might also have a cache [53:15] reference to it now if both a and B go [53:17] are the scope then this thing should be [53:20] deleted freed but if the cache is still [53:22] referencing it the cache will stop it [53:24] from returning the memory for the system [53:26] the cache should then be rewritten to [53:29] get a weak reference instead then it [53:31] doesn't count so it's only the two main [53:33] references that count and once the two [53:34] main references go away its reference [53:36] counted and it's freed and the weak [53:40] reference dies now the cool new feature [53:46] is our cache pre-loading it basically [53:50] loads the use of space code that start [53:52] up and then any code you have any [53:55] classes any functions it's as if they [53:58] were internal for the rest of the life [54:00] of that PHP instance that makes it [54:05] harder to change that code obviously [54:06] because if you need to make changes to [54:09] ploy a new version then you can't just [54:12] happy [54:13] HP stat it and recompile it because it's [54:16] only looking at this stuff on startup or [54:18] you could force you'd have to do some [54:20] more complicated things to forcibly [54:21] compile its inspired by Jabba's hotspot [54:26] VM and it works like this so if say you [54:29] have code that just has a class a echoes [54:33] out a in a constructor you probably have [54:35] an autoloader and when you do a new a [54:37] the other though the triggers loads in [54:40] that PHP file a dot PHP and the classes [54:45] run constructor runs we get a in the [54:49] preloaded world if in your eye and I you [54:52] have op cash preload point it to a [54:56] script in this case preload dot PHP in [54:58] that PHP script all you have to do is up [55:01] cache compiled file whatever you want to [55:03] preload by whatever logic you want in my [55:06] case I wrote a little preload function [55:08] that I can pass the file names to that I [55:10] want to preload and IAP cache compiled [55:14] file those file names so in this case [55:18] when I run that same script PHP this [55:21] script here with the auto loader you can [55:25] see that when I run it it doesn't say [55:27] that the auto loader was triggered it [55:29] just outputs a because on startup it [55:33] preloads a and that class is registered [55:37] this might seem like a lot of stuff that [55:41] doesn't necessarily give you a whole lot [55:42] of benefit it helps you a little bit [55:45] because even though app cache compiles [55:47] and caches the opcodes [55:49] there still is a little bit more work to [55:50] do to bring those up codes into scope [55:54] and to create the class in this [55:55] particular request for example you can [55:59] have five classes all with the same name [56:01] right in different PHP files and [56:04] depending on whatever context you are [56:06] loading one file over another you pick [56:08] the right class out of op cache and [56:11] create that for that request in the [56:13] preloaded world you can only have one [56:15] class with that name you can't pre those [56:18] two classes with the same name that just [56:20] wouldn't work you will get a [56:21] redefinition error but they're also kind [56:23] of illustrates that there is a little [56:25] bit extra work involved [56:27] if you don't preload something so this [56:29] slightly faster but where it really [56:32] becomes interesting is when combined [56:34] with FFI foreign function interface lets [56:38] you create this FFI object directly from [56:43] an underlying c library in this case [56:46] this example is really simple this is [56:49] just loading in Lib C and defining this [56:54] is base we think of this as a header [56:56] file right so this is a header file you [56:58] know the end that just has the prototype [57:00] for the printf function and we're [57:03] telling it grab this from Lib C dot so6 [57:06] now off of this FF I object you created [57:10] you can now call anything that were [57:12] defined any prototypes that were in that [57:14] header file you now have access to [57:16] directly and you can call directly into [57:18] this C printf are completely useless [57:21] because PHP already has a printf [57:23] function that does exactly that [57:24] basically to test it out I went in [57:28] grabbed a library called gif Inc off a [57:31] github it's a very simple little library [57:34] the header file looked like this the top [57:37] two lines are something I added you can [57:39] ignore those but this is exactly the [57:41] header files to come with the library [57:43] the hello file and it just defines three [57:45] functions nuke if GE nuke fge add frame [57:51] and close gift right so this is a little [57:53] library that creates animated gifts it [57:57] has this somewhat complicated structure [58:00] for the gif Heather number of frames [58:03] color depth things like that to load [58:09] that in because I added these two I set [58:13] a scope and I told it which shared [58:16] library this is in that's the only two [58:20] things I added to the Heather file [58:21] otherwise I just pasted it directly and [58:24] I can just load that header file now and [58:26] it does everything and it compiles the [58:29] code and creates this FFI object and now [58:33] I can just play with the FFI object you [58:36] still need to know a little bit of C you [58:38] need to understand for example [58:40] at this color argument to new gif the [58:43] fourth argument to new gif if we look at [58:46] it here you can see you get the filename [58:48] width and the height these are just long [58:50] so that's easy enough but this one here [58:52] you end eight pointer Oh what is that [58:57] right if you're in the PHP world now [59:00] you're looking at C pointers you kinda [59:03] have to know what that means that this [59:05] is actually an array of you ain't eight [59:07] unsigned integers that you're passing in [59:12] so in this space you have to create this [59:15] array and you can say F F I knew you in [59:17] Tate and I want twelve of them because [59:20] these are the colors that I'm passing in [59:22] and I pass in RGB values for these [59:25] colors then I can call the function for [59:29] these the simple Long's we can we look [59:32] at the the thing we look at these go now [59:35] wrong key you look at these and you have [59:39] to know enough C to know that this is [59:40] just a PHP long will do here and PHP [59:43] long will do here char pointer that's [59:45] just a string just pass a string in this [59:47] case and again integer integer that's [59:50] fine to just pass a PHP integer in here [59:53] this one you have to create separately [59:55] right create that separately do a bit of [59:57] loops add a frame different colors every [60:00] time through close the gif and the [60:02] result is that which is kind of cool but [60:09] pre-loading + FF I it's super [60:12] interesting because this step is deadly [60:15] slow the FF I load you do not want to do [60:18] this on the per request basis but if you [60:22] preload this thing on server startup all [60:25] your F of I blocks are going to get [60:27] compiled and added directly in to PHP as [60:31] if they were an extension I can see a [60:36] whole bunch of our very thin extensions [60:38] that just wrap see libraries I can see [60:42] these being converted to pre loaded FF [60:44] eyes that you can just compose or [60:46] install directly because they're really [60:48] just PHP scripts so they can be managed [60:50] through composer and also all the [60:54] data marshalling like all this other [60:57] stuff is just PHP code right the amount [61:00] of C that's in here is creating that [61:02] header file and then a little bit of [61:04] creating the types maybe that you need a [61:06] C developer for all this other stuff [61:09] people who only know PHP can happily [61:11] maintain the other parts of the [61:13] extension there's only so much that's [61:17] actually needed for these the C part [61:19] right and you need a C developer to get [61:21] the base right but then from then on and [61:23] any little change to that extension can [61:25] be done in PHP managed through Composer [61:29] it'll it'll increase or broaden the the [61:33] users the amount of users that can help [61:36] maintain extensions and I think it can [61:39] kind of change the world for us we'll [61:43] see all right I know I'm pretty much out [61:48] of time but one last little rant so [61:51] these 25 years also included having a [61:55] son 17 years ago me hacking on some PHP [61:58] stuff gain on the ThinkPad Mac's were [62:03] cool back then so I had a sticker I [62:05] never really converted it to the whole [62:08] Mac thing oh yeah little Karl being like [62:13] three days old at that point I think two [62:14] days old maybe a little bit later anyone [62:20] in here remember Linux talk college boy [62:26] yes so Karl would run around he was [62:29] really really good at finding the on/off [62:31] switch on anything he would run from [62:34] booth to booth at this big Linux text [62:36] conference and he would find the off [62:38] switch and turn off these servers which [62:41] didn't I mean he was a cute kid and he [62:44] had his PHP shirt on so they couldn't [62:46] get too upset at him but there were a [62:48] few that were really grumbling because [62:50] he would circle back and do it again and [62:52] again now he's 17 he's driving playing [62:59] video games in the car right it's a [63:02] completely different world that we live [63:04] in now and he has hair down to his [63:06] elbows [63:07] yeah very very different and it's making [63:12] me feel rather old when my son comes and [63:16] picks me up also over these 25 years I [63:20] used to go to Australia every year we [63:23] had some great hacker gatherings this is [63:26] andrew tridgell famous for our sink and [63:29] many other things leanness stalls a [63:32] bunch of other AHS hackers in here you [63:36] can see this was before LCD panels or [63:38] anything right this is this is old old [63:40] school some other highlights for the 25 [63:44] years this is me in India at the [63:47] conference I don't have a suit like that [63:52] these conference organizers thought that [63:55] while there are speakers are so [63:56] important they should be wearing suits [63:58] so they photoshopped me into a suit and [64:03] there are these huge posters all over [64:05] the town of me in this suit looking very [64:08] important I guess and I saw that I know [64:10] what the hell this was another highlight [64:17] this was in Sri Lanka anyone know who [64:21] this might be sitting here you're [64:25] cheating yes arthur c clarke one of the [64:28] saw that yeah you can't see that okay [64:32] you have good eyes [64:34] yes arthur c clarke lived in sri lanka [64:37] for years and years and years he came to [64:39] a PHP conference and said right in the [64:42] front row ask questions completely [64:45] engaged and it was super cool to teach [64:48] PHP to arthur c clarke [64:51] although the really cool thing about [64:53] this particular conference was that this [64:56] was in 2005 in december 2004 there was [65:01] the huge indian ocean earthquake i don't [65:04] know if you remember but there was a [65:05] massive tsunami after that that slammed [65:08] in sri lanka a lot of people died out of [65:13] that came something called Sahana and [65:17] the Sahana project is a disaster relief [65:20] project and I talked to the folks there [65:23] when I was there and talked through some [65:26] of the things that they could do with [65:28] PHP in Sahana and this is one of the [65:34] things that makes me still contribute to [65:38] PHP makes me still feel like it's [65:41] worthwhile even doing some of the things [65:43] when I get slammed with flames and blog [65:48] posts online about all those all the bad [65:51] decisions I've made over the years but [65:55] then I go to Sri Lanka and I see [65:57] something like this kid at the [65:59] University and also a guy working for [66:01] the government there got together and [66:03] built a disaster relief in a box [66:06] management type system where basically [66:08] if relief comes in Plane full of diapers [66:12] comes in someone on the ground will say [66:14] we have diapers they're over in hangar [66:16] number three [66:17] whatever same for whatever else comes in [66:20] so you can keep track of aid coming into [66:22] the country [66:23] you can also there's also people find [66:25] them so this is a very simple front-end [66:27] for the people finder and there's also a [66:28] mobile app now where the rescue worker [66:31] is asked the person their name take them [66:33] to shelter number three and the enter [66:36] that into the mobile app and then you're [66:38] online you check where's my grandmother [66:39] he put the name of your grandmother in [66:41] and it'll tell you yes she's been found [66:43] she's over there right and there are [66:45] seven eight nine different modules like [66:47] that and the the value is that this can [66:51] be spun up in three minutes right this [66:54] is just a package that you spin up super [66:58] super quickly and it has been used now [67:00] in 50 plus disasters around the world [67:05] knowing that PHP has literally probably [67:09] saved someone's life makes all that [67:12] online grief completely irrelevant this [67:17] is a tool PHP is not important what you [67:21] do with it is important if you save [67:23] someone's life with something you've [67:25] built that's awesome arguing about the [67:29] color of the hammer used to build that [67:32] thing [67:33] it's just moronic and all these flames [67:37] about the technologies and stuff we [67:40] can't lose track of what we're doing [67:42] here why we're programming we're [67:44] programming to solve a problem and [67:46] hopefully it's a problem that actually [67:49] matters right it's a very nice quote [67:53] from the second national secretary of [67:55] defense of the Philippines who set that [67:57] right directly targeted as Sahana [68:02] because he saw what Sahana did for a big [68:07] disaster in the Philippines so it was a [68:11] much slight thing back then so work on [68:15] things that matter to you please I see a [68:19] lot of people that have left why there [68:22] are a lot of people I don't see in this [68:23] room and in other conference rooms that [68:25] I go to that were there ten years ago [68:28] but now they're middle managers they're [68:31] not programming anymore they burned out [68:32] they changed jobs and sometimes that [68:35] that's just sort of the progression then [68:37] they make sense for them and there are [68:38] good managers there are also a lot of [68:40] really crappy middle managers out there [68:42] there were great programmers and they [68:44] become crappy managers because they [68:48] don't feel like they can keep up it's [68:50] too much work to keep up with how fast [68:52] technology is moving which is kind of [68:54] code for that they've lost interests [68:58] they're not more than they motivated [69:00] enough to actually sit and read about [69:03] things in evenings they have a families [69:05] now and it takes more time and I [69:06] understand that I have a family but [69:09] there's still this Drive there's this [69:11] passion and motivation that makes me [69:15] continue if you don't have that you will [69:19] burn out and especially the younger [69:21] folks in the room you love programming [69:24] but will you still be programming when [69:26] you're 50 60 70 maybe you don't want to [69:29] and that's fine perfectly fine but if [69:31] you want to if you love what you're [69:33] doing really look at what you're [69:35] actually doing and don't worry that much [69:38] about the tool if you switch tools fine [69:41] it's it's what you built with it that's [69:43] important I'm sure there are all kinds [69:45] of geek arguments about [69:47] paintbrushes what's the best paintbrush [69:49] that painters might have internally [69:52] doesn't matter what people remember are [69:54] the actual paintings right [69:57] who made well I was gonna say [70:02] Michelangelo but that's he's a big PT [70:03] guy right so but I mean who created new [70:08] built Mozart's piano if you're a music [70:10] geek you probably know I mean maybe you [70:12] know but who built the piano isn't as [70:15] important as the actual music that was [70:17] created with it right and that's what [70:21] we're doing we're building things and [70:23] things come out of this I think I am [70:27] squarely in the middle of this chart I [70:29] can code a little bit I'm not a very [70:31] good coder I'm sort of a mediocre coder [70:36] I don't particularly like programming [70:39] I built PHP because it was too [70:41] complicated the tools I had at the time [70:43] just weren't up for the actual task I [70:45] thought it took me too long and was too [70:47] hard and too tedious so in order to [70:50] program less I spent the next next 25 [70:53] years programming something that would [70:56] let me program lasts it made no sense [70:58] but still it did allow me to build [71:02] things along the way that actually [71:04] affected people's lives and that still [71:07] keeps me going and I'm very very [71:09] thankful for the Y's there are a lot of [71:12] Y's that have helped out on the PHP [71:16] project over the years people just love [71:18] to code doesn't really matter what [71:20] they're coding they just sort of love [71:21] the act of coding they love the journey [71:23] they don't really care where they're [71:25] going kind of like flying right I hate [71:28] flying but I spend my life flying I fly [71:31] a lot because I want to get to somewhere [71:35] not because I just like sitting in this [71:37] smelly little tube with a bunch of [71:38] people all right and seamen that there [71:41] are lots of dreamers out there that have [71:42] absolutely no basis in reality to know [71:46] if they can build some of these dreams [71:47] and that you need a little bit of [71:49] grounding to figure out if this grand [71:52] idea you have can actually work all [71:56] right that's my rant and I know I'm over [71:58] time sorry [71:59] conference folks [72:00] so slides are there a couple of things [72:04] thank you [72:06] [Applause] [72:09] [Music]