Testing HTTP Redirects in PHP

For a task today, I wanted to verify that redirects on a website were working as expected after migrating them from one redirect plugin to another one (yes, this site had 2 enabled). I couldn’t figure out the right invocation to test them using cURL in PHP, even though the documentation seemed straightforward (just set follow redirects to false…didn’t work).

At the end of the day, I initially got it working by using curl from the command line, then parsing the headers it spits back. The switches are s, k, and capital i). That makes the initial request and returns the headers without following any Location headers

exec( "curl -skI " . escapeshellarg( $url ), $output );

But, I really wanted to know it could be done without dropping to the shell. And of course, there is a way to do it, using stream filters. I got tripped up in creating the context. At first, I had max_redirect and follow_location in the ssl block, but they were ignored. I didn’t realize you could specify options across “protocols” but it is totally doable—all with native PHP functionality:

$url = "https://www.oscarm.org";

$opts = [
    'ssl' => [
        'method' => 'GET',
        'verify_peer' => false,
        'allow_self_signed' => true,
    'http' => [
        'max_redirects' => 1,
        'follow_location' => 0,

$context = stream_context_create($opts);
$stream = fopen($url, 'r', false, $context);

// header information as well as meta data
// about the stream
$headers = stream_get_meta_data($stream);