# PHP HTTP Status Codes: Best Practices for Clean Code

By Dinesh Uprety
Published: 2025-04-19
Updated: 2026-10-15
Canonical: https://laranepal.com/blog/php-http-status-code-class-best-practices-for-clean-maintainable-code

# A Clean Approach to HTTP Status Codes in PHP

## Introduction

HTTP status codes are fundamental to web communication, but working with raw numbers in code can be problematic. Let's
explore a better way to handle them in PHP.

## The Problem with Numeric Status Codes

Using numbers directly leads to several issues:

- Poor readability - what does `418` mean at a glance?
- No IDE support for autocompletion
- Risk of typos with no validation
- Scattered definitions across a codebase

## A Better Solution: The HTTPStatusCode Class

Here's how we can improve this with a dedicated class:

```php
<?php

declare(strict_types=1);

namespace App\Http;

/**
 * Provides named constants and utilities for HTTP status codes
 */
final class HTTPStatusCode
{
    // Informational responses
    public const CONTINUE = 100;
    public const SWITCHING_PROTOCOLS = 101;
    
    // Successful responses
    public const OK = 200;
    public const CREATED = 201;
    
    
    /**
     * Returns the HTTP status message for a given code.
     * @throws InvalidArgumentException if the code is invalid.
     */
    public static function getMessage(int $code): string
    {
        return match ($code) {
            self::CONTINUE => 'Continue',
            self::NOT_FOUND => 'Not Found',
            self::INTERNAL_SERVER_ERROR => 'Internal Server Error',
            // ... (Full match cases in the url below)
            default => throw new \InvalidArgumentException("Invalid HTTP status code: $code"),
        };
    }
    
    /**
     * Checks if the status code is a client error (4xx).
     */
    public static function isClientError(int $code): bool
    {
        return $code >= 400 && $code < 500;
    }

    /**
     * Checks if the status code is a server error (5xx).
     */
    public static function isServerError(int $code): bool
    {
        return $code >= 500 && $code < 600;
    }
}
```

The full code is available on my
GitHub. [View it here](https://gist.github.com/dineshuprety/8afd7e43d5fc978d44d08b740ce8a635).

## Key Advantages

1. **Improved Readability**

    ```php
    // Before
    if ($status === 404) { ... }
    
    // After  
    if ($status === HTTPStatusCode::NOT_FOUND) { ... }
    ```
2. **Built-in Validation**

   ```php
   try {
       $message = HTTPStatusCode::getMessage(999);
   } catch (\InvalidArgumentException $e) {
       // Handle invalid code
   }
   ```
3. **IDE Support**
    - Autocomplete for all status codes
    - Type hints and documentation

## Practical Applications

**API Responses**

   ```php
   function createApiResponse(int $status, $data = null): array
   {
       return [
           'status' => $status,
           'message' => HTTPStatusCode::getMessage($status),
           'data' => $data
       ];
   }
   ```

**Error Handling**

```php
if (HTTPStatusCode::isClientError($status)) {
    // handle client error or log it
}
```

**Testing**

```php
$this->assertSame(
    HTTPStatusCode::OK, 
    $response->getStatusCode()
);
```

## Implementation Considerations

1. **Immutable Design**
    - The class is marked `final` to prevent extension
    - All methods are static since no instance state is needed

2. **Performance**
    - The messages array is defined once in memory
    - No object instantiation overhead

3. **Extensibility**
    - Easy to add new utility methods
    - Simple to update status messages if needed

## Conclusion

This approach provides a clean, maintainable way to work with HTTP status codes in PHP. By using named constants and
centralizing the definitions, we get:

* Better code clarity
* Reduced chance of errors
* Improved developer experience
* Easier maintenance

The complete implementation can be dropped into any PHP project and immediately improve how status codes are handled.
