PHP Redirect: A Technical Guide to Server-Side URL Redirection

Master server-side redirects with PHP header() function, proper HTTP status codes, security best practices, and WordPress integration for optimal SEO performance.

Understanding PHP Redirects and Their Role in Technical SEO

PHP redirects are fundamental to website maintenance, search engine optimization, and site architecture management. Unlike client-side redirects that rely on JavaScript or HTML meta tags, PHP redirects happen at the server level before any content reaches the browser--making them faster, more reliable, and ideal for preserving search engine rankings.

When you implement a PHP redirect, the server sends an HTTP header instructing the browser to navigate to a different URL. This server-level interaction ensures that search engine crawlers follow redirects efficiently, transferring link equity when properly configured with the correct status codes.

This guide covers the technical implementation of server-side redirects using PHP's header() function, proper status code selection, common pitfalls to avoid, and security best practices that protect both your site and your visitors.

Key PHP Redirect Concepts

Server-Side Execution

PHP redirects execute at the server level before content is sent, making them faster and more reliable than client-side alternatives.

HTTP Status Codes

Choose between 301 (permanent) for SEO preservation or 302 (temporary) for short-term redirects with different caching behaviors.

Header Function

The header() function sends raw HTTP Location headers that instruct browsers and crawlers where to find the requested resource.

Security Considerations

Prevent open redirect vulnerabilities by validating user input against strict whitelists rather than accepting arbitrary URLs.

HTTP Status Codes for PHP Redirects

Selecting the correct HTTP status code is critical for SEO because it tells search engines how to treat the redirect and whether to transfer link equity.

301: Moved Permanently

The 301 status code indicates a permanent move to a new location. This is the most important redirect for SEO because it signals search engines to transfer all ranking power (link equity) from the old URL to the new one. Search engines update their indexes to point to the new URL and consolidate ranking signals.

Best use cases for 301 redirects:

  • Permanent page URL changes
  • Domain migrations
  • Enforcing www to non-www or HTTP to HTTPS
  • Consolidating duplicate content
  • Removing outdated content permanently

302: Found (Temporary Redirect)

The 302 status code indicates a temporary move. Search engines keep the original URL indexed and do not transfer link equity. This is appropriate for short-term scenarios where the original URL will return to service.

Best use cases for 302 redirects:

  • A/B testing landing pages
  • Geographic redirects based on user location
  • Temporary maintenance pages
  • Redirecting after form submissions

307 and 308: Modern Alternatives

The 307 status code guarantees that the request method will not change (e.g., a POST request remains POST). The 308 status code is the permanent equivalent that also preserves the request method. These are less commonly used but important for specific API and form handling scenarios. For a deeper dive into redirect chains and how they impact your SEO, see our guide on redirect chains.

Basic PHP Redirect with 301 Status Code
1<?php2// 301 Permanent Redirect - preserves link equity3header("HTTP/1.1 301 Moved Permanently");4header("Location: /new-page.php");5exit;6 7// Alternative shorthand syntax8header("Location: /new-page.php", true, 301);9exit;

Common Technical Issues and Solutions

The "Headers Already Sent" Error

This is the most common PHP redirect error developers encounter. The header() function must be called before any output is sent to the browser--including HTML, whitespace, or even a UTF-8 BOM (Byte Order Mark). When output precedes the header call, PHP cannot modify the HTTP headers, and the redirect fails.

Common causes:

  • Whitespace before the opening <?php tag
  • HTML content or echo statements before the redirect
  • UTF-8 BOM characters in included files
  • Error messages or warnings output before the redirect

Solution 1: Place redirect logic at the top

<?php
// Redirect must be the first code executed
if ($needs_redirect) {
 header("Location: /new-page.php");
 exit;
}
// All other code comes after
?>
<!DOCTYPE html>

Solution 2: Use output buffering as a fallback

<?php
ob_start(); // Start output buffering
// ... your code here ...
echo "This output won't break the redirect";
header("Location: /new-page.php");
ob_end_flush();
exit;

Output buffering is a "duct tape" solution--better to structure your code to avoid the need for it.

Forgetting the exit() After header()

A critical but often overlooked issue is failing to call exit; or die(); after the redirect header. The PHP script continues executing even after sending the redirect header, which can cause security vulnerabilities, unexpected behavior, and performance issues.

Always include exit after header:

<?php
header("Location: /new-page.php");
exit; // Critical: stops script execution

Without exit;, code after the redirect will still execute, potentially exposing sensitive information or performing unintended actions. When implementing redirects at scale for your web development projects, consider using server-level redirects for better performance.

Security Best Practices

Preventing Open Redirect Vulnerabilities

Open redirect vulnerabilities occur when user-supplied input is used directly in redirect targets without validation. Attackers can exploit this to send users to malicious sites while making the link appear trustworthy.

Vulnerable code (NEVER use):

<?php
// DANGEROUS: User input directly in redirect
$redirect_url = $_GET['url'];
header("Location: " . $redirect_url);
exit;

Secure implementation using whitelist approach:

<?php
// Whitelist approach: only allow known safe URLs
$allowed_urls = [
 '/dashboard',
 '/profile',
 '/settings'
];

if (isset($_GET['url']) && in_array($_GET['url'], $allowed_urls)) {
 header("Location: " . $_GET['url']);
 exit;
} else {
 header("Location: /default-page.php");
 exit;
}

Always validate and sanitize user input used in redirects. The whitelist approach is the most secure method for dynamic redirect targets.

Relative vs. Absolute URLs

Use absolute URLs (starting with http:// or https://) for maximum compatibility, especially when redirecting across domains:

<?php
// Best practice: absolute URL
header("Location: https://example.com/new-page.php");

// Also valid: root-relative URL
header("Location: /new-page.php");

// Potentially problematic: relative URL
header("Location: new-page.php");

For WordPress-specific implementations, our guide on WordPress redirects covers these security practices in the context of the WordPress ecosystem.

Validation and Monitoring

Testing Redirect Implementation

Proper validation ensures redirects work correctly and don't create issues for users or search engines:

  1. Browser testing: Manually visit the old URL and verify the browser redirects to the new location
  2. Developer tools: Check the Network tab for proper 301/302 status codes
  3. cURL verification: Test redirects from command line
# Check redirect status and destination
curl -I http://old-url.com
# Look for "HTTP/" status code and "Location:" header
  1. Search console: Monitor for crawl errors or redirect chains in Google Search Console

Detecting Redirect Chains

Redirect chains occur when one redirect points to another redirect, creating a chain of multiple hops. This wastes crawl budget and can dilute link equity:

# Use curl to trace redirect chain
curl -L -v http://old-url.com 2>&1 | grep -E "(< HTTP|< Location)"

The goal is to create direct single-hop redirects, avoiding chains to maximize crawler efficiency and preserve link equity. Learn more about avoiding common pitfalls in our comprehensive guide to redirect chains.

Monitoring with Server Logs

Server logs provide insight into redirect behavior and potential issues:

# Check Apache access logs for redirect activity
tail -f /var/log/apache2/access.log | grep "301\|302"

# Filter for specific redirect patterns
grep "redirect-from-old-page" /var/log/nginx/access.log

WordPress Integration

Using template_redirect Hook

In WordPress, use the template_redirect action hook to implement redirects. This ensures the redirect runs at the right point in WordPress loading sequence:

<?php
add_action('template_redirect', 'custom_page_redirect');
function custom_page_redirect() {
 if (is_page('old-page-slug')) {
 wp_redirect(home_url('/new-page-slug/'), 301);
 exit;
 }
}

Using WordPress's wp_redirect() function is preferred over the raw header() function because it provides better integration with WordPress internals and filters.

Common WordPress Redirect Scenarios

1. Force trailing slashes:

add_action('template_redirect', 'force_trailing_slash');
function force_trailing_slash() {
 if (preg_match('/\/[^\.]+$/', $_SERVER['REQUEST_URI'])) {
 wp_redirect(rtrim(home_url($_SERVER['REQUEST_URI']), '/') . '/', 301);
 exit;
 }
}

2. Redirect after form submission:

add_action('form_submission_handler', 'redirect_after_form');
function redirect_after_form($form_data) {
 wp_redirect(add_query_arg('status', 'success', $_SERVER['HTTP_REFERER']));
 exit;
}

For WordPress users who prefer plugin-based solutions, our guide on the best redirect plugins for WordPress covers both free and premium options for managing redirects without coding.

Performance Considerations

Cache Control for Redirects

While browsers handle 301 redirects aggressively (caching them for extended periods), temporary redirects (302, 307) are not cached by default:

<?php
header("Location: /temporary-page.php", true, 302);
header("Cache-Control: no-store, no-cache, must-revalidate");
exit;

Minimizing Redirect Impact

For optimal performance and SEO:

  1. Implement redirects at the server level (.htaccess or nginx.conf) when possible for faster processing
  2. Avoid redirect chains--go directly from source to final destination
  3. Use 301 for permanent moves to leverage browser caching
  4. Monitor crawl stats to identify redirect-related crawl budget waste

Example .htaccess redirect (server-level, faster than PHP):

Redirect 301 /old-page.php /new-page.php

Server-level redirects execute before PHP is even invoked, making them the fastest option for permanent redirects. To learn when to use server-level redirects versus PHP implementations, see our guide on static redirects.

Frequently Asked Questions About PHP Redirects

Summary: PHP Redirect Best Practices

PHP redirects are a fundamental tool for site maintenance and SEO. The key principles to remember:

AspectBest Practice
ImplementationAlways use header("Location: ...") with exit; immediately after
Status CodesUse 301 for permanent moves (preserves SEO), 302 for temporary
OutputPlace redirect logic before any HTML or echo output
SecurityValidate user input using whitelist approach for dynamic redirects
TestingUse browser tools and curl to verify redirect behavior
ChainsAvoid redirect chains--go directly from source to destination
WordPressUse wp_redirect() with template_redirect hook

Properly implemented PHP redirects preserve link equity, improve user experience, and maintain search engine visibility during site changes. By following these technical guidelines, you can confidently manage URL changes, migrations, and content restructuring without sacrificing your search rankings.

When implementing redirects for a production site, always test in a staging environment first, verify the correct HTTP status codes are being returned, and monitor Google Search Console for any crawl errors that might indicate issues with your redirect implementation. For comprehensive technical SEO audits and redirect strategy implementation, our technical SEO services can help ensure your site maintains optimal search visibility.

Need Help with Your SEO Technical Implementation?

Our technical SEO experts can help you implement proper redirects, optimize site architecture, and ensure your website maintains search visibility during changes.