🐘 PHP for Backend Development
PHP is the quiet giant of the web — it runs WordPress, Wikipedia, and a huge chunk of every site you visit. Far from the messy language of its reputation, modern PHP 8 is fast, typed, and genuinely pleasant to write. This lesson gives you a working command of the language so you can build real server-side features.
🎯 Learning Objectives
By the end of this lesson, you will be able to:
- Explain what server-side scripting is and how PHP fits into the request/response cycle
- Write core PHP 8 syntax — variables, control structures, functions, and arrays — correctly
- Build a small object-oriented program using classes, constructors, and inheritance
- Weigh PHP's strengths and trade-offs against Node.js and Python for a given project
- Run a PHP script locally with the built-in web server
Estimated Time: 35–45 minutes • Difficulty: Beginner
Hands-on: Build and run a tiny "greeting" script, then extend it into a small class.
In This Lesson
What Is PHP?
PHP (a recursive acronym for PHP: Hypertext Preprocessor) is an open-source scripting language designed from the ground up for the web. Where a language like Python is general-purpose and later grew web frameworks, PHP was born to generate web pages, and that focus still shows in how naturally it slots into HTML.
It was created by Rasmus Lerdorf in 1994 as a handful of C programs to track visits to his online résumé. Three decades later it powers roughly three-quarters of all websites whose server-side language is known — largely because WordPress alone runs more than 40% of the entire web.
💡 A useful analogy: If HTML is the printed page, PHP is the printing press that stamps out a fresh, personalized page for every visitor — inserting their name, their cart, today's date — before the paper ever reaches them.
📖 Key Terms
Interpreter: the PHP program that reads your .php files and executes the code inside them.
Server-side: code that runs on the web server, before the response is sent — the user never sees it.
Dynamic page: HTML that is generated fresh on each request rather than served from a static file.
PHP's evolution
PHP has improved dramatically. The jump to PHP 7 (2015) roughly doubled performance, and the PHP 8 line (2020 onward) added a JIT compiler, real type declarations, enums, and readonly properties. The syntax you'll learn here targets PHP 8.3+ — the modern, actively supported baseline.
How Server-Side Scripting Works
The single most important thing to understand about PHP is where it runs. When a browser requests a .php page, the web server hands the file to the PHP interpreter, which executes any code and produces plain HTML. Only that finished HTML travels back to the browser — the PHP source never leaves the server.
Because PHP was designed to mix with HTML, you can drop into and out of "PHP mode" using <?php ... ?> tags. Everything outside those tags is sent to the browser untouched:
<!DOCTYPE html>
<html>
<body>
<h1>Welcome!</h1>
<?php
// Only this block is executed by PHP
$hour = (int) date('H');
if ($hour < 12) {
echo '<p>Good morning.</p>';
} elseif ($hour < 18) {
echo '<p>Good afternoon.</p>';
} else {
echo '<p>Good evening.</p>';
}
?>
<p>This is plain HTML again.</p>
</body>
</html>
✅ Modern practice
In real applications you rarely sprinkle PHP throughout HTML like this. Instead you keep logic in .php classes and use a template engine (Twig, Blade) for the HTML. But understanding the embedded model explains why PHP works the way it does.
Core Syntax: Variables & Types
Every PHP variable starts with a $. PHP is dynamically typed — a variable's type is inferred from the value you assign — but modern PHP lets you add explicit type declarations where they matter (we'll see that with functions).
<?php
$name = 'Ada'; // string
$age = 36; // int
$height = 1.7; // float
$isMember = true; // bool
$hobbies = ['reading', 'chess']; // array
$nickname = null; // null
// Double quotes interpolate variables; single quotes do not.
echo "Hi, {$name}. You are {$age}."; // Hi, Ada. You are 36.
echo 'Hi, {$name}.'; // Hi, {$name}. (literal)
// The null coalescing operator supplies a fallback.
$display = $nickname ?? $name; // 'Ada'
⚠️ Single vs. double quotes
This trips up newcomers constantly: only double quotes (and heredocs) expand variables. Use the {$var} brace form inside strings — it's unambiguous and works for array/object access too, e.g. "{$user['name']}".
Type juggling and strict types
PHP will happily convert types for you ("5" + 3 gives 8). That convenience can hide bugs, so professional projects turn on strict typing at the top of each file:
<?php
declare(strict_types=1);
// With strict_types on, passing a string where an int is
// declared throws a TypeError instead of silently converting.
Control Structures & Functions
PHP's control flow reads much like C, JavaScript, or Java — if/elseif/else, switch, and the usual loops. PHP 8 also added match, a stricter, expression-based cousin of switch.
<?php
$score = 82;
// match returns a value and uses strict (===) comparison
$grade = match (true) {
$score >= 90 => 'A',
$score >= 80 => 'B',
$score >= 70 => 'C',
default => 'F',
};
echo $grade; // B
// foreach is the workhorse loop for arrays
$colors = ['red', 'green', 'blue'];
foreach ($colors as $color) {
echo $color . PHP_EOL;
}
// foreach with key => value
$person = ['name' => 'Ada', 'age' => 36];
foreach ($person as $key => $value) {
echo "{$key}: {$value}" . PHP_EOL;
}
Functions with types
Modern PHP functions declare parameter and return types. This is the single biggest quality upgrade over old-style PHP — your editor and static analysers can catch mistakes before the code ever runs.
<?php
declare(strict_types=1);
// Typed parameters and a typed return value
function greet(string $name, string $greeting = 'Hello'): string
{
return "{$greeting}, {$name}!";
}
echo greet('Ada'); // Hello, Ada!
echo greet('Bob', 'Hi'); // Hi, Bob!
// Variadic parameters collect extra arguments into an array
function total(float ...$amounts): float
{
return array_sum($amounts);
}
echo total(1.5, 2.25, 3.0); // 6.75
// Arrow functions (PHP 7.4+) capture outer scope automatically
$prices = [10, 20, 30];
$withTax = array_map(fn ($p) => $p * 1.1, $prices);
Arrays — PHP's Swiss Army Knife
Arrays are everywhere in PHP. A single array type serves as both an ordered list (indexed) and a key/value map (associative), and the standard library ships hundreds of array_* helper functions.
<?php
// Indexed array (a list)
$fruits = ['apple', 'banana', 'orange'];
$fruits[] = 'grape'; // append
echo $fruits[0]; // apple
// Associative array (a map)
$user = [
'name' => 'Ada',
'email' => 'ada@example.com',
];
echo $user['name']; // Ada
// Nested / multidimensional
$users = [
['name' => 'Ada', 'admin' => true],
['name' => 'Bob', 'admin' => false],
];
echo $users[1]['name']; // Bob
// Functional transforms
$numbers = [1, 2, 3, 4, 5];
$doubled = array_map(fn ($n) => $n * 2, $numbers); // [2,4,6,8,10]
$evens = array_filter($numbers, fn ($n) => $n % 2 === 0); // [2,4]
$sum = array_reduce($numbers, fn ($c, $n) => $c + $n, 0); // 15
📖 The spaceship operator
PHP's <=> operator returns -1, 0, or 1 and makes custom sorting concise: usort($users, fn ($a, $b) => $a['name'] <=> $b['name']); sorts users alphabetically by name.
Object-Oriented PHP
Serious PHP is object-oriented. Classes bundle data (properties) with behaviour (methods), and PHP 8 makes classes remarkably compact with constructor property promotion — you declare and assign properties right in the constructor signature.
<?php
declare(strict_types=1);
class Person
{
// Constructor property promotion: declares + assigns in one place
public function __construct(
public string $name,
protected int $age,
private string $email = ''
) {}
public function greet(): string
{
return "Hi, I'm {$this->name}.";
}
public function getAge(): int
{
return $this->age;
}
}
$ada = new Person('Ada', 36, 'ada@example.com');
echo $ada->greet(); // Hi, I'm Ada.
echo $ada->name; // Ada (public)
echo $ada->getAge(); // 36 (age is protected, reached via method)
Inheritance
A child class extends a parent, reusing its code and adding or overriding behaviour. Call the parent constructor with parent::__construct(...).
<?php
class Student extends Person
{
public function __construct(
string $name,
int $age,
public string $studentId = ''
) {
parent::__construct($name, $age);
}
public function card(): string
{
return "{$this->name} (ID: {$this->studentId})";
}
}
$bob = new Student('Bob', 20, 'S-12345');
echo $bob->card(); // Bob (ID: S-12345)
echo $bob->greet(); // Hi, I'm Bob. (inherited)
💡 Visibility at a glance
public — reachable from anywhere. protected — this class and its subclasses. private — this class only. Default to the most restrictive level that still works; expose data through methods.
The Modern PHP Ecosystem
You rarely build PHP applications from scratch. A rich ecosystem of frameworks, tools, and a package manager sits on top of the language:
+ Packagist] PHP --> QA[Quality & Testing] FW --> Laravel[Laravel] FW --> Symfony[Symfony] FW --> Slim[Slim] CMS --> WordPress[WordPress] CMS --> Drupal[Drupal] QA --> PHPUnit[PHPUnit / Pest] QA --> PHPStan[PHPStan]
| Tool | What it does | When you'll meet it |
|---|---|---|
| Composer | Installs and manages library dependencies | Every modern project (next lessons) |
| Laravel | Full-featured web framework: routing, ORM, auth | Most new PHP web apps & APIs |
| Symfony | Reusable components + enterprise framework | Large apps; powers parts of Laravel |
| PHPUnit / Pest | Automated testing | Any codebase you want to trust |
| PHPStan | Static analysis — finds bugs without running code | Team & CI pipelines |
PHP also excels at building JSON APIs. Here's a minimal REST-style endpoint in plain PHP using PDO (the safe, prepared-statement database layer):
<?php
declare(strict_types=1);
header('Content-Type: application/json');
$pdo = new PDO(
'mysql:host=localhost;dbname=app;charset=utf8mb4',
'user',
'pass',
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
// GET /users/42 -> fetch one user, safely (parameterised query)
$id = (int) ($_GET['id'] ?? 0);
$stmt = $pdo->prepare('SELECT id, name, email FROM users WHERE id = ?');
$stmt->execute([$id]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
echo json_encode($user ?: ['error' => 'Not found']);
⚠️ Always use prepared statements
Never build a query by pasting user input into a string — that's how SQL-injection attacks happen. The ? placeholder with execute([$id]) keeps data and code separate. This is non-negotiable in production PHP.
PHP vs. Node.js & Python
No backend language is "best" — each has a sweet spot. Knowing where PHP shines (and where it doesn't) helps you choose well.
| Aspect | PHP | Node.js | Python |
|---|---|---|---|
| Execution model | Request-per-process (shared-nothing) | Single-threaded event loop | Request-per-process (usually) |
| Sweet spot | CMS, e-commerce, web apps & APIs | Real-time apps, sockets, microservices | Data science, ML, scripting, web |
| Hosting | Supported almost everywhere, cheaply | Needs a Node runtime | Widely available |
| HTML integration | Native — the whole point | Via template libraries | Via template engines |
| Concurrency | Handled by the web server per request | Excellent, built in | Improving (async/await) |
✅ Reach for PHP when…
- You're building or extending a CMS/e-commerce site (WordPress, Magento, Drupal).
- You want to ship a database-backed web app or API quickly with Laravel.
- Cheap, universal shared hosting matters.
💡 Consider alternatives when…
You need heavy real-time features (chat, live dashboards) — Node's event loop fits better — or your project is data-science/ML heavy, where Python's ecosystem is unmatched.
Hands-on Exercise
🏋️ From script to class
Objective: Write, run, and then refactor a small piece of PHP — no framework, no database.
Instructions:
- Create a folder and a file
greet.php. - Write a typed function
greet(string $name): stringthat returns"Hello, NAME! Welcome to PHP." - Call it for three different names and
echoeach result on its own line. - Run it from the terminal with PHP's built-in server:
php -S localhost:8000, then openhttp://localhost:8000/greet.php. (Or runphp greet.phpdirectly on the command line.) - Refactor: wrap the behaviour in a
Greeterclass with afor($name)method, and produce the same output.
💡 Hint
Start the file with <?php declare(strict_types=1);. For the class version, use constructor property promotion to store a default greeting, e.g. public function __construct(private string $greeting = 'Hello') {}. Use PHP_EOL for line breaks so output looks right in both the terminal and the browser source.
✅ Sample solution
<?php
declare(strict_types=1);
// --- Function version ---
function greet(string $name): string
{
return "Hello, {$name}! Welcome to PHP." . PHP_EOL;
}
foreach (['Ada', 'Bob', 'Cleo'] as $name) {
echo greet($name);
}
// --- Class version (same output) ---
class Greeter
{
public function __construct(private string $greeting = 'Hello') {}
public function for(string $name): string
{
return "{$this->greeting}, {$name}! Welcome to PHP." . PHP_EOL;
}
}
$greeter = new Greeter();
foreach (['Ada', 'Bob', 'Cleo'] as $name) {
echo $greeter->for($name);
}
Both loops print the same three lines. The class version is easy to extend — change the greeting once in the constructor and every call updates.
🎯 Quick Quiz
Question 1: Where does PHP code execute in the request/response cycle?
Question 2: Which string will interpolate the variable $name?
Question 3: Why should database queries use prepared statements with placeholders?
Summary & Quiz
🎉 Key Takeaways
- PHP is a server-side language built for the web; the browser only ever sees the HTML it generates.
- Modern PHP 8 is fast and typed — use
declare(strict_types=1), typed functions, andmatch. - Arrays serve as both lists and maps, backed by a huge
array_*toolkit. - OOP with constructor property promotion keeps classes concise; respect public/protected/private.
- Always use prepared statements for database access to prevent SQL injection.
- PHP shines for CMS, e-commerce, and database-backed web apps & APIs.
📚 Further Reading
🚀 What's Next?
You can write PHP — now you need somewhere to run it. Next we'll set up a complete PHP development environment: the interpreter, a local server, a database, and an editor tuned for PHP with step-through debugging.
🎉 Great start!
You've got working PHP under your belt. Let's build the workshop you'll write it in.