PHP Best Practices for Modern Web Development

Discover essential PHP best practices and modern techniques for building robust web applications.

Published on November 12, 2024

PHP continues to evolve as a powerful language for web development. Here are essential best practices for writing clean, secure, and maintainable PHP code.

Use Modern PHP Versions

Always use the latest stable PHP version for better performance and security.

// PHP 8+ features
class User {
    public function __construct(
        public string $name,
        public string $email,
        public ?DateTime $createdAt = null
    ) {
        $this->createdAt ??= new DateTime();
    }
}

Embrace Type Declarations

Use strict typing for better code reliability.

<?php
declare(strict_types=1);

function calculateTotal(float $price, int $quantity): float {
    return $price * $quantity;
}

Follow PSR Standards

Adhere to PHP-FIG standards for consistent code style.

<?php

namespace App\Services;

use App\Models\User;
use App\Interfaces\UserRepositoryInterface;

class UserService
{
    public function __construct(
        private UserRepositoryInterface $userRepository
    ) {}
    
    public function createUser(array $data): User
    {
        // Validate and create user
        return $this->userRepository->create($data);
    }
}

Security Best Practices

Input Validation and Sanitization

// Validate input
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if (!$email) {
    throw new InvalidArgumentException('Invalid email format');
}

// Use prepared statements
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = ?');
$stmt->execute([$email]);

Password Hashing

// Hash passwords
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);

// Verify passwords
if (password_verify($inputPassword, $hashedPassword)) {
    // Password is correct
}

Error Handling

Use exceptions for better error management.

try {
    $user = $this->userService->findById($id);
} catch (UserNotFoundException $e) {
    return response()->json(['error' => 'User not found'], 404);
} catch (Exception $e) {
    logger()->error('Unexpected error: ' . $e->getMessage());
    return response()->json(['error' => 'Internal server error'], 500);
}

Dependency Injection

Use dependency injection for better testability and maintainability.

class OrderController
{
    public function __construct(
        private OrderService $orderService,
        private PaymentGateway $paymentGateway
    ) {}
    
    public function process(Request $request): Response
    {
        $order = $this->orderService->create($request->all());
        $payment = $this->paymentGateway->charge($order);
        
        return response()->json(['order' => $order, 'payment' => $payment]);
    }
}

Following these best practices will help you write more secure, maintainable, and performant PHP applications.