01 — tags in the page
The document is the program — deploy by uploading a file.
<h1>Crew</h1>
<?php foreach ($crew as $name): ?>
<p><?= htmlspecialchars($name) ?></p>
<?php endforeach; ?>§ 02 — Eras · 1995
code inside the page — the web’s long tail
Left: era context, features, and the 101 hello. Right: 3 core concepts, 3 deeper 201 lessons, the factorial specimen, and where PHP lives today — each column scrolls on its own.
Dynamic pages required CGI gymnastics. PHP made the server-side behavior of a page as easy to write as the page itself.
An stdlib that grew by accretion — inconsistent names, forgiving-by-default behavior, and a security reputation earned early.
Session one is the smallest program that still counts as speaking PHP: what every tutorial prints first, in the dialect that mattered when the language arrived (1995).
<?php
echo "Hello, world";101First contact — hello world and 3 ideas that define how PHP reads. 201 — 3 lessons on mechanisms you meet after the factorial specimen: the sharp edges practitioners actually use.
3 fragments, each naming a habit of mind in PHP. Read the note, then the code — together they are the 101 in one sitting.
01 — tags in the page
The document is the program — deploy by uploading a file.
<h1>Crew</h1>
<?php foreach ($crew as $name): ?>
<p><?= htmlspecialchars($name) ?></p>
<?php endforeach; ?>02 — arrays (and hashtables)
One type — ordered map — does duty for list, dict and tuple.
$wage = ["perch" => 24, "sundial" => 31];
$wage["graymail"] = 12;
foreach ($wage as $k => $v) echo "$k: $v\n";03 — functions & types (modern)
Modern PHP is typed, fast and boring in the best way.
function tally(array $xs): int {
return array_sum($xs);
}The 201 assumes you have read the 101 and the specimen. Each lesson is one mechanism — what it is for, how it looks in code, and the trap or payoff that makes PHP distinctive at scale.
Union types, enums, readonly properties and never — PHP’s type system caught up with the decade, and static analysers can finally rely on it.
enum Port: string {
case Osaka = "osaka";
case Genoa = "genoa";
}
final class Ship {
public function __construct(public readonly string $name) {}
}Attributes put metadata in the source, readable by reflection — the basis for routing, validation and dependency injection without XML.
#[Route("/api/crew", methods: ["GET"])]
public function crew(): array { ... }A generator streams values without materialising an array — the answer to “this query returns a million rows”.
function crew(): Generator {
foreach ($this->rows as $row) {
yield $row['name'] => $row['tons'];
}
}The page template: code inside the document, the document inside the code — the long tail of the web, written between two tags.
<ul>
<?php foreach ($crew as $name): ?>
<li><?= htmlspecialchars($name) ?></li>
<?php endforeach; ?>
</ul>installbrew install php
runphp fact.php
WordPress alone runs ~40% of the web; Laravel is one of the most pleasant frameworks anywhere.