SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    SitePoint Member
    Join Date
    Nov 2005
    Location
    Belgium
    Posts
    14
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    file_get_contents and fopen timeout

    I recently had the problem described in this post:
    http://www.sitepoint.com/forums/show...hlight=timeout

    As this thread is a bit old to post a solution, I open a new one with my solution.

    PHP functions like fopen(), fread() and file_get_contents() don't have timeout protection. That means that if the requested file or page exists but that the server is slow or fail to send the 200 OK header, your script will freeze.

    The set_time_limit() function that changes the value of the max_execution_time configuration variable has no effect on these streams. The only way to stop the frozen script is to hit the navigator stop button or wait until the web server reaches its time limit and sends a HTTP fail header.

    I see this as a shortcoming of these PHP functions.

    I have recently written a little function that simulate file_get_contents() with a timeout using CURL (also tried and succeeded with fsockopen but it's not as fast as CURL)

    The function

    PHP Code:
    /*

    UrlGetContentsCurl ( string url [, int timeout [, bool content [, int offset [, int maxlen]]]] )

    Arguments:
      string url:   url with its protocole. For ex.
                    http://www.rfc-editor.org/rfc/rfc2606.txt
                    ftp://ftp.rfc-editor.org/in-notes/rfc2606.txt
      int timeout:  time limit.
                    Optional. Default: current value of max_execution_time.
      bool content: true to get the content. False, the function returns the response time 
                    of the page or file.
                    Optional. Default: true.
      int offset:   offset applied to start the content capture.
                    Optional. Default: 0 (start of the page)
      int maxlen:   number of bytes to capture satrting at offset.
                    Optional. Default: null (all the file/page)

    Returns:
      False         failure to connect to the server or to receive a 200 OK status from the server in due time.
      String        The actual content of page/file if [content] is set to true
      Float         Response time to establish the connection to the server and to receive the 200 OK status
                    for the requested file/page ([content] set to false)

    */


    function UrlGetContentsCurl(){
      
    // parse the argument passed and set default values
      
    $arg_names    = array('url''timeout''getContent''offset''maxLen');
      
    $arg_passed   func_get_args();
      
    $arg_nb       count($arg_passed);
      if (!
    $arg_nb){
        echo 
    'At least one argument is needed for this function';
        return 
    false;
      }
      
    $arg = array (
        
    'url'       => null,
        
    'timeout'   => ini_get('max_execution_time'),
        
    'getContent'=> true,
        
    'offset'    => 0,
        
    'maxLen'    => null
      
    );
      foreach (
    $arg_passed as $k=>$v){
        
    $arg[$arg_names[$k]] = $v;
      }

      
    // CURL connection and result
      
    $ch curl_init($arg['url']);
      
    curl_setopt($chCURLOPT_HEADER0);
      
    curl_setopt($chCURLOPT_RETURNTRANSFER1);
      
    curl_setopt($chCURLOPT_USERAGENT"Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)");
      
    curl_setopt($chCURLOPT_RESUME_FROM$arg['offset']);
      
    curl_setopt($chCURLOPT_TIMEOUT$arg['timeout']);
      
    $result  curl_exec($ch);
      
    $elapsed curl_getinfo ($chCURLINFO_TOTAL_TIME);  
      
    $CurlErr curl_error($ch);
      
    curl_close($ch);
      if (
    $CurlErr) {
        echo 
    $CurlErr;
        return 
    false;
      }elseif (
    $arg['getContent']){
        return 
    $arg['maxLen']
          ? 
    substr($result0$arg['maxLen'])
          : 
    $result;
      }
      return 
    $elapsed;

    How to use it?

    PHP Code:
    $url        'http://www.rfc-editor.org/rfc/rfc2606.txt';
    $timeout    5;
    $getContent true;                               
    $offset     0;
    $maxLen     50;

    echo 
    UrlGetContentsCurl($url$timeout$getContent,  $offset$maxLen);
    // or
    echo UrlGetContentsCurl($url$timeoutfalse);
    // or
    echo UrlGetContentsCurl($url$timeout);
    // or
    echo UrlGetContentsCurl($url); 
    I benchmarked my function against the PHP fopen() and file_get_contents() and I noticed no difference in time.

    Edit: Added User-Ugent as some sites use to reject unsigned request.
    Last edited by ripat; Nov 26, 2005 at 11:53.

  2. #2
    SitePoint Zealot
    Join Date
    Dec 2001
    Posts
    198
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great, I was just in need of something like this, thanks for making it and posting it here

  3. #3
    SitePoint Evangelist
    Join Date
    Jan 2005
    Location
    UK
    Posts
    539
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is just what i need! Just wondering how i could get the content and the elapsed time returned if necessary?

  4. #4
    PHP Guru lampcms.com's Avatar
    Join Date
    Jan 2009
    Posts
    921
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry to tell you that you went to all this trouble because file_get_contents() actually does support the http timeout setting

    This is how to set the timeout to 5 and a half seconds.

    $aStreamOptions = array(
    'http' => array('timeout' => 5.5,
    'user_agent' => 'Mozilla or something like that')
    );

    $context = stream_context_create($aStreamOptions);

    // Open the file using the HTTP headers set above
    $file = file_get_contents('http://www.example.com/', false, $context);

    Simple, isnt' it?
    My project: Open source Q&A
    (similar to StackOverflow)
    powered by php+MongoDB
    Source on github, collaborators welcome!


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •