2010-06-14 2 views
0

Im en utilisant ce code ici: http://www.digiways.com/articles/php/httpredirects/En utilisant PHP pour lire une page Web avec fsockopen(), mais fgets ne fonctionne pas

public function ReadHttpFile($strUrl, $iHttpRedirectMaxRecursiveCalls = 5) 
    { 
     // parsing the url getting web server name/IP, path and port. 
     $url = parse_url($strUrl); 
     // setting path to '/' if not present in $strUrl 
     if (isset($url['path']) === false) 
     $url['path'] = '/'; 
     // setting port to default HTTP server port 80 
     if (isset($url['port']) === false) 
    $url['port'] = 80; 
     // connecting to the server] 



     // reseting class data   
     $this->success = false; 
     unset($this->strFile); 
     unset($this->aHeaderLines); 
     $this->strLocation = $strUrl; 
    $fp = fsockopen ($url['host'], $url['port'], $errno, $errstr, 30); 
     // Return if the socket was not open $this->success is set to false. 
     if (!$fp) 
      return; 
    $header = 'GET/HTTP/1.1\r\n'; 
    $header .= 'Host: '.$url['host'].$url['path']; 
    if (isset($url['query'])) 
    $header .= '?'.$url['query']; 
    $header .= '\r\n'; 
    $header .= 'Connection: Close\r\n\r\n'; 
    // sending the request to the server 
    echo "Header is: <br />".str_replace('\n', '\n<br />', $header)."<br />"; 
    $length = strlen($header); 
    if($length != fwrite($fp, $header, $length)) 
    { 
    echo 'error writing to header, exiting<br />'; 
    return; 
    } 
    // $bHeader is set to true while we receive the HTTP header 
    // and after the empty line (end of HTTP header) it's set to false. 
    $bHeader = true; 
    // continuing untill there's no more text to read from the socket 
    while (!feof($fp)) 
    { 
    echo "in loop"; 
    // reading a line of text from the socket 
    // not more than 8192 symbols. 
    $good = $strLine = fgets($fp, 128); 
    if(!$good) 
    { 
    echo 'bad'; 
    return; 
    } 
    // removing trailing \n and \r characters. 
    $strLine = ereg_replace('[\r\n]', '', $strLine); 
    if ($bHeader == false) 
    $this->strFile .= $strLine.'\n'; 
    else 
    $this->aHeaderLines[] = trim($strLine); 
    if (strlen($strLine) == 0) 
    $bHeader = false; 
    echo "read: $strLine<br />"; 
    return; 
    } 
    echo "<br />after loop<br />"; 
    fclose ($fp); 

    } 

C'est tout ce que j'obtiens:

Header is: 
GET/HTTP/1.1\r\n 
Host: www.google.com/\r\n 
Connection: Close\r\n\r\n 
in loopbad 

Il échoue les fgets ($ fp, 128);

Répondre

1

Y at-il une raison que vous n'utilisez pas intégré dans PHP, activée par défaut la capacité de récupérer des fichiers distants en utilisant fopen?

$remote_page = file_get_contents('http://www.google.com/'); // <- Works! 

Il y a aussi beaucoup de haute qualité des bibliothèques tierces, si vous avez besoin de faire quelque chose comme aller chercher les en-têtes sans penser trop dur. Essayez Zend_Http_Client sur la taille.

1

La faille est ici:

$good = $strLine = fgets($fp, 128); 
if(!$good) 
{ 
echo 'bad'; 
return; 
} 

fgets() retourne soit une chaîne en cas de succès, ou en cas d'échec. Cependant, s'il n'y avait pas plus de données à retourner, fgets() retourne la chaîne vide (''). Ainsi, les deux $good et $strLine sont mis à la chaîne vide, ce qui se fera un plaisir PHP jeté FALSE dans le test if(). Vous devez réécrire comme suit:

$strLine = fgets($fp, 128); 
if ($strLine === FALSE) { // strict comparison - types and values must match 
    echo 'bad'; 
    return; 
} 

Il n'y a pas besoin de la double affectation, que vous pouvez tester $strLine directement.

Questions connexes