Debugging .htaccess: How to Log and Echo Variables for Effective Troubleshooting


2 views

The .htaccess file operates at the server level before your PHP code executes, making traditional debugging methods ineffective. When you need to inspect captured regex groups ($1, $2, etc.) or verify rewrite rule behavior, you need server-level logging solutions.

The most reliable way to debug .htaccess is through Apache's error logging system. Add these lines to your .htaccess:

RewriteEngine On
RewriteRule ^product/([^/]+)/([0-9]+)$ product.php?name=$1&id=$2 [L]

# Debugging
ErrorLog /path/to/your/logs/htaccess_errors.log
RewriteLog /path/to/your/logs/htaccess_rewrite.log
RewriteLogLevel 3

Remember to:

  • Use absolute paths for log files
  • Set appropriate permissions (chmod 666)
  • Disable logging in production

For capturing specific values, pass them as environment variables to PHP:

RewriteRule ^blog/([^/]+)$ blog.php?slug=$1 [E=CAPTURED_SLUG:$1,L]

<FilesMatch "\.php$">
    SetEnvIf REDIRECT_CAPTURED_SLUG ^(.+)$ CAPTURED_SLUG=$1
</FilesMatch>

Then in your PHP file:

<?php
if (getenv('CAPTURED_SLUG')) {
    file_put_contents('/path/to/debug.log', 
        date('Y-m-d H:i:s') . " - Captured slug: " . 
        getenv('CAPTURED_SLUG') . "\n", 
        FILE_APPEND);
}
?>

For complex cases, immediately route to a debug script:

RewriteRule ^test/(.*)$ debug.php?url=$1 [L]

debug.php contents:

<?php
$debug_data = [
    'timestamp' => date('c'),
    'server_vars' => $_SERVER,
    'get_params' => $_GET
];
file_put_contents(__DIR__.'/htaccess_debug.log', 
    json_encode($debug_data, JSON_PRETTY_PRINT)."\n", 
    FILE_APPEND);
?>

Always remember to:

  • Restrict log file access via .htaccess
  • Use temporary debug files only
  • Never expose sensitive data in logs
  • Disable debugging in production environments

For those who prefer GUI tools:

  • Wireshark for network-level inspection
  • Charles Proxy for request/response monitoring
  • Postman for API endpoint testing

When working with Apache's .htaccess files, particularly with complex RewriteRules, developers often struggle to inspect captured patterns ($1, $2, etc.). Unlike traditional programming environments where you can use print statements, .htaccess executes silently.

The most effective method is to configure Apache's logging to capture rewrite details. Add these directives to your virtual host configuration or .htaccess:

RewriteEngine On
RewriteRule ^(.*)$ - [E=REWRITE_DEBUG:%1]
RewriteRule ^(.*)$ - [E=REWRITE_DEBUG:%{REWRITE_DEBUG},%1]

# Then log the environment variable
SetEnvIf REWRITE_DEBUG (.+) REWRITE_DEBUG=$1
CustomLog /path/to/rewrite_debug.log "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" REWRITE_DEBUG=%{REWRITE_DEBUG}e"

For WordPress or PHP sites, create a bridge file (debug.php):

RewriteCond %{REQUEST_URI} ^/debug\.php$
RewriteRule ^ - [L]

RewriteRule ^article/([^/]+)/([0-9]+) debug.php?title=$1&id=$2 [L]

Then in debug.php:

<?php
file_put_contents('rewrite_debug.log', 
    print_r($_SERVER, true) . print_r($_GET, true), 
    FILE_APPEND);
// Rest of your normal PHP code

For quick debugging, capture values to environment variables then display them:

RewriteRule ^product/([^/]+)/?$ index.php?product=$1 [E=PRODUCT_NAME:$1]

# Later in your PHP:
echo "Captured product: " . $_SERVER['PRODUCT_NAME'];

Only log when a specific cookie is present (useful for production debugging):

RewriteCond %{HTTP_COOKIE} debug_rewrite=true
RewriteRule ^ - [E=DEBUG_REWRITE:1]

RewriteCond %{ENV:DEBUG_REWRITE} =1
RewriteRule (.*) - [E=CAPTURE_DEBUG:$1]

# Configure your logging to include %{CAPTURE_DEBUG}e