如何使用数组从php函数获取值

时间:2012-01-16 16:03:50

标签: php arrays

我有以下代码,当我尝试从数组$headers中获取值时,没有任何内容出现,但是当我使用var_dump($headers)时,它会显示所有数组值。我做错了什么?

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');

输出

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 个答案:

答案 0 :(得分:1)

看起来问题是换行符。

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

 !=

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

删除尾随的新行/回车。

答案 1 :(得分:1)

您依赖于特定位置的某个标头,它并不总是如此,并且您也没有说明HTTP标头密钥不区分大小写的事实。

试试这个:

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;
    }

}

答案 2 :(得分:1)

你需要在这样的开关中使用trim功能:

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

由于表面,所以标题数组中的所有行都在最后都有EOL。

答案 3 :(得分:0)

当我在计算机上运行测试时,标题大小仅为7(包括两个空白行)。你应该做的是在标题的earch行上寻找一个模式并采取行动。

例如:

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

      }
   }
}

如果你想操纵标题,一个好主意可能是用标题构建一个关联数组,这样你就可以使用协议名称访问一个项目(例如:$headers['location'])。只需使用':'爆炸标题即可为密钥应用strtolower。可能会有帮助。