How to Send PHP Errors by Email with Full Backtrace and Input Data

Introduction

When your PHP application crashes or behaves unexpectedly, it’s often due to unnoticed errors like undefined variables or broken logic. By learning how to send PHP errors by email with full backtrace and request input, you can catch bugs in real-time—even before users report them.

In this article, you’ll get a plug-and-play solution to automatically email yourself whenever a PHP error occurs, including:

  • Notices
  • Warnings
  • Fatal Errors
  • Uncaught Exceptions

We’ll also show how to capture full backtrace info, input data (GET/POST/SESSION), and provide reproduction steps using live data to send PHP errors by email.

 

7 Powerful Reasons Why Understanding BERT Token IDs Will Transform Your NLP Skills

 


Why Send PHP Errors by Email?

While tools like Sentry or Bugsnag offer advanced monitoring, you may want to start with a simple self-hosted solution — especially for small projects or tight environments to send PHP errors by email.

Benefits:

  • Instant alerts via email
  • No external service needed
  • Reproducible context (trace + inputs)
  • Ideal for debugging live systems

Part 1: Use in Vanilla PHP (error-monitor.php)

Step 1: Include Globally

Save the following code as error-monitor.php and include it at the top of your app:

require_once 'path/to/error-monitor.php';

Step 2: Full Code – error-monitor.php

<?php

error_reporting(E_ALL);
ini_set('display_errors', 0);
ini_set('log_errors', 1);

set_error_handler('customErrorHandler');
set_exception_handler('customExceptionHandler');
register_shutdown_function('shutdownHandler');

function customErrorHandler($errno, $errstr, $errfile, $errline) {
    $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
    $errorData = [
        'type'    => getFriendlyErrorType($errno),
        'message' => $errstr,
        'file'    => $errfile,
        'line'    => $errline,
        'trace'   => print_r($trace, true),
        'input'   => getInputData()
    ];
    sendErrorEmail($errorData);
    return true;
}

function customExceptionHandler($exception) {
    $errorData = [
        'type'    => 'Uncaught Exception: ' . get_class($exception),
        'message' => $exception->getMessage(),
        'file'    => $exception->getFile(),
        'line'    => $exception->getLine(),
        'trace'   => $exception->getTraceAsString(),
        'input'   => getInputData()
    ];
    sendErrorEmail($errorData);
}

function shutdownHandler() {
    $error = error_get_last();
    if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        $errorData = [
            'type'    => getFriendlyErrorType($error['type']),
            'message' => $error['message'],
            'file'    => $error['file'],
            'line'    => $error['line'],
            'trace'   => 'Backtrace not available (fatal error)',
            'input'   => getInputData()
        ];
        sendErrorEmail($errorData);
    }
}

function getFriendlyErrorType($type) {
    return match($type) {
        E_ERROR => 'Fatal Error',
        E_WARNING => 'Warning',
        E_NOTICE => 'Notice',
        E_PARSE => 'Parse Error',
        E_CORE_ERROR => 'Core Error',
        E_COMPILE_ERROR => 'Compile Error',
        default => 'Unknown Error',
    };
}

function getInputData() {
    return [
        'GET'    => $_GET,
        'POST'   => $_POST,
        'FILES'  => $_FILES,
        'SESSION'=> $_SESSION ?? [],
        'SERVER' => $_SERVER
    ];
}

function sendErrorEmail($data) {
    if ($_ENV['APP_ENV'] !== 'production') return;

    $to = 'admin@example.com';
    $subject = '[PHP Error] ' . $data['type'];

    $message = "<h2>{$data['type']}</h2>";
    $message .= "<p><strong>Message:</strong> {$data['message']}</p>";
    $message .= "<p><strong>File:</strong> {$data['file']}</p>";
    $message .= "<p><strong>Line:</strong> {$data['line']}</p>";
    $message .= "<pre><strong>Backtrace:</strong>\n" . htmlspecialchars($data['trace']) . "</pre>";
    $message .= "<pre><strong>Input Data:</strong>\n" . htmlspecialchars(print_r($data['input'], true)) . "</pre>";

    $headers = "From: error-monitor@yourdomain.com\r\n";
    $headers .= "Content-Type: text/html; charset=UTF-8\r\n";

    mail($to, $subject, $message, $headers);
}

What It Will Automatically Capture

TypeCaptured?Notes
NoticesUndefined variables, missing array keys
WarningsDeprecated functions, include warnings
Uncaught ExceptionsAll uncaught throw new Exception()
Fatal ErrorsCaught using shutdownHandler()
Parse ErrorsNot catchable during execution
Custom try/catchYou must re-throw or log manually

TL;DR: Do I Need to Modify Code to send PHP errors by email?

SituationModify Code?
Plain PHP site❌ Just include once globally
Framework (Laravel, Symfony)✅ Add to bootstrapping
Using try/catch everywhere⚠️ Yes, call customExceptionHandler($e) manually
Want full control of reporting✅ Maybe wrap your code or use middleware

Part 2: Use in Laravel

Laravel Integration

Add this to your AppServiceProvider:

public function boot() {
    require_once base_path('error-monitor.php');
}

Make sure to:

  • Place error-monitor.php in your project root or /app/Services
  • Use $_ENV['APP_ENV'] or Laravel’s app()->environment() inside sendErrorEmail()

Optional: Laravel Exception Handler

If you want better control, modify Laravel’s native exception handler:

// app/Exceptions/Handler.php
public function report(Throwable $e)
{
    parent::report($e);

    \customExceptionHandler($e); // Optional: Call from Laravel handler
}

This approach gives you flexibility for both Laravel logging + custom email reporting.


Bonus: Only Send Emails in Production

To prevent spamming during development:

if ($_ENV['APP_ENV'] === 'production') {
sendErrorEmail($errorData);
}

Pro Tips for send PHP errors by email

  • Integrate with Mailtrap during development for safe email testing.

  • Log errors to file using file_put_contents() for offline access.

  • Combine with tools like Monolog for advanced logging.

Conclusion

Setting up automated error emails in PHP gives you:

✅ Real-time visibility into crashes
✅ Contextual debugging info
✅ Easy reproduction of bugs
✅ Simple and free alternative to error monitoring tools

Whether you’re building a plain PHP app or using Laravel, this guide will help you stay ahead of production bugs without expensive monitoring tools.

You may also like...

Creating a Shopify App using Laravel How to Create Custom WordPress Plugin? How to Build a Telegram Bot using PHP How to Convert Magento 2 into PWA?