HTTP Fetching in PHP Without cURL
Page last updated on 2011 / 04 / 09On 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.
<?php class streams { /* A class to perform HTTP requests,handy if cURL is unavailable See the examples at the foot of the page for usage */ // Prepares some variables and HTTP headers for the fetch public function read_stream_http_variables($request,$uri,&$array) { $line = preg_replace("'^[^/]+//'",'',$uri); preg_match("'^([a-z0-9-.:@]+)(.+)$'i",$line,$n); if(!isset($n[1])) RETURN FALSE; if(preg_match("':d+$'",$n[1],$o)) { $n[2] = $o[0].$n[2]; $n[1] = preg_replace("'{$o[0]}$'",'',$n[1]); } $n[1] = trim(strtolower($n[1])); $n[2] = trim($n[2]); $array['host'] = $n[1]; $array['url'] = $n[2]; if(!isset($array['fputs']) || !is_array($array['fputs'])) $array['fputs'] = array(); array_unshift($array['fputs'],$request.' '.$array['url']." HTTP/1.1\r\n"); if(!isset($array['fputs']['User-Agent'])) $array['fputs']['User-Agent'] = 'User-Agent: Mozilla/6.0 (Windows; Windows NT 4.0; en-US;)'."\r\n"; if(!isset($array['fputs']['Accept'])) $array['fputs']['Accept'] = "Accept: */*\r\n"; array_push($array['fputs'],"Host: {$array['host']}\r\n"); if(!isset($array['fputs']['Connection'])) $array['fputs']['Connection'] = "Connection: Close\r\n"; if($request == 'POST' && isset($array['POST'])) { array_push($array['fputs'],"Content-Length: ".strlen($array['POST'])."\r\n"); array_push($array['fputs'],'Content-Type: application/x-www-form-urlencoded'."\r\n"); array_push($array['fputs'],"\r\n{$array['POST']}"); } else array_push($array['fputs'],"\r\n"); } // Perform the HTTP request. HTTP Headers and the HTTP document are separated public function read_stream($request,$host,$port,$timeout) { $fp = fsockopen($host,$port,$errno,$errstr,$timeout); if(!$fp) RETURN array(0,$errno,$errstr); else { if($request) // For separating the HEAD and BODY of HTTP requests $head = TRUE; else $head = FALSE; if(count($data['fputs'])) fputs($fp,implode('',$data['fputs'])); while(!feof($fp)) { if($head) { if(!trim($line = fgets($fp))) $head = FALSE; else { $line = preg_split("':\s*'",rtrim($line),2); @$data['headers'][strtolower($line[0])] = $line[1]; } } else $data['output'] .= fread($fp,65536); } if(isset($data['headers']['transfer-encoding']) || isset($data['headers']['content-encoding'])) $data['output'] = $this->decode_body($data['headers'],$data['output']); } } // 'Normalizes' the HTTP document if any transfer/content encoding was used public function decode_body($info,$str,$eol = "\r\n") { $tmp = $str; $add = strlen ($eol); $str = ''; if(isset($info['transfer-encoding']) && $info['transfer-encoding'] == 'chunked') { do { $tmp = ltrim($tmp); $pos = strpos($tmp,$eol); $len = hexdec(substr($tmp,0,$pos )); if(isset($info['content-encoding'] ) ) $str .= gzinflate(substr($tmp,($pos + $add + 10 ),$len )); else $str .= substr($tmp,($pos + $add ),$len); $tmp = substr($tmp,($len + $pos + $add )); $check = trim($tmp); } while(!empty($check)); } elseif(isset($info['content-encoding'])) $str = gzinflate(substr($tmp,10)); else RETURN $tmp; return $str; } } // Example 1 - HTTP Fetching (GET) $_streams = new streams; $url = 'www.yahoo.com/'; $data = array(); $_streams->read_stream_http_variables('GET',$url,$data); $_streams->read_stream(1,$data['host'],80,5,$data); print_r($data); exit(0); // Example 2 - HTTP Fetching (POST) $_streams = new streams; $url = 'www.yahoo.com/'; $data = array('POST'=>'postvar1=1&postvar2=2','output'=>'','headers'=>array()); $_streams->read_stream_http_variables('POST',$url,$data); $_streams->read_stream(1,$data['host'],80,5,$data); print_r($data); exit(0); // Example 3 - WHOIS Fetching $_streams = new streams; $domain = 'example.net'; $data = array('fputs'=>array($domain."\r\n"),'output'=>''); $_streams->read_stream(0,'whois.internic.net',43,5,$data); print_r($data); exit(0); ?>
Tweet