PHP cheat sheet

A scannable PHP reference: 20 short snippets across 8 topics, each linking back to the lesson it came from.

At a glance

TopicWhat it covers
PHP: getting startedPHP executes on the server and sends the resulting HTML to the browser. The visitor never sees your source — only itslesson
PHP variables and stringsVariables are dynamically typed and prefixed with $. Since PHP 7 you can also declare strict types per file withlesson
PHP arraysOne array type serves both roles because PHP arrays are ordered maps. Iteration preserves insertion orderlesson
Forms, sessions and safetyHandling GET and POST, validating input, keeping sessions, and the defences against the classic web attackslesson
A modern PHP toolchain with ComposerInstall a current PHP, serve it locally, and let Composer handle dependencies, PSR-4 autoloading and the tooling aroundlesson
Modern PHP 8 features in practiceThe pipe passes the left-hand value as the argument of the callable on the right, so a chain reads in execution orderlesson
Composer, dependencies and coding standardsVersion constraints and the lockfile, scripts, autoload optimisation, PSR-12 formatting, PHPStan and Rector in onelesson
Testing, frameworks and deploymentPHPUnit and Pest, unit versus feature tests, a tour of Laravel and Symfony routing, and shipping with OPcache, PHP-FPMlesson

Quick snippets

PHP: getting started

A server-side language

<?php
// everything between these tags runs on the server
$name = "world";
echo "Hello, " . $name;

Mixing PHP and HTML

<!DOCTYPE html>
<html>
<body>
  <h1><?php echo htmlspecialchars($title); ?></h1>
  <ul>
  <?php foreach ($items as $item): ?>
    <li><?= htmlspecialchars($item) ?></li>
  <?php endforeach; ?>
  </ul>
</body>
</html>

Running it

php -v
php -S localhost:8000      # built-in dev server
php script.php             # run a CLI script

Full lesson: PHP: getting started →

PHP variables and strings

Variables

$count = 10;              // no declaration keyword
$price = 19.99;
$label = "cart";
$active = true;
$nothing = null;

echo gettype($count);      // integer
var_dump($count);          // type + value, best for debugging

Strings

$name = "Ada";
echo "Hello $name";            // double quotes interpolate
echo 'Hello $name';            // single quotes do not
echo "Sum: {$arr['total']}";   // braces when the expression is ambiguous

$multi = <<<TEXT
Line one
Line two: $name
TEXT;

echo nl2br(htmlspecialchars($multi));

Loose versus strict comparison

var_dump(0 == "a");     // false in PHP 8 (was true in PHP 7!)
var_dump("1" == "01");  // true  - numeric strings compared numerically
var_dump("10" == "1e1");// true
var_dump(100 == "1e2"); // true

var_dump("1" === 1);    // false - type differs

Full lesson: PHP variables and strings →

PHP arrays

Lists and associative arrays

$list = [1, 2, 3];                      // indexed
$user = ["id" => 7, "name" => "Ada"];   // associative

$list[] = 4;                            // append
echo $user["name"];
echo $list[0] ?? "missing";             // null-coalescing for missing keys

$id = 7;
$h = "id";
echo $user[$h];                         // variable key

Array functions worth knowing

$adults = array_filter($people, fn($p) => $p["age"] >= 18);
$names  = array_map(fn($p) => $p["name"], $adults);
$total  = array_reduce($items, fn($sum, $i) => $sum + $i["price"], 0);

usort($people, fn($a, $b) => $a["age"] <=> $b["age"]);
$ids = array_column($people, "id");

Arrays and JSON

$json = json_encode($user, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
$back = json_decode($json, true);       // true = associative arrays

if (json_last_error() !== JSON_ERROR_NONE) {
    throw new RuntimeException(json_last_error_msg());
}

Full lesson: PHP arrays →

Forms, sessions and safety

Reading request data

$email = filter_input(INPUT_POST, "email", FILTER_VALIDATE_EMAIL);
$page  = filter_input(INPUT_GET, "page", FILTER_VALIDATE_INT, ["options" => ["min_range" => 1]]);

if ($email === null || $email === false) {
    http_response_code(422);
    exit("Invalid email");
}

// never: $email = $_POST["email"]; then use it directly in SQL or HTML

The classic attacks and their fixes

// SQL injection, fixed
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch();

// CSRF token
$_SESSION["csrf"] = bin2hex(random_bytes(32));
// in the form: <input type="hidden" name="csrf" value="<?= $_SESSION['csrf'] ?>">
// on submit:   hash_equals($_SESSION["csrf"], $_POST["csrf"] ?? "")

Full lesson: Forms, sessions and safety →

A modern PHP toolchain with Composer

PHP 8.4 or 8.5, served locally

php -v                                 # aim for 8.4 or 8.5
php -m                                 # extensions actually loaded
php -i | grep "Loaded Configuration"   # which php.ini is in use
php -S localhost:8000 -t public        # built-in server, docroot public/

Composer and PSR-4 autoloading

composer init --name=acme/blog --require=php:^8.4
composer require monolog/monolog:^3         # production dependency
composer require --dev phpunit/phpunit:^11  # development only
composer install                            # installs exactly what composer.lock pins
composer update monolog/monolog             # deliberately move one package forward

Composer and PSR-4 autoloading

<?php
// public/index.php - the single entry point the web server hands requests to
require __DIR__ . '/../vendor/autoload.php';

use Acme\Blog\Post;   // resolves to src/Post.php through the psr-4 rule

$post = new Post();
echo $post->title();

Full lesson: A modern PHP toolchain with Composer →

Modern PHP 8 features in practice

Pipe operator and clone-with

$slug = $title
    |> trim(...)
    |> strtolower(...)
    |> (fn(string $s): string => preg_replace('/[^a-z0-9]+/', '-', $s));

// equivalent without the pipe, read inside out
$slug = preg_replace('/[^a-z0-9]+/', '-', strtolower(trim($title)));

$draft = clone($post, ["status" => Status::Draft, "publishedAt" => null]);

Full lesson: Modern PHP 8 features in practice →

Composer, dependencies and coding standards

Constraints that mean what you think

composer require "monolog/monolog:^3.7"     # >=3.7.0 <4.0.0
composer require "phpunit/phpunit:~11.2"    # >=11.2.0 <11.3.0 (patch-level safety)
composer show monolog/monolog               # installed version and its own requirements
composer why-not php 8.3                    # which package blocks that downgrade
composer outdated --direct
composer audit                              # known security advisories
composer validate --strict

Scripts and autoload performance

{
  "scripts": {
    "test": "phpunit",
    "stan": "phpstan analyse src tests --level=6",
    "lint": "php-cs-fixer fix --dry-run --diff",
    "check": ["@lint", "@stan", "@test"]
  },
  "config": {
    "optimize-autoloader": true,
    "sort-packages": true
  }
}

Scripts and autoload performance

composer check                  # one command a reviewer can trust
composer dump-autoload -o       # build a class map: no filesystem lookups at runtime
composer dump-autoload --classmap-authoritative   # never fall back to scanning
composer dump-autoload --apcu   # cache the map in shared memory when APCu is present

Full lesson: Composer, dependencies and coding standards →

Testing, frameworks and deployment

Unit and feature tests

<?php
// Pest: the same two tests, with closures and expectations
it("slugifies a title", function () {
    expect((new Slugger())->slug("Hello World"))->toBe("hello-world");
});

it("rejects an empty string", function () {
    (new Slugger())->slug("   ");
})->throws(InvalidArgumentException::class);

Shipping it

# a release directory per build, switched with a symlink
composer install --no-dev --optimize-autoloader
php bin/console cache:warmup        # Laravel: php artisan optimize
ln -sfn /srv/releases/2026-09-18-1 /srv/current
systemctl reload php8.5-fpm         # new opcache, zero dropped requests

Full lesson: Testing, frameworks and deployment →

FAQ

Is this PHP cheat sheet free to use?
Yes. No sign-up and no tracking: the page is static, every example is on the page itself, and you can print it or save it as a one-page reference.
Where do the examples come from?
Every snippet is taken from the 8 lessons of the PHP course on this site, and each section links back to the lesson it was pulled from.
How do I go deeper than a cheat sheet?
Open the full PHP course — it carries the worked explanations, the edge cases and the exercises behind every line here.

Node.js Java HTTP Go Rust Spring Boot

Last refreshed 2026-09-27.