HTTP Fetching in PHP Without cURL

Page last updated on 2011 / 04 / 09

On some shared hosting accounts, cURL, fopen or file_get_contents functions may be disabled 'for security reasons', yet you can still achieve HTTP fetching using socket functions.

This simple class of code will allow you to do a wide range of HTTP fetching. It should be easy enough to customise should you feel the need to. Check out the 3 examples provided at the foot of the code to try it out. You should be able to use this code with plain old PHP, with no extra functionality.

  1. <?php
  2.  
  3. class streams
  4. {
  5. /*
  6. A class to perform HTTP requests,handy if cURL is unavailable
  7. See the examples at the foot of the page for usage
  8. */
  9.  
  10. // Prepares some variables and HTTP headers for the fetch
  11. public function read_stream_http_variables($request,$uri,&$array)
  12. {
  13. $line = preg_replace("'^[^/]+//'",'',$uri);
  14. preg_match("'^([a-z0-9-.:@]+)(.+)$'i",$line,$n);
  15. if(!isset($n[1]))
  16. RETURN FALSE;
  17. if(preg_match("':d+$'",$n[1],$o))
  18. {
  19. $n[2] = $o[0].$n[2];
  20. $n[1] = preg_replace("'{$o[0]}$'",'',$n[1]);
  21. }
  22. $n[1] = trim(strtolower($n[1]));
  23. $n[2] = trim($n[2]);
  24.  
  25. $array['host'] = $n[1];
  26. $array['url'] = $n[2];
  27.  
  28. if(!isset($array['fputs']) || !is_array($array['fputs']))
  29. $array['fputs'] = array();
  30. array_unshift($array['fputs'],$request.' '.$array['url']." HTTP/1.1\r\n");
  31. if(!isset($array['fputs']['User-Agent']))
  32. $array['fputs']['User-Agent'] = 'User-Agent: Mozilla/6.0 (Windows; Windows NT 4.0; en-US;)'."\r\n";
  33. if(!isset($array['fputs']['Accept']))
  34. $array['fputs']['Accept'] = "Accept: */*\r\n";
  35. array_push($array['fputs'],"Host: {$array['host']}\r\n");
  36. if(!isset($array['fputs']['Connection']))
  37. $array['fputs']['Connection'] = "Connection: Close\r\n";
  38.  
  39. if($request == 'POST' && isset($array['POST']))
  40. {
  41. array_push($array['fputs'],"Content-Length: ".strlen($array['POST'])."\r\n");
  42. array_push($array['fputs'],'Content-Type: application/x-www-form-urlencoded'."\r\n");
  43. array_push($array['fputs'],"\r\n{$array['POST']}");
  44. }
  45. else
  46. array_push($array['fputs'],"\r\n");
  47. }
  48. // Perform the HTTP request. HTTP Headers and the HTTP document are separated
  49. public function read_stream($request,$host,$port,$timeout)
  50. {
  51. $fp = fsockopen($host,$port,$errno,$errstr,$timeout);
  52. if(!$fp)
  53. RETURN array(0,$errno,$errstr);
  54. else
  55. {
  56. if($request) // For separating the HEAD and BODY of HTTP requests
  57. $head = TRUE;
  58. else
  59. $head = FALSE;
  60. if(count($data['fputs']))
  61. fputs($fp,implode('',$data['fputs']));
  62. while(!feof($fp))
  63. {
  64. if($head)
  65. {
  66. if(!trim($line = fgets($fp)))
  67. $head = FALSE;
  68. else
  69. {
  70. $line = preg_split("':\s*'",rtrim($line),2);
  71. @$data['headers'][strtolower($line[0])] = $line[1];
  72. }
  73. }
  74. else
  75. $data['output'] .= fread($fp,65536);
  76. }
  77. if(isset($data['headers']['transfer-encoding']) || isset($data['headers']['content-encoding']))
  78. $data['output'] = $this->decode_body($data['headers'],$data['output']);
  79. }
  80. }
  81. // 'Normalizes' the HTTP document if any transfer/content encoding was used
  82. public function decode_body($info,$str,$eol = "\r\n")
  83. {
  84. $tmp = $str;
  85. $add = strlen ($eol);
  86. $str = '';
  87. if(isset($info['transfer-encoding']) && $info['transfer-encoding'] == 'chunked')
  88. {
  89. do
  90. {
  91. $tmp = ltrim($tmp);
  92. $pos = strpos($tmp,$eol);
  93. $len = hexdec(substr($tmp,0,$pos ));
  94. if(isset($info['content-encoding'] ) )
  95. $str .= gzinflate(substr($tmp,($pos + $add + 10 ),$len ));
  96.  
  97. else
  98. $str .= substr($tmp,($pos + $add ),$len);
  99. $tmp = substr($tmp,($len + $pos + $add ));
  100. $check = trim($tmp);
  101. } while(!empty($check));
  102. }
  103. elseif(isset($info['content-encoding']))
  104. $str = gzinflate(substr($tmp,10));
  105. else
  106. RETURN $tmp;
  107.  
  108. return $str;
  109. }
  110. }
  111.  
  112. // Example 1 - HTTP Fetching (GET)
  113. $_streams = new streams;
  114. $url = 'www.yahoo.com/';
  115.  
  116. $data = array();
  117. $_streams->read_stream_http_variables('GET',$url,$data);
  118. $_streams->read_stream(1,$data['host'],80,5,$data);
  119. print_r($data);
  120. exit(0);
  121.  
  122. // Example 2 - HTTP Fetching (POST)
  123. $_streams = new streams;
  124. $url = 'www.yahoo.com/';
  125.  
  126. $data = array('POST'=>'postvar1=1&postvar2=2','output'=>'','headers'=>array());
  127. $_streams->read_stream_http_variables('POST',$url,$data);
  128. $_streams->read_stream(1,$data['host'],80,5,$data);
  129. print_r($data);
  130. exit(0);
  131.  
  132. // Example 3 - WHOIS Fetching
  133. $_streams = new streams;
  134. $domain = 'example.net';
  135.  
  136. $data = array('fputs'=>array($domain."\r\n"),'output'=>'');
  137. $_streams->read_stream(0,'whois.internic.net',43,5,$data);
  138. print_r($data);
  139. exit(0);
  140.  
  141.  
  142. ?>
  143.  

Next Article
Forking with PHP from the Command Line




Tweet