Seo tools

Neo Inspiration

  • Search

    • About Me

      • inspi 改め
        jakk@webアーキテクト(自称)
        php,javascript,seoなど
        得意技は extract();



  • Categories

  • Ranking

  • Comments

  • Others


  • php の file_get_contents で true も false も返ってこない

    特定のURLでfile_get_contents で true も false も返ってこない現象があって
    困っていたのでその対策メモ

    現象

    単純に

    $html = file_get_contents($url);

    ってやるとタイムアウトすることがあって、
    それは
    ini_set(’default_socket_timeout’,3);
    ってやってもダメなパターン。

    問題はタイムアウトじゃない?

    file_get_contentsがだめでもこれ以上切り分けできないので、
    処理を1個づつかくために fsockopen 使ってみたけどやっぱりだめ。

    fsockopen がダメな時のソースはこんなかんじ。

    $fp = fsockopen($server,80,$errno,$errstr,$timeout);
    if($fp){
      while(!feof($fp)){
        $data .= fread($fp, 1024);
      }
    }
    echo $data;

    で こっから1こづつ切り分けていくと
    どうも

    while(!feof($fp)){
      $data .= fread($fp,1024);
    }

    ここが無限ループになってるらしい。

    file_get_contentsのCソースまでは追いきれないので
    (Cソース探したけどどこにあるかわからなくて)
    カンですが、file_get_contents も同じ感じの処理をしていて、
    feof のとこで詰まってるんじゃないかと。
    だとしたら、ソケットの問題じゃないので、default_socket_timeout を指定しても意味なかったってわけです。

    こうやって解決

    問題が無限ループだったので php feof で検索したら・・・

    関連検索: php feof 無限ループ, php feof fgets

    同じ問題で詰まった人がいっぱいいるw!

    で見ていくと

    http://jp.php.net/feof
    無効なファイルポインタを渡した場合、無限ループに陥ることがあります。 なぜなら EOF が TRUE を返すことができないからです。

    ということらしい。

    つまり feof が true を返さないので、feof で判定するのはダメなわけだ。
    おそらく何らかの形でEOFが受信できない場合も trueが返らないんだろう。。
    なので feof じゃなくて fread が成功したかで判定するように変更

    $fp = fsockopen($server,80,$errno,$errstr,$timeout);
    if($fp){
    while($eof_check= fread($fp,1024)){
      $data .= $eof_check;
    }
    }
    echo $data;

    したら うまくいった!

    ってことで

    結局こんな感じの関数作って対処しました。

    function ex_file_get_contents($server=”,$timeout=10){
      $data = ”;
      if(isset($server)){
        $fp = @fsockopen($server, 80,$errno, $errstr, $timeout);
        if($fp){
          while($eof_check=@fread($fp, 1024)){
            $data .= $eof_check;
          }
          @fclose($fp);
        }else{
          return false;
        }
      }else{
        return false;
      }
      return $data;
    }


    Leave a Reply

    2008/11/22 01:54:52