Adeel's web page

HOME

PHP lecture for newcomers

How PHP executes the script

When we execute a PHP script through the command line, or open a PHP page in a browser, the PHP engine first loads the PHP file. The execution process consists of lexical analysis, parsing, compilation, and finally execution. If OPcache is enabled, the first three steps are skipped, and the cached bytecode is executed directly.

The lexical process involves converting the source code into tokens. Parsing analyzes these tokens to form an Abstract Syntax Tree (AST). Compilation converts the AST into Opcodes, and finally, the Zend Engine executes these opcodes. The bytecode is the entire sequence of Opcodes, designed to be interpreted efficiently by the PHP interpreter.

PHP 7 and PHP 8 introduced significant performance improvements and new language features. PHP 7 was up to twice as fast as PHP 5.6 with reduced memory usage. PHP 8 continues this evolution.

PHP 8.0 is a major update containing many new features and optimizations, including named arguments, union types, attributes, constructor property promotion, match expressions, nullsafe operators, JIT, and improvements in the type system, error handling, and consistency.

Why PHP

If you are working on CMS or CRUD-based applications, PHP is an excellent choice. The latest PHP (v8.4) includes modern features that make it competitive and developer-friendly.

Typed properties

public ?DateTimeImmutable $publishedAt;

Readonly properties and classes

public readonly ?string $prop;

Attempting to modify a readonly property causes an Error. However, objects stored in readonly properties can still be modified. The same applies to readonly classes:

readonly class Test {
    public string $prop;
}

Property Promotion

class CustomerDTO
{
    public function __construct(
        public string $name,
        public string $email,
        public DateTimeImmutable $birth_date,
    ) {}
}

Instead of defining a class property and then assigning it in the constructor, this shorthand syntax promotes constructor parameters directly to class properties.

Null Coalescing Operator (??)

$name = $_POST['name'] ?? 'Farhan';

If the value is null or not found, the null coalescing operator returns the right-hand value. It’s commonly used to assign default values.

Null Safe Operator (?->)

if ($user !== null) {
    if ($user->getAddress() !== null) {
        $country = $user->getAddress()->country;
    }
}

With the null safe operator:

$country = $user?->getAddress()?->country;

The null safe operator shortens nested null checks. If any object in the chain is null, the entire expression evaluates to null without throwing an error.

OpCache and JIT

OPcache is a built-in PHP extension that improves performance by caching precompiled script bytecode in shared memory. On subsequent requests, PHP retrieves bytecode directly from cache, skipping parsing and compilation.

JIT (Just-In-Time) compilation, introduced in PHP 8, extends OPcache by compiling frequently executed sections of code into native machine code at runtime. This significantly improves performance for CPU-intensive workloads.

Fibers for concurrent programming

Fibers are functions that can be paused and resumed, allowing cooperative multitasking. They enable non-blocking I/O without full multithreading.

$fiber = new Fiber(function (): void {
    $value = Fiber::suspend('Paused execution');
    echo "Resumed with: $value\n";
});

echo $fiber->start();
$fiber->resume('Hello Fiber!');

FFI (Foreign Function Interface)

FFI allows PHP to directly call C functions and use C data structures without external extensions.

$ffi = FFI::cdef("
    int printf(const char *format, ...);
");
$ffi->printf("Hello from C! Number: %d\n", 123);

Generators

Generators allow you to iterate over data without loading the entire dataset into memory, making them ideal for handling large datasets efficiently.

function getNumbers(): Generator {
    for ($i = 1; $i <= 5; $i++) {
        yield $i;
    }
}

foreach (getNumbers() as $num) {
    echo $num . PHP_EOL;
}

PHP Type System Improvements

Example: Union Type

function setValue(int|string $value): void {
    echo $value;
}

Example: Intersection Type

function process(Countable&Iterator $obj): void {
    // Requires both interfaces
}

Example: Nullable Type

function getUser(?int $id): ?User {
    return $id ? new User($id) : null;
}

Example: Void Type

function logMessage(string $msg): void {
    echo $msg;
}

Example: Never Type

function terminate(string $message): never {
    exit($message);
}

Example: Static Return Type

class Base {
    public function create(): static {
        return new static();
    }
}

Code Analyzers (PHPStan & Psalm)

Static analysis tools like PHPStan and Psalm help detect bugs, type mismatches, and unsafe operations without executing the code.

# PHPStan Example
vendor/bin/phpstan analyse src --level=max

# Psalm Example
vendor/bin/psalm --show-info=true

Comparison with Node.js

PHP excels in synchronous request-response patterns, while Node.js shines for real-time and event-driven applications. PHP offers a richer ecosystem for CMS and server-rendered sites, whereas Node.js dominates in microservices and WebSocket-based apps.

Comparison with .NET

.NET offers strong enterprise tooling and native performance, but PHP remains simpler for web deployment and affordable hosting. PHP’s lightweight footprint and massive hosting availability make it ideal for small-to-medium businesses.

How to fix PHP drawbacks

Language Features

Object-Oriented Programming (OOP)

class Car {
    public function __construct(private string $model) {}
    public function getModel(): string {
        return $this->model;
    }
}
$car = new Car('Honda');
echo $car->getModel();

Functional Programming

$numbers = [1, 2, 3, 4, 5];
$squared = array_map(fn($n) => $n * $n, $numbers);
print_r($squared);