0

I have the following code and when i try to get a value from the array $headers nothing appears, but when I use var_dump($headers) it shows all the array values. What Am I doing wrong?

function linkcheck($url) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $headers = explode("\n", curl_exec($ch));
    curl_close($ch);

    switch ($headers[18]) {
        case "Location: https://somewebsite.com/welcome":
            echo "Actice";
            break;
        case "Location: https://somewebsite.com/no_such_link":
            echo "Inactive";
            break;

    }
}

echo linkcheck('http://somewebsite.com/54sdf');

Output

array(37) {
  [0]=>
  string(19) "HTTP/1.1 302 Found
"
  [1]=>
  string(39) "Content-Type: text/html; charset=utf-8
"
  [2]=>
  string(18) "Connection: close
"
  [3]=>
  string(12) "Status: 302
"
  [4]=>
  string(60) "X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.10
"
  [5]=>
  string(34) "X-UA-Compatible: IE=Edge,chrome=1
"
  [6]=>
  string(47) "Location: https://somewebsite.com/54sdf
"
  [7]=>
  string(20) "X-Runtime: 0.006921
"
  [8]=>
  string(132) "Set-Cookie: _sp_session_id=; domain=.superpoints.com; path=/; expires=Mon, 16-Jan-2012 18:08:29 GMT
"
  [9]=>
  string(24) "Cache-Control: no-cache
"
  [10]=>
  string(69) "Server: nginx/0.7.65 + Phusion Passenger 2.2.10 (mod_rails/mod_rack)
"
  [11]=>
  string(1) "
"
  [12]=>
  string(19) "HTTP/1.1 302 Found
"
  [13]=>
  string(39) "Content-Type: text/html; charset=utf-8
"
  [14]=>
  string(18) "Connection: close
"
  [15]=>
  string(12) "Status: 302
"
  [16]=>
  string(60) "X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.10
"
  [17]=>
  string(34) "X-UA-Compatible: IE=Edge,chrome=1
"
  [18]=>
  string(55) "Location: https://somewebsite.com/no_such_link
"
}
4
  • can you post the output of var_dump($headers)? Commented Jan 16, 2012 at 16:05
  • Are you sure that the "keys" of the $headers array are integers? What does the print_r output of $headers look like (an example would be useful). Commented Jan 16, 2012 at 16:05
  • when i echo out 18 i get the value but when i place it into the switch it doesnt do anything Commented Jan 16, 2012 at 16:13
  • Try setting CURLOPT_FOLLOWLOCATION to false. It's following the redirect, so when cURL's done, the headers may be from that page instead. Commented Jan 16, 2012 at 16:15

4 Answers 4

1

You are relying on a certain header being at a certain position, which it will not always be, and you are also not acounting for the fact the HTTP header keys are case-insensitive.

Try this:

function linkcheck($url) {

    // Do cURL
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    $response = explode("\n", curl_exec($ch));
    curl_close($ch);

    // Seperate headers from body
    $parts = explode("\r\n\r\n", $response);

    // Turn headers into associative array
    $head = explode("\r\n", $parts[0]);
    array_shift($head); // Skip response line
    $headers = array();
    foreach ($head as $header) {
        $header = explode(':', $header);
        $key = strtolower(trim(array_shift($header)));
        $val = trim(implode(':', $header));
        if (isset($headers[$key])) {
            if (is_array($headers[$key])) {
                $headers[$key][] = $val;
            } else {
                $headers[$key] = array($headers[$key], $val);
            }
        } else {
            $headers[$key] = $val;
        }
    }

    // If there is no location header, we can't test it
    if (!isset($headers['location'])) {
        echo "No location header";
        return;
    }

    switch ($headers['location']) {
        case "https://somewebsite.com/welcome":
            echo "Active";
            break;
        case "https://somewebsite.com/no_such_link":
            echo "Inactive";
            break;
        default:
            echo "Unknown value";
            break;
    }

}
Sign up to request clarification or add additional context in comments.

Comments

1

It looks the the issue is line breaks.

"Location: https://somewebsite.com/no_such_link
"

 !=

"Location: https://somewebsite.com/no_such_link"

remove the trailing new lines/carriage returns.

Comments

1

You need to use trim function in switch like this:

switch (trim($headers[18])) {
    case "Location: https://somewebsite.com/welcome":
        echo "Actice";
        break;
    case "Location: https://somewebsite.com/no_such_link":
        echo "Inactive";
        break;
}

It is due the face that all the lines in your headers array have an EOL at the end.

Comments

0

When I ran the test on my computer, the header size was only 7 (including two blank lines). What you should do is looking for a pattern on earch line of the headers and take action.

For instance:

foreach ($headers AS $line) {
   if (strpos('Location', $line)) {
      list ($loc, $url) = explode(':', $line);
      if ($url == 'keyword') { 
        // do stuff

      }
   }
}

If you want to manipulate headers, a good idea could be to build an associative array with headers, so that you can access an item with the protocols name (eg: $headers['location']). Just explode headers with ':' an apply an strtolower for the key. May be helpful.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.