How to configure CORS in PHP

Enable Cross-Origin Resource Sharing (CORS) in PHP by setting Access-Control response headers with the header() function before any output.

Configure Cross-Origin Resource Sharing (CORS) headers in PHP by calling the header() function at the top of the script to allow cross-origin requests.

Prerequisites

  • PHP 7.4 or later installed.
  • A web server (Apache HTTP Server or Nginx) configured to serve PHP files.

Step-by-Step: Enable CORS in PHP

  1. Add the Cross-Origin Resource Sharing (CORS) headers at the top of the PHP file, before any HTML output or echo statements. The header() function sets HTTP response headers in PHP.

    Option A: Allow all origins-- Set the wildcard * for public APIs that do not use cookies or authentication:

    <?php
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');

    Option B: Allow a specific origin-- Replace the wildcard with the exact origin URL:

    <?php
    header('Access-Control-Allow-Origin: https://app.example.com');
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');
    header('Access-Control-Allow-Credentials: true');

    Option C: Allow multiple origins-- Validate the Origin request header against an allowlist and set the matching origin in the response:

    <?php
    $allowed_origins = [
        'https://app.example.com',
        'https://admin.example.com',
    ];
    
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
    
    if (in_array($origin, $allowed_origins, true)) {
        header("Access-Control-Allow-Origin: $origin");
        header('Vary: Origin');
    }
    
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');
    header('Access-Control-Allow-Credentials: true');
  2. Handle preflight OPTIONS requests in PHP. Return a 204 No Content response for OPTIONS requests so the browser receives the CORS headers without processing the full script:

    <?php
    header('Access-Control-Allow-Origin: https://app.example.com');
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');
    header('Access-Control-Max-Age: 86400');
    
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
        http_response_code(204);
        exit;
    }
    
    // Application logic below

How to Verify CORS Is Working in PHP

Send a test request with curl to confirm the PHP script returns Cross-Origin Resource Sharing (CORS) headers:

curl -I -H "Origin: https://app.example.com" https://api.example.com/endpoint.php

The response should include:

Access-Control-Allow-Origin: https://app.example.com

Common Issues When Configuring CORS in PHP

  • Headers already sent.PHP throws a "headers already sent" warning if header() is called after output. Place all header() calls before any echo, HTML, or whitespace outside <?php tags.
  • Duplicate CORS headers.The web server (Apache or Nginx) and PHP both set Access-Control-Allow-Origin. The browser rejects responses with duplicate CORS headers. Set CORS in one layer only.
  • Preflight returns the full page.OPTIONS requests execute the entire PHP script if not intercepted. Check $_SERVER['REQUEST_METHOD'] and exit early for OPTIONS.

For a detailed explanation of the CORS mechanism, see CORS tutorial: How Cross-Origin Resource Sharing works.