PHP
03 / 06

Modern PHP: Composer, Fibers & Best Practices

PHP: Modern PHP, Composer & Best Practices

Composer

# Install Composer
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

# Create project
composer init
composer create-project laravel/laravel myapp

# Install packages
composer require guzzlehttp/guzzle
composer require --dev phpunit/phpunit psalm/psalm

# Update dependencies
composer update
composer update guzzlehttp/guzzle  # single package

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

# Scripts
# composer.json: "scripts": { "test": "vendor/bin/phpunit", "lint": "vendor/bin/psalm" }
composer test
composer lint

PHP 8.x Features

<?php

// Named arguments (PHP 8.0)
array_slice(array: $arr, offset: 1, length: 3, preserve_keys: true);

// Match expression (PHP 8.0) — strict, no fallthrough, exhaustive
$label = match($status) {
    'active', 'enabled' => 'Active',
    'inactive' => 'Inactive',
    default => throw new \ValueError("Unknown status: $status"),
};

// Nullsafe operator (PHP 8.0)
$country = $user?->getAddress()?->getCountry()?->getName();

// Union types (PHP 8.0)
function parseId(int|string $id): User { ... }

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

// Readonly properties (PHP 8.1)
class Point {
    public function __construct(
        public readonly float $x,
        public readonly float $y,
    ) {}
}

// Fibers (PHP 8.1) — cooperative concurrency
$fiber = new Fiber(function (): void {
    $value = Fiber::suspend('first');   // yields 'first', receives next value
    echo "Resumed with: $value\n";
    Fiber::suspend('second');
});

$val1 = $fiber->start();           // 'first'
$val2 = $fiber->resume('hello');   // 'second'

// First class callables (PHP 8.1)
$fn = strlen(...);
$fn("hello");   // 5

// Readonly classes (PHP 8.2)
readonly class Money {
    public function __construct(
        public int $amount,
        public string $currency,
    ) {}
}

// Typed class constants (PHP 8.3)
class Config {
    const string VERSION = '1.0.0';
    const int MAX_RETRIES = 3;
}

Best Practices

  • Use strict_types: add declare(strict_types=1) at the top of every PHP file — prevents type coercion bugs.

  • Type declarations everywhere: parameters, return types, properties. Use union types and nullable (?) where needed.

  • Use PDO with prepared statements always — never concatenate user input into SQL queries.

  • Hash passwords with password_hash() and verify with password_verify() — never md5 or sha1.

  • Validate and sanitize all input: filter_input(), FILTER_VALIDATE_*, or a validation library.

  • Use Composer for all dependencies. Never copy-paste vendor code into your project.

  • Follow PSR-12 coding standard. Use PHP_CodeSniffer or PHP-CS-Fixer for enforcement.

  • Use a static analyzer: PHPStan (level 8+) or Psalm catches type errors without running the code.

  • Major frameworks: Laravel (most popular, batteries-included), Symfony (enterprise, modular), Slim (microframework for APIs).

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free