PHP: The Modern Web Language

Master modern PHP with Laravel, Composer, and current best practices


PHP: The Modern Web Language
1 Loading...

PHP: The Modern Web Language

PHP remains one of the most used languages on the web, powering about 77% of all websites, including WordPress, Facebook, and Wikipedia. With PHP 8.x, the language underwent a significant transformation, incorporating modern features like strong typing, JIT compilation, and attributes.

Myth busted: Modern PHP is completely different from legacy PHP. With frameworks like Laravel and Symfony, PHP rivals any modern stack in productivity and elegance.

PHP 8.x Features

  1. JIT Compilation - Significantly improved performance
  2. Named Arguments - Named arguments for clarity
  3. Attributes - Native metadata (like annotations)
  4. Match Expression - More powerful switch
  5. Constructor Promotion - More concise classes
  6. Union Types - Multiple types allowed
  7. Nullsafe Operator - ?-> for safe chaining

Modern Fundamentals

Types and Variables

<?php

declare(strict_types=1);

// Scalar types
$name = 'Maria';           // string
$age = 25;                 // int
$height = 1.68;            // float
$active = true;            // bool

// Arrays
$fruits = ['apple', 'banana', 'orange'];
$user = [
    'name' => 'Maria',
    'email' => '[email protected]',
    'age' => 25
];

// Array destructuring
['name' => $name, 'email' => $email] = $user;

// Spread operator
$numbers = [1, 2, 3];
$moreNumbers = [...$numbers, 4, 5, 6];

// Null coalescing
$value = $user['phone'] ?? 'Not provided';

// Nullsafe operator (PHP 8.0+)
$city = $user?->address?->city;

Modern Classes

<?php

declare(strict_types=1);

// Constructor promotion (PHP 8.0+)
class User
{
    public function __construct(
        public readonly int $id,
        public string $name,
        public string $email,
        public bool $active = true,
        public ?\DateTimeImmutable $createdAt = null
    ) {
        $this->createdAt ??= new \DateTimeImmutable();
    }
    
    public function greet(): string
    {
        return "Hello, {$this->name}!";
    }
    
    public function deactivate(): void
    {
        $this->active = false;
    }
}

// Enums (PHP 8.1+)
enum Status: string
{
    case Pending = 'pending';
    case Approved = 'approved';
    case Rejected = 'rejected';
    
    public function label(): string
    {
        return match($this) {
            self::Pending => 'Awaiting review',
            self::Approved => 'Approved ✓',
            self::Rejected => 'Rejected ✗',
        };
    }
}

// Readonly classes (PHP 8.2+)
readonly class Product
{
    public function __construct(
        public string $name,
        public float $price,
        public int $quantity
    ) {}
    
    public function totalValue(): float
    {
        return $this->price * $this->quantity;
    }
}

Interfaces and Traits

<?php

interface Repository
{
    public function findById(int $id): ?object;
    public function findAll(): array;
    public function save(object $entity): object;
    public function delete(int $id): void;
}

trait Timestamps
{
    public ?\DateTimeImmutable $createdAt = null;
    public ?\DateTimeImmutable $updatedAt = null;
    
    public function updateTimestamp(): void
    {
        $this->updatedAt = new \DateTimeImmutable();
        $this->createdAt ??= $this->updatedAt;
    }
}

class UserRepository implements Repository
{
    use Timestamps;
    
    private array $users = [];
    
    public function findById(int $id): ?User
    {
        return $this->users[$id] ?? null;
    }
    
    public function findAll(): array
    {
        return array_values($this->users);
    }
    
    public function save(object $entity): User
    {
        $this->users[$entity->id] = $entity;
        $this->updateTimestamp();
        return $entity;
    }
    
    public function delete(int $id): void
    {
        unset($this->users[$id]);
    }
}

Match Expression and Attributes

<?php

// Match expression (PHP 8.0+)
function describe(mixed $value): string
{
    return match(true) {
        is_null($value) => 'Null',
        is_string($value) && $value === '' => 'Empty string',
        is_string($value) => "String: $value",
        is_int($value) && $value > 0 => "Positive integer: $value",
        is_int($value) => "Integer: $value",
        is_array($value) => 'Array with ' . count($value) . ' items',
        default => 'Unknown type',
    };
}

// Attributes (PHP 8.0+)
#[Attribute(Attribute::TARGET_PROPERTY)]
class Validate
{
    public function __construct(
        public string $rule,
        public string $message = 'Invalid field'
    ) {}
}

#[Attribute(Attribute::TARGET_CLASS)]
class Entity
{
    public function __construct(
        public string $table
    ) {}
}

#[Entity(table: 'users')]
class User
{
    #[Validate(rule: 'required', message: 'Name is required')]
    public string $name;
    
    #[Validate(rule: 'email')]
    public string $email;
}

Modern Laravel

<?php

// Controller with Route::resource
class ProductController extends Controller
{
    public function __construct(
        private ProductService $service
    ) {}
    
    public function index(): JsonResponse
    {
        return response()->json(
            $this->service->list()
        );
    }
    
    public function store(ProductRequest $request): JsonResponse
    {
        $product = $this->service->create($request->validated());
        
        return response()->json($product, 201);
    }
    
    public function show(Product $product): JsonResponse
    {
        return response()->json($product->load('category'));
    }
}

// Eloquent Model
class Product extends Model
{
    protected $fillable = ['name', 'price', 'category_id'];
    
    protected $casts = [
        'price' => 'decimal:2',
        'active' => 'boolean',
    ];
    
    public function category(): BelongsTo
    {
        return $this->belongsTo(Category::class);
    }
    
    public function scopeActive(Builder $query): Builder
    {
        return $query->where('active', true);
    }
}

// Fluent Query Builder
$products = Product::query()
    ->active()
    ->where('price', '>=', 500)
    ->with('category')
    ->orderBy('price', 'desc')
    ->paginate(20);

Essential Tools

ToolPurpose
ComposerDependency manager
LaravelFull-stack framework
SymfonyEnterprise framework
PHPUnitUnit testing
PHPStanStatic analysis
PestElegant testing

Learning Checklist

  • Master PHP 8.x features
  • Understand Composer and autoloading
  • Learn Laravel or Symfony
  • Study design patterns
  • Practice testing with PHPUnit/Pest
  • Explore REST APIs with Laravel
  • Implement authentication and authorization

Essential Resources

Quote

“Modern PHP has nothing to do with the PHP you may have heard about. It’s a mature, typed, and performant language.” - Taylor Otwell


PHP continues to evolve and remains an excellent choice for web development!