Cheat Sheet Library

PHP Cheat Sheet

Server-side language for websites, forms, APIs and databases. This sheet targets PHP 8.4 and marks features that need PHP 8.0 or later.

  • 116 entries
  • 14 sections
  • Updated

116 entries

On this page

Running PHP #

CommandWhat it does
php file.phpRun a script in the terminal
php -S localhost:8000 -t publicBuilt-in web server with public as web root (development only)
php -aInteractive shell
php -l file.phpCheck a file for syntax errors
composer require vendor/packageInstall a package into vendor/ (composer install restores from composer.lock)
require __DIR__ . '/vendor/autoload.php';Load Composer packages in your code

Variables & Types #

CodeWhat it does
<?phpOpening tag; leave out the closing ?> in PHP-only files
<?= $name ?>Short echo tag inside HTML
$name = "Milan";Variables start with $, no declaration needed
echo "Hi", PHP_EOL;Print one or more values (print takes one)
const MAX = 10;Constant (old style: define('MAX', 10))
var_dump($x); / print_r($arr);Show type and value / readable dump of an array
(int) "42"Cast; also (float), (string), (bool), (array)
is_int($x) / is_string($x) / get_debug_type($x)Type checks / type name (PHP 8.0+)
isset($x) / empty($x)Exists and is not null / missing or falsy ("", "0", 0, [], null)
declare(strict_types=1);First statement of a file: wrong scalar types throw TypeError instead of being converted
function f(?string $s): intParameter and return types; ? = nullable
int|float / mixed / neverUnion type / any type (PHP 8.0+) / never returns (PHP 8.1+)

Strings #

CodeWhat it does
'Hi $name\n'Single quotes: literal text, no variables or escapes
"Hi $name\n"Double quotes: variables and escapes are expanded
"Total: {$order['total']}"Braces for array keys, properties and method calls
"a" . "b" / $s .= "c";Concatenate / append
strlen($s) / mb_strlen($s)Length in bytes / in characters (use mb_ for é, ü)
strtoupper($s) / ucfirst($s) / ucwords($s)Uppercase / first letter / each word
trim($s)Strip whitespace from both ends (ltrim, rtrim)
str_contains($s, "x")Contains substring (also str_starts_with, str_ends_with) (PHP 8.0+)
strpos($s, "x")Position of first match, or false
substr($s, 0, 5) / substr($s, -3)Part of a string / last 3 characters
str_replace("a", "b", $s)Replace all occurrences
explode(",", $s) / implode(", ", $arr)Split into an array / join into a string
sprintf("%s: %.2f", $name, $price)Formatted string (printf prints it)
number_format(1234.5, 2, ',', '.')"1.234,50"
<<<HTML ... HTML;Heredoc: multi-line string, works like double quotes
<<<'TXT' ... TXT;Nowdoc: multi-line string, works like single quotes
preg_match('/(\d+)/', $s, $m) / preg_replace('/\s+/', ' ', $s)Regex match (groups in $m) / regex replace

Operators #

CodeWhat it does
=== / !==Same value and type (use these; == juggles types: "1" == "01" is true)
$a <=> $bSpaceship: -1, 0 or 1 (handy for sorting)
$x ?? 'default'Null coalescing: $x if set and not null, else the default
$x ??= []Assign only if $x is null or unset
$user?->address?->cityNullsafe: returns null instead of failing on null (PHP 8.0+)
$a ?: $b$a if truthy, else $b
&& / || / !And / or / not
2 ** 10 / intdiv(7, 2) / 7 % 2Power (1024) / integer division (3) / remainder (1)

Control Flow #

CodeWhat it does
if (...) { } elseif (...) { } else { }Conditions
match ($x) { 1, 2 => 'low', default => 'high' }Returns a value, strict ===, no break; no match throws UnhandledMatchError (PHP 8.0+)
match (true) { $age < 18 => 'minor', default => 'adult' }Match conditions instead of values
switch ($x) { case 1: ...; break; }Older style: loose == comparison, needs break
for ($i = 0; $i < 10; $i++) { } / while (...) { }Counting loop / condition loop (break, continue)
foreach ($items as $key => $value) { }Loop over an array (as $value for values only)
if (...): ... endif;Template syntax (also foreach: ... endforeach;)

Arrays #

CodeWhat it does
$nums = [1, 2, 3]; / $nums[] = 4;Indexed array / append
$user = ['name' => 'Ann', 'age' => 30];Associative array (key => value)
count($arr)Number of elements
in_array(2, $nums, true)Value exists (true = strict comparison)
array_key_exists('age', $user)Key exists, even if its value is null
array_keys($arr) / array_values($arr)All keys / values re-indexed from 0
array_map(fn($n) => $n * 2, $nums)Transform every element
array_filter($nums, fn($n) => $n > 1)Keep matching elements (keeps the original keys)
array_reduce($nums, fn($c, $n) => $c + $n, 0)Reduce to one value (or just array_sum($nums))
array_merge($a, $b) / [...$a, ...$b]Merge; later string keys win (spread with string keys PHP 8.1+)
array_column($rows, 'name', 'id')One column from a list of rows, keyed by id
sort($a) / asort($a) / ksort($a)Sort values (re-indexes) / by value keeping keys / by key
usort($rows, fn($x, $y) => $x['age'] <=> $y['age'])Sort with your own comparison
[$a, $b] = [1, 2]; / ['name' => $name] = $user;Destructure by position / by key
array_find($nums, fn($n) => $n > 2)First matching value or null (also array_any, array_all) (PHP 8.4+)

Functions #

CodeWhat it does
function greet(string $name = "World"): string { }Typed parameter with a default value
greet(name: "Ann")Named arguments, any order, skip optional ones (PHP 8.0+)
function sum(int ...$nums) / sum(...$list)Variadic: extra arguments arrive as an array / unpack an array into arguments
function add(array &$arr)Pass by reference: changes affect the caller's variable
$double = fn($x) => $x * 2;Arrow function; reads outer variables automatically
function ($x) use ($factor) { return $x * $factor; }Closure; use copies outer variables in (use (&$n) by reference)
strlen(...)First-class callable: turns a function into a Closure (PHP 8.1+)
static $calls = 0;Local variable that keeps its value between calls

Classes #

class User
{
    public function __construct(
        public readonly string $name,   // promoted property (8.0+), readonly (8.1+)
        private int $age = 0,
    ) {}

    public function isAdult(): bool { return $this->age >= 18; }
}
$u = new User('Ann', 30);   // $u->name
CodeWhat it does
public / protected / privateVisible everywhere / in the class and children / only in this class
class Admin extends UserInheritance; call the parent with parent::__construct(...)
abstract class Shape / final class CircleCan't be created directly / can't be extended
const VERSION = '1.0';Class constant, read with User::VERSION
public static function create(): staticStatic method: User::create(); inside, use self:: / static::
readonly class PointEvery property is readonly (PHP 8.2+)
new User('Ann')->isAdult()No extra parentheses needed around new (PHP 8.4+)
public private(set) int $balance = 0;Asymmetric visibility: public read, private write (PHP 8.4+)
public string $email { set => strtolower($value); }Property hook runs on every write (PHP 8.4+)

Interfaces, Traits & Enums #

interface HasArea { public function area(): float; }
trait Loggable { public function log(string $m): void { echo static::class . ": $m"; } }

final class Circle implements HasArea {
    use Loggable;                       // copy the trait's methods in
    public function __construct(private float $r) {}
    public function area(): float { return M_PI * $this->r ** 2; }
}

enum Status: string { case Active = 'active'; case Banned = 'banned'; }  // PHP 8.1+
CodeWhat it does
enum Suit { case Hearts; case Spades; }Pure enum without values (PHP 8.1+)
Status::Active->value / Suit::Hearts->name'active' / 'Hearts'
Status::from('active') / Status::tryFrom('x')Case from a value; ValueError / null if invalid
Status::cases()Array of all cases

Errors & Exceptions #

CodeWhat it does
try { } catch (NotFoundException $e) { } finally { }Catch an exception; finally always runs
catch (TypeError | ValueError $e)Several types in one catch
catch (Throwable $e)Catch everything, including Error (TypeError, DivisionByZeroError)
throw new InvalidArgumentException("Bad id");Throw an exception (custom: class NotFound extends Exception {})
$e->getMessage() / $e->getCode() / $e->getLine()Details of the exception
$id ?? throw new Exception('Missing id')throw as an expression (PHP 8.0+)
error_reporting(E_ALL); ini_set('display_errors', '1');Show every error during development

Forms & Superglobals #

CodeWhat it does
$_GET['q'] ?? ''Query string value from ?q=...
$_POST['email'] ?? ''Field from a form sent with method="post"
$_SERVER['REQUEST_METHOD'] === 'POST'Was the form submitted?
session_start(); $_SESSION['user'] = $id;Session data that survives between requests
<?= htmlspecialchars($name) ?>Escape text for HTML output (prevents XSS)
filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT)Int, false if invalid, null if missing
filter_var($email, FILTER_VALIDATE_EMAIL)The email, or false
password_hash($pw, PASSWORD_DEFAULT) / password_verify($pw, $hash)Store and check passwords safely
header('Location: /thanks.php'); exit;Redirect (before any output)

Files, JSON & Dates #

CodeWhat it does
file_get_contents('data.txt')Read a whole file into a string
file_put_contents('log.txt', $line, FILE_APPEND)Write a file (append with the flag)
file_exists($p) / is_dir($p) / unlink($p)Check a path / is it a folder / delete a file
__DIR__ . '/config.php'Path relative to the current file
json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)PHP value to JSON text
json_decode($json, true)JSON to associative array (without true: objects)
json_decode($json, true, flags: JSON_THROW_ON_ERROR)Throw JsonException on bad JSON instead of returning null
date('Y-m-d H:i:s') / time()Now as formatted text / Unix timestamp
new DateTimeImmutable('2026-10-11')Date object (immutable: methods return a new one)
$d->modify('+1 week')->format('d/m/Y')Date math and formatting
$a->diff($b)->daysDays between two dates

Databases (PDO) #

$pdo = new PDO('mysql:host=localhost;dbname=shop;charset=utf8mb4', $user, $pass, [
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,  // errors throw by default (8.0+)
]);
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email');
$stmt->execute(['email' => $email]);   // value sent separately: no SQL injection
$user = $stmt->fetch();                // one row, or false
$pdo->prepare('INSERT INTO users (name, email) VALUES (?, ?)')->execute([$name, $email]);
$id = $pdo->lastInsertId();
CodeWhat it does
new PDO('sqlite:' . __DIR__ . '/app.db')Connect to an SQLite file
$stmt->fetchAll() / $stmt->fetchColumn()All rows / first column of the next row (for COUNT(*))
$pdo->beginTransaction() / commit() / rollBack()All-or-nothing changes

Tips #

  • Put declare(strict_types=1); at the top of every file and compare with ===.
  • Never trust $_GET, $_POST or $_COOKIE: validate input, escape output with htmlspecialchars, and always use prepared statements for SQL.
  • Hash passwords with password_hash(); never md5() or sha1().
  • strpos() returns 0 for a match at the start: test with !== false, or use str_contains().
  • After foreach ($arr as &$v), call unset($v), or a later loop over $arr overwrites its last element.
  • php -S and display_errors are for development only; log errors in production.