Lesson 64 of 158 – PHP API Error Handling
64%

PHP API Error Handling

Error handling is an important part of building a reliable PHP REST API. An API should detect errors, return suitable HTTP status codes, and send clear JSON error responses to the client.

Note: Never expose sensitive database information, passwords, file paths, or internal server details in API error responses.

1. What is API Error Handling?

API error handling means detecting problems during request processing and returning an appropriate response to the client.

Client Request
      ↓
PHP API
      ↓
Error?
 ┌────┴────┐
No        Yes
↓           ↓
Success   Error Response
            ↓
        JSON + Status Code

2. Why Error Handling is Important

Without proper error handling, an API can return confusing messages or unexpected output.

  • Helps identify problems.
  • Provides useful information to the client.
  • Prevents application crashes.
  • Improves API reliability.
  • Protects sensitive server information.

3. API Errors and HTTP Status Codes

API errors should normally be accompanied by an appropriate HTTP status code.

Status Example Situation
400 Invalid request data
401 Authentication required
403 Access denied
404 Resource not found
405 Method not allowed
500 Server error

4. Set JSON Response Header

A REST API should tell the client that it is returning JSON.

header("Content-Type: application/json");

This should be sent before outputting the JSON response.

5. Basic Error Response

A simple JSON error response can be created using a PHP array and json_encode().

echo json_encode([
    "success" => false,
    "message" => "Invalid request"
]);

6. Error Response with Status Code

http_response_code(400);

echo json_encode([
    "success" => false,
    "message" => "Invalid request"
]);

The client receives both the HTTP status and the JSON response.

7. Handling Missing Input

Suppose a student API requires a student ID.

$id = $_GET['id'] ?? '';

if ($id === '') {

    http_response_code(400);

    echo json_encode([
        "success" => false,
        "message" => "Student ID is required"
    ]);

    exit;
}

8. Handling Invalid ID

The API should validate IDs before using them in database operations.

$id = $_GET['id'] ?? '';

if (!filter_var($id, FILTER_VALIDATE_INT)) {

    http_response_code(400);

    echo json_encode([
        "success" => false,
        "message" => "Invalid student ID"
    ]);

    exit;
}

9. Handling Not Found Errors

If the requested student does not exist, the API can return HTTP 404.

if (!$student) {

    http_response_code(404);

    echo json_encode([
        "success" => false,
        "message" => "Student not found"
    ]);

    exit;
}

10. Handling Authentication Errors

A protected API can return HTTP 401 when authentication is missing or invalid.

if (!$token) {

    http_response_code(401);

    echo json_encode([
        "success" => false,
        "message" => "Authentication required"
    ]);

    exit;
}

11. Handling Forbidden Access

HTTP 403 can be used when a user is authenticated but does not have permission to perform an operation.

if ($role !== 'admin') {

    http_response_code(403);

    echo json_encode([
        "success" => false,
        "message" => "Access denied"
    ]);

    exit;
}

12. Handling Unsupported Methods

An API can check the HTTP request method.

$method = $_SERVER['REQUEST_METHOD'];

if ($method !== 'GET') {

    http_response_code(405);

    echo json_encode([
        "success" => false,
        "message" => "Method not allowed"
    ]);

    exit;
}

13. PHP Exceptions

PHP exceptions can be handled using try and catch.

try {

    // Code that may cause an exception

} catch (Exception $e) {

    // Handle the exception

}

14. Basic try-catch Example

try {

    $number = 10 / 0;

} catch (Exception $e) {

    echo "An error occurred";

}

The catch block can handle an exception instead of allowing the application to stop unexpectedly.

15. PDO Exception Handling

PDO can be configured to throw exceptions for database errors.

$pdo->setAttribute(
    PDO::ATTR_ERRMODE,
    PDO::ERRMODE_EXCEPTION
);

This makes database errors easier to handle using try-catch.

16. Database Error Handling

try {

    $stmt = $pdo->prepare(
        "SELECT * FROM students"
    );

    $stmt->execute();

} catch (PDOException $e) {

    http_response_code(500);

    echo json_encode([
        "success" => false,
        "message" => "Database operation failed"
    ]);

    exit;
}

17. Do Not Expose Database Errors

Avoid sending the actual database exception message directly to the mobile application.

// Avoid this

echo $e->getMessage();

Instead, return a safe message.

echo json_encode([
    "success" => false,
    "message" => "Database operation failed"
]);

18. Log the Actual Error

The actual error can be logged on the server while a safe message is returned to the client.

error_log($e->getMessage());

http_response_code(500);

echo json_encode([
    "success" => false,
    "message" => "Something went wrong"
]);

19. Validation Error Handling

$name = trim($_POST['name'] ?? '');
$email = trim($_POST['email'] ?? '');

if ($name === '' || $email === '') {

    http_response_code(400);

    echo json_encode([
        "success" => false,
        "message" => "Name and email are required"
    ]);

    exit;
}

20. Email Validation

PHP can validate an email address using filter_var().

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {

    http_response_code(422);

    echo json_encode([
        "success" => false,
        "message" => "Invalid email address"
    ]);

    exit;
}

21. JSON Input Error

When a REST API receives JSON, PHP can read it using php://input.

$input = file_get_contents("php://input");

$data = json_decode($input, true);

if (json_last_error() !== JSON_ERROR_NONE) {

    http_response_code(400);

    echo json_encode([
        "success" => false,
        "message" => "Invalid JSON data"
    ]);

    exit;
}

22. Create a Reusable Error Function

A reusable function can make API error handling shorter and more consistent.

function sendError(
    int $status,
    string $message
) {

    http_response_code($status);

    echo json_encode([
        "success" => false,
        "message" => $message
    ]);

    exit;
}

23. Use the Error Function

$id = $_GET['id'] ?? '';

if ($id === '') {

    sendError(
        400,
        "Student ID is required"
    );
}

The function sets the status, creates the JSON response, and stops execution.

24. Error Function for Not Found

$student = null;

if (!$student) {

    sendError(
        404,
        "Student not found"
    );
}

This keeps API code clean and easy to maintain.

25. Error Function for Server Error

try {

    $stmt = $pdo->prepare(
        "SELECT * FROM students"
    );

    $stmt->execute();

} catch (PDOException $e) {

    error_log($e->getMessage());

    sendError(
        500,
        "Unable to process request"
    );
}

26. React Native Handling API Errors

React Native can check the HTTP response and then read the JSON error.

fetch(url)
    .then(async response => {

        const data = await response.json();

        if (!response.ok) {

            throw new Error(data.message);
        }

        return data;
    })
    .then(data => {

        console.log(data);

    })
    .catch(error => {

        console.log(error.message);

    });

27. Error Handling Flow

React Native
      ↓
API Request
      ↓
PHP Validation
      ↓
Database Operation
      ↓
Error?
 ┌────┴────┐
No        Yes
↓           ↓
Success   Log Error
↓           ↓
JSON      Status Code
Response  +
          JSON Error

28. Complete API Error Handling Example

<?php

header("Content-Type: application/json");

function sendError(
    int $status,
    string $message
) {

    http_response_code($status);

    echo json_encode([
        "success" => false,
        "message" => $message
    ]);

    exit;
}

$id = $_GET['id'] ?? '';

if ($id === '') {

    sendError(
        400,
        "Student ID is required"
    );
}

if (!filter_var($id, FILTER_VALIDATE_INT)) {

    sendError(
        400,
        "Invalid student ID"
    );
}

?>

29. API Error Handling Best Practices

  • Validate input before database operations.
  • Use appropriate HTTP status codes.
  • Return errors in JSON format.
  • Use clear and simple error messages.
  • Use try-catch for operations that can throw exceptions.
  • Configure PDO to throw exceptions when appropriate.
  • Log technical errors on the server.
  • Do not expose database errors to clients.
  • Do not expose passwords or sensitive information.
  • Use reusable error response functions.
  • Stop execution after sending a final error response.

30. Complete Error Handling Structure

A professional PHP REST API should follow a predictable error handling process.

<?php

header("Content-Type: application/json");

function sendError(
    int $status,
    string $message
) {

    http_response_code($status);

    echo json_encode([
        "success" => false,
        "message" => $message
    ]);

    exit;
}

try {

    $id = $_GET['id'] ?? '';

    if ($id === '') {
        sendError(400, "Student ID is required");
    }

    if (!filter_var($id, FILTER_VALIDATE_INT)) {
        sendError(400, "Invalid student ID");
    }

    // Database operation here

    http_response_code(200);

    echo json_encode([
        "success" => true,
        "message" => "Request successful"
    ]);

} catch (PDOException $e) {

    error_log($e->getMessage());

    sendError(
        500,
        "Database operation failed"
    );

} catch (Exception $e) {

    error_log($e->getMessage());

    sendError(
        500,
        "Something went wrong"
    );
}

?>

📌 Key Points

  • API error handling detects and manages problems during request processing.
  • Errors should be returned using JSON responses.
  • Use appropriate HTTP status codes for different errors.
  • Use 400 for invalid requests.
  • Use 401 for authentication problems.
  • Use 403 for forbidden operations.
  • Use 404 when a resource is not found.
  • Use 405 when an HTTP method is not allowed.
  • Use 422 for validation errors when appropriate.
  • Use 500 for unexpected server errors.
  • PHP exceptions can be handled using try-catch.
  • PDO exceptions can be handled using PDOException.
  • Use error_log() to record technical errors on the server.
  • Never expose sensitive database or server details to clients.
  • Reusable error functions make API code cleaner.
  • React Native can read the JSON error message and HTTP status.

🧠 Quick Quiz

Question: Which PHP structure is commonly used to handle exceptions?