PHP

Essential PHP syntax, functions, and patterns for web development.

languages
phpbackendwebserver

Variables & Data Types

<?php
// Variables (loosely typed)
$name = "Alice";        // string
$age = 30;              // integer
$price = 19.99;         // float
$isActive = true;       // boolean
$items = [1, 2, 3];     // array
$person = null;         // null

// Type declarations (PHP 7+)
declare(strict_types=1);

function add(int $a, int $b): int {
    return $a + $b;
}

// Constants
define("MAX_SIZE", 100);
const APP_NAME = "MyApp";

// Variable variables
$varName = "hello";
$$varName = "world";    // Creates $hello = "world"

Strings

<?php
// String concatenation
$greeting = "Hello, " . $name . "!";

// Interpolation (double quotes only)
$greeting = "Hello, $name!";
$greeting = "Hello, {$user['name']}!";

// Heredoc & Nowdoc
$html = <<<HTML
<div>$name</div>
HTML;

$raw = <<<'TEXT'
No $interpolation here
TEXT;

// String functions
strlen($str);                  // Length
strtoupper($str);              // UPPERCASE
strtolower($str);              // lowercase
trim($str);                    // Remove whitespace
substr($str, 0, 5);            // Substring
str_replace("a", "b", $str);   // Replace
explode(",", $str);            // Split to array
implode("-", $arr);            // Join array
strpos($str, "needle");        // Find position
sprintf("Hello %s", $name);    // Format string

Arrays

<?php
// Indexed arrays
$fruits = ["apple", "banana", "cherry"];
$fruits[] = "date";            // Append

// Associative arrays
$person = [
    "name" => "Alice",
    "age" => 30
];

// Array functions
count($arr);                   // Length
array_push($arr, $item);       // Add to end
array_pop($arr);               // Remove from end
array_shift($arr);             // Remove from start
array_unshift($arr, $item);    // Add to start
array_merge($arr1, $arr2);     // Merge arrays
array_keys($arr);              // Get keys
array_values($arr);            // Get values
in_array($val, $arr);          // Check if exists
array_search($val, $arr);      // Find index
array_unique($arr);            // Remove duplicates
array_reverse($arr);           // Reverse order
sort($arr);                    // Sort ascending
rsort($arr);                   // Sort descending

// Array iteration
array_map(fn($x) => $x * 2, $arr);
array_filter($arr, fn($x) => $x > 5);
array_reduce($arr, fn($acc, $x) => $acc + $x, 0);

Control Structures

<?php
// If/else
if ($age >= 18) {
    echo "Adult";
} elseif ($age >= 13) {
    echo "Teen";
} else {
    echo "Child";
}

// Ternary operator
$status = $age >= 18 ? "adult" : "minor";

// Null coalescing
$name = $user["name"] ?? "Guest";

// Null coalescing assignment (PHP 7.4+)
$name ??= "Default";

// Nullsafe operator (PHP 8+)
$country = $user?->address?->country;

// Match expression (PHP 8+)
$result = match($status) {
    "active" => "User is active",
    "pending" => "User is pending",
    default => "Unknown status"
};

// Switch
switch ($day) {
    case "Monday":
        echo "Start of week";
        break;
    case "Friday":
        echo "End of week";
        break;
    default:
        echo "Mid week";
}

Loops

<?php
// For loop
for ($i = 0; $i < 10; $i++) {
    echo $i;
}

// While loop
while ($condition) {
    // code
}

// Do-while loop
do {
    // code
} while ($condition);

// Foreach
foreach ($items as $item) {
    echo $item;
}

// Foreach with key
foreach ($person as $key => $value) {
    echo "$key: $value";
}

// Loop control
break;      // Exit loop
continue;   // Skip iteration

Functions

<?php
// Basic function
function greet($name) {
    return "Hello, $name!";
}

// Default parameters
function greet($name = "World") {
    return "Hello, $name!";
}

// Named arguments (PHP 8+)
function createUser($name, $email, $role = "user") {}
createUser(name: "Alice", email: "alice@example.com");

// Variadic functions
function sum(...$numbers) {
    return array_sum($numbers);
}

// Arrow functions (PHP 7.4+)
$double = fn($x) => $x * 2;

// Anonymous functions (closures)
$greet = function($name) {
    return "Hello, $name!";
};

// Use variables from parent scope
$multiplier = 3;
$multiply = function($x) use ($multiplier) {
    return $x * $multiplier;
};

Classes & Objects

<?php
class User {
    // Properties
    public string $name;
    private int $age;
    protected string $email;
    public static int $count = 0;

    // Constructor
    public function __construct(string $name, int $age) {
        $this->name = $name;
        $this->age = $age;
        self::$count++;
    }

    // Constructor property promotion (PHP 8+)
    public function __construct(
        public string $name,
        private int $age
    ) {}

    // Methods
    public function greet(): string {
        return "Hello, {$this->name}!";
    }

    // Static method
    public static function getCount(): int {
        return self::$count;
    }

    // Getter/Setter
    public function getAge(): int {
        return $this->age;
    }

    public function setAge(int $age): void {
        $this->age = $age;
    }
}

// Usage
$user = new User("Alice", 30);
echo $user->greet();
echo User::$count;

Inheritance & Interfaces

<?php
// Inheritance
class Admin extends User {
    public function __construct(string $name, int $age) {
        parent::__construct($name, $age);
    }

    // Override method
    public function greet(): string {
        return "Hello Admin, {$this->name}!";
    }
}

// Abstract class
abstract class Shape {
    abstract public function area(): float;
}

// Interface
interface Printable {
    public function print(): void;
}

// Implementing interface
class Document implements Printable {
    public function print(): void {
        echo "Printing...";
    }
}

// Traits
trait Loggable {
    public function log(string $message): void {
        echo "[LOG] $message";
    }
}

class Service {
    use Loggable;
}

Error Handling

<?php
// Try/catch
try {
    $result = riskyOperation();
} catch (InvalidArgumentException $e) {
    echo "Invalid argument: " . $e->getMessage();
} catch (Exception $e) {
    echo "Error: " . $e->getMessage();
} finally {
    echo "Cleanup";
}

// Throw exception
function divide($a, $b) {
    if ($b === 0) {
        throw new InvalidArgumentException("Cannot divide by zero");
    }
    return $a / $b;
}

// Custom exception
class ValidationException extends Exception {
    public function __construct(
        string $message,
        public array $errors = []
    ) {
        parent::__construct($message);
    }
}

File Operations

<?php
// Read file
$content = file_get_contents("file.txt");
$lines = file("file.txt", FILE_IGNORE_NEW_LINES);

// Write file
file_put_contents("file.txt", $content);
file_put_contents("file.txt", $data, FILE_APPEND);

// File handling
$handle = fopen("file.txt", "r");
while (($line = fgets($handle)) !== false) {
    echo $line;
}
fclose($handle);

// File info
file_exists("file.txt");       // Check exists
is_file("file.txt");           // Is file
is_dir("folder");              // Is directory
filesize("file.txt");          // Get size
unlink("file.txt");            // Delete file
rename("old.txt", "new.txt");  // Rename/move
copy("src.txt", "dest.txt");   // Copy file

JSON & Serialization

<?php
// JSON encode/decode
$json = json_encode($array);
$data = json_decode($json, true); // true for associative array

// Check for errors
if (json_last_error() !== JSON_ERROR_NONE) {
    echo json_last_error_msg();
}

// Pretty print
$json = json_encode($data, JSON_PRETTY_PRINT);

// Serialize/unserialize
$serialized = serialize($data);
$data = unserialize($serialized);

Superglobals

<?php
// Request data
$_GET["param"];        // URL parameters
$_POST["field"];       // POST data
$_REQUEST["data"];     // GET, POST, COOKIE

// Server info
$_SERVER["REQUEST_METHOD"];
$_SERVER["HTTP_HOST"];
$_SERVER["REQUEST_URI"];
$_SERVER["REMOTE_ADDR"];

// Session
session_start();
$_SESSION["user"] = $user;
unset($_SESSION["user"]);
session_destroy();

// Cookies
setcookie("name", "value", time() + 3600);
$_COOKIE["name"];

// Files
$_FILES["upload"]["name"];
$_FILES["upload"]["tmp_name"];
$_FILES["upload"]["size"];
$_FILES["upload"]["error"];

Database (PDO)

<?php
// Connect
$pdo = new PDO(
    "mysql:host=localhost;dbname=mydb",
    "username",
    "password",
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);

// Prepared statements (prevents SQL injection)
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute(["id" => $userId]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);

// Insert
$stmt = $pdo->prepare("INSERT INTO users (name, email) VALUES (?, ?)");
$stmt->execute([$name, $email]);
$lastId = $pdo->lastInsertId();

// Fetch all
$stmt = $pdo->query("SELECT * FROM users");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);

// Transaction
$pdo->beginTransaction();
try {
    // queries...
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
}

Date & Time

<?php
// Current date/time
$now = new DateTime();
$now = new DateTime("now");
$timestamp = time();

// Create from string
$date = new DateTime("2024-01-15");
$date = new DateTime("next Monday");
$date = DateTime::createFromFormat("d/m/Y", "15/01/2024");

// Format date
$date->format("Y-m-d");         // 2024-01-15
$date->format("F j, Y");        // January 15, 2024
$date->format("H:i:s");         // 14:30:00
date("Y-m-d H:i:s", $timestamp);

// Modify date
$date->modify("+1 day");
$date->modify("-2 weeks");
$date->add(new DateInterval("P1M")); // Add 1 month
$date->sub(new DateInterval("P1Y")); // Subtract 1 year

// Date difference
$date1 = new DateTime("2024-01-01");
$date2 = new DateTime("2024-12-31");
$diff = $date1->diff($date2);
echo $diff->days;               // Total days
echo $diff->format("%y years, %m months, %d days");

// Timezone
$date = new DateTime("now", new DateTimeZone("America/New_York"));
$date->setTimezone(new DateTimeZone("UTC"));

// Immutable (recommended)
$date = new DateTimeImmutable("now");
$newDate = $date->modify("+1 day"); // Returns new instance

Regular Expressions

<?php
// Match
preg_match("/pattern/", $subject, $matches);
preg_match("/(\d+)-(\d+)/", "123-456", $matches);
// $matches = ["123-456", "123", "456"]

// Match all
preg_match_all("/\d+/", "a1b2c3", $matches);
// $matches[0] = ["1", "2", "3"]

// Replace
$result = preg_replace("/\s+/", " ", $text);

// Replace with callback
$result = preg_replace_callback(
    "/\d+/",
    fn($m) => $m[0] * 2,
    "a1b2c3"
);

// Split
$parts = preg_split("/[\s,]+/", "a, b c");

// Common patterns
"/^\d+$/"           // Only digits
"/^[a-zA-Z]+$/"     // Only letters
"/^[\w.-]+@[\w.-]+\.\w+$/"  // Email (basic)
"/^https?:\/\//"    // URL protocol

// Modifiers
"/pattern/i"        // Case insensitive
"/pattern/m"        // Multiline
"/pattern/s"        // Dot matches newline
"/pattern/u"        // Unicode support

Namespaces & Autoloading

<?php
// Define namespace
namespace App\Models;

class User {
    // ...
}

// Using namespaces
namespace App\Controllers;

use App\Models\User;
use App\Models\Post as BlogPost;  // Alias
use function App\Helpers\format;  // Import function
use const App\Config\VERSION;     // Import constant

$user = new User();
$post = new BlogPost();

// Fully qualified name
$user = new \App\Models\User();

// PSR-4 Autoloading (composer.json)
// {
//     "autoload": {
//         "psr-4": {
//             "App\\": "src/"
//         }
//     }
// }

// Manual autoloader
spl_autoload_register(function ($class) {
    $file = __DIR__ . "/" . str_replace("\\", "/", $class) . ".php";
    if (file_exists($file)) {
        require $file;
    }
});

Enums (PHP 8.1+)

<?php
// Basic enum
enum Status {
    case Pending;
    case Active;
    case Archived;
}

$status = Status::Active;
$status->name;  // "Active"

// Backed enum (with values)
enum Status: string {
    case Pending = "pending";
    case Active = "active";
    case Archived = "archived";
}

$status = Status::Active;
$status->value;  // "active"

// Create from value
$status = Status::from("active");      // Throws if invalid
$status = Status::tryFrom("invalid");  // Returns null if invalid

// Enum methods
enum Color: string {
    case Red = "#FF0000";
    case Green = "#00FF00";
    case Blue = "#0000FF";

    public function label(): string {
        return match($this) {
            self::Red => "Red Color",
            self::Green => "Green Color",
            self::Blue => "Blue Color",
        };
    }

    public static function all(): array {
        return self::cases();
    }
}

Attributes (PHP 8+)

<?php
// Built-in attributes
#[Deprecated("Use newMethod() instead")]
public function oldMethod() {}

#[Override]
public function parentMethod() {}

// Custom attributes
#[Attribute]
class Route {
    public function __construct(
        public string $path,
        public string $method = "GET"
    ) {}
}

// Using attributes
class UserController {
    #[Route("/users", method: "GET")]
    public function index() {}

    #[Route("/users/{id}", method: "GET")]
    public function show(int $id) {}
}

// Reading attributes via reflection
$reflection = new ReflectionClass(UserController::class);
foreach ($reflection->getMethods() as $method) {
    $attributes = $method->getAttributes(Route::class);
    foreach ($attributes as $attr) {
        $route = $attr->newInstance();
        echo "{$route->method} {$route->path}";
    }
}

Magic Methods

<?php
class MagicClass {
    private array $data = [];

    // Called when accessing inaccessible properties
    public function __get(string $name): mixed {
        return $this->data[$name] ?? null;
    }

    // Called when setting inaccessible properties
    public function __set(string $name, mixed $value): void {
        $this->data[$name] = $value;
    }

    // Called when checking isset() on inaccessible properties
    public function __isset(string $name): bool {
        return isset($this->data[$name]);
    }

    // Called when unset() on inaccessible properties
    public function __unset(string $name): void {
        unset($this->data[$name]);
    }

    // Called when invoking inaccessible methods
    public function __call(string $name, array $args): mixed {
        return "Called $name with " . count($args) . " args";
    }

    // Called when invoking inaccessible static methods
    public static function __callStatic(string $name, array $args): mixed {
        return "Static called $name";
    }

    // Called when object is used as string
    public function __toString(): string {
        return json_encode($this->data);
    }

    // Called when object is invoked as function
    public function __invoke(...$args): mixed {
        return "Invoked with " . count($args) . " args";
    }

    // Called for var_export()
    public static function __set_state(array $data): object {
        $obj = new self();
        $obj->data = $data;
        return $obj;
    }

    // Called for serialize()
    public function __serialize(): array {
        return $this->data;
    }

    // Called for unserialize()
    public function __unserialize(array $data): void {
        $this->data = $data;
    }

    // Called when cloning object
    public function __clone(): void {
        $this->data = array_merge([], $this->data);
    }
}

Generators

<?php
// Basic generator
function numbers(int $max): Generator {
    for ($i = 1; $i <= $max; $i++) {
        yield $i;
    }
}

foreach (numbers(5) as $num) {
    echo $num; // 1, 2, 3, 4, 5
}

// Yield key-value pairs
function entries(): Generator {
    yield "a" => 1;
    yield "b" => 2;
    yield "c" => 3;
}

// Yield from (delegate)
function combined(): Generator {
    yield from [1, 2, 3];
    yield from range(4, 6);
}

// Memory-efficient file reading
function readLines(string $file): Generator {
    $handle = fopen($file, "r");
    while (($line = fgets($handle)) !== false) {
        yield trim($line);
    }
    fclose($handle);
}

foreach (readLines("large-file.txt") as $line) {
    // Process one line at a time
}

// Generator with return value
function process(): Generator {
    yield 1;
    yield 2;
    return "done";
}

$gen = process();
foreach ($gen as $val) {}
echo $gen->getReturn(); // "done"

HTTP Client (cURL)

<?php
// Simple GET request
$response = file_get_contents("https://api.example.com/data");

// cURL GET
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => "https://api.example.com/data",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ["Authorization: Bearer $token"]
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

// cURL POST with JSON
$ch = curl_init();
curl_setopt_array($ch, [
    CURLOPT_URL => "https://api.example.com/users",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => json_encode(["name" => "Alice"]),
    CURLOPT_HTTPHEADER => [
        "Content-Type: application/json",
        "Authorization: Bearer $token"
    ]
]);
$response = curl_exec($ch);
curl_close($ch);

// Stream context (alternative)
$context = stream_context_create([
    "http" => [
        "method" => "POST",
        "header" => "Content-Type: application/json\r\n",
        "content" => json_encode(["name" => "Alice"])
    ]
]);
$response = file_get_contents($url, false, $context);

Password Hashing

<?php
// Hash password (use for storing)
$hash = password_hash($password, PASSWORD_DEFAULT);
$hash = password_hash($password, PASSWORD_BCRYPT, ["cost" => 12]);
$hash = password_hash($password, PASSWORD_ARGON2ID);

// Verify password
if (password_verify($password, $hash)) {
    echo "Password is correct";
}

// Check if rehash needed (algorithm/cost changed)
if (password_needs_rehash($hash, PASSWORD_DEFAULT)) {
    $hash = password_hash($password, PASSWORD_DEFAULT);
    // Update hash in database
}

// Get hash info
$info = password_get_info($hash);
// ["algo" => 2, "algoName" => "bcrypt", "options" => ["cost" => 12]]

Encryption

<?php
// Symmetric encryption (OpenSSL)
$key = random_bytes(32);  // 256-bit key
$iv = random_bytes(16);   // Initialization vector

// Encrypt
$encrypted = openssl_encrypt(
    $plaintext,
    "AES-256-CBC",
    $key,
    OPENSSL_RAW_DATA,
    $iv
);
$encoded = base64_encode($iv . $encrypted);

// Decrypt
$decoded = base64_decode($encoded);
$iv = substr($decoded, 0, 16);
$encrypted = substr($decoded, 16);
$plaintext = openssl_decrypt(
    $encrypted,
    "AES-256-CBC",
    $key,
    OPENSSL_RAW_DATA,
    $iv
);

// Hashing
$hash = hash("sha256", $data);
$hash = hash_hmac("sha256", $data, $secretKey);

// Random values
$bytes = random_bytes(32);
$int = random_int(1, 100);

Type System (PHP 8+)

<?php
// Union types
function process(int|string $value): int|float {
    return is_string($value) ? strlen($value) : $value;
}

// Nullable types
function find(?int $id): ?User {
    return $id ? User::find($id) : null;
}

// Intersection types (PHP 8.1+)
function process(Iterator&Countable $collection): void {}

// Mixed type
function debug(mixed $value): void {
    var_dump($value);
}

// Never return type (PHP 8.1+)
function redirect(string $url): never {
    header("Location: $url");
    exit;
}

// Readonly properties (PHP 8.1+)
class User {
    public function __construct(
        public readonly string $id,
        public readonly string $name
    ) {}
}

// Readonly classes (PHP 8.2+)
readonly class ValueObject {
    public function __construct(
        public string $name,
        public int $value
    ) {}
}

// First-class callable syntax (PHP 8.1+)
$closure = $object->method(...);
$closure = ClassName::method(...);

Debugging

<?php
// Output debugging
var_dump($variable);      // Type and value
print_r($array);          // Human-readable arrays
var_export($data, true);  // Valid PHP code

// Error reporting
error_reporting(E_ALL);
ini_set("display_errors", "1");

// Custom error handler
set_error_handler(function($errno, $errstr, $errfile, $errline) {
    throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});

// Assertions
assert($value > 0, "Value must be positive");

// Backtrace
debug_print_backtrace();
$trace = debug_backtrace();

// Execution time
$start = microtime(true);
// ... code ...
$elapsed = microtime(true) - $start;

// Memory usage
memory_get_usage();       // Current memory
memory_get_peak_usage();  // Peak memory

Version History

VersionRelease DateKey Features
PHP 8.4Nov 2024Property hooks, asymmetric visibility, #[\Deprecated] attribute
PHP 8.3Nov 2023Typed class constants, json_validate(), #[\Override] attribute
PHP 8.2Dec 2022Readonly classes, null, true, false as types, DNF types
PHP 8.1Nov 2021Enums, fibers, readonly properties, intersection types, never type
PHP 8.0Nov 2020Named arguments, attributes, union types, match expression, nullsafe operator, constructor promotion
PHP 7.4Nov 2019Arrow functions, typed properties, null coalescing assignment, spread operator in arrays
PHP 7.3Dec 2018Flexible heredoc/nowdoc, trailing commas in function calls
PHP 7.2Nov 2017Object type hint, parameter type widening
PHP 7.1Dec 2016Nullable types, void return type, class constant visibility
PHP 7.0Dec 2015Scalar type hints, return types, null coalescing, spaceship operator