HTTP запрос средствами PHP (POST/GET)
Для определенного приложения, мне необходимо было написать функцию, для выполнения HTTP-запроса к внешним сайтам.
Релизовал функцию позволяющую это делать:
/**
* HTTP Request v1.0 by Denik
* Parametres:
* - (string) or (array)[url] - site url
* - [method] - POST | GET
* - [data] - array of post data
* - [port] - connection port
* - [timeout] - timeout connection
* - [redirect] - true, allow redirects in headers
* - [return] - content|headers|array - type of return data, default - content
* - [cookie] - allow to set cookies
* - [referer] - allow to set referer url
**/
function http_request($params)
{
if( ! is_array($params) )
{
$params = array(
'url' => $params,
'method' => 'GET'
);
}
if( $params['url']=='' ) return FALSE;
if( ! isset($params['method']) ) $params['method'] = (isset($params['data'])&&is_array($params['data'])) ? 'POST' : 'GET';
$params['method'] = strtoupper($params['method']);
if( ! in_array($params['method'], array('GET', 'POST')) ) return FALSE;
/* Приводим ссылку в правильный вид */
$url = parse_url($params['url']);
if( ! isset($url['scheme']) ) $url['scheme'] = 'http';
if( ! isset($url['path']) ) $url['path'] = '/';
if( ! isset($url['host']) && isset($url['path']) )
{
if( strpos($url['path'], '/') )
{
$url['host'] = substr($url['path'], 0, strpos($url['path'], '/'));
$url['path'] = substr($url['path'], strpos($url['path'], '/'));
}
else
{
$url['host'] = $url['path'];
$url['path'] = '/';
}
}
$url['path'] = preg_replace("/[\\/]+/", "/", $url['path']);
if( isset($url['query']) ) $url['path'] .= "?{$url['query']}";
$port = isset($params['port']) ? $params['port']
: ( isset($url['port']) ? $url['port'] : ($url['scheme']=='https'?443:80) );
$timeout = isset($params['timeout']) ? $params['timeout'] : 30;
if( ! isset($params['return']) ) $params['return'] = 'content';
$scheme = $url['scheme']=='https' ? 'ssl://':'';
$fp = @fsockopen($scheme.$url['host'], $port, $errno, $errstr, $timeout);
if( $fp )
{
/* Mozilla */
if( ! isset($params['User-Agent']) ) $params['User-Agent'] = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16";
$request = "{$params['method']} {$url['path']} HTTP/1.0\r\n";
$request .= "Host: {$url['host']}\r\n";
$request .= "User-Agent: {$params['User-Agent']}"."\r\n";
if( isset($params['referer']) ) $request .= "Referer: {$params['referer']}\r\n";
if( isset($params['cookie']) )
{
$cookie = "";
if( is_array($params['cookie']) ) {foreach( $params['cookie'] as $k=>$v ) $cookie .= "$k=$v; "; $cookie = substr($cookie,0,-2);}
else $cookie = $params['cookie'];
if( $cookie!='' ) $request .= "Cookie: $cookie\r\n";
}
$request .= "Connection: close\r\n";
if( $params['method']=='POST' )
{
if( isset($params['data']) && is_array($params['data']) )
{
foreach($params['data'] AS $k => $v)
$data .= urlencode($k).'='.urlencode($v).'&';
if( substr($data, -1)=='&' ) $data = substr($data,0,-1);
}
$data .= "\r\n\r\n";
$request .= "Content-type: application/x-www-form-urlencoded\r\n";
$request .= "Content-length: ".strlen($data)."\r\n";
}
$request .= "\r\n";
if( $params['method'] == 'POST' ) $request .= $data;
@fwrite ($fp,$request); /* Send request */
$res = ""; $headers = ""; $h_detected = false;
while( !@feof($fp) )
{
$res .= @fread($fp, 1024); /* читаем контент */
/* Проверка наличия загловков в контенте */
if( ! $h_detected && strpos($res, "\r\n\r\n")!==FALSE )
{
/* заголовки уже считаны - корректируем контент */
$h_detected = true;
$headers = substr($res, 0, strpos($res, "\r\n\r\n"));
$res = substr($res, strpos($res, "\r\n\r\n")+4);
/* Headers to Array */
if( $params['return']=='headers' || $params['return']=='array'
|| (isset($params['redirect']) && $params['redirect']==true) )
{
$h = explode("\r\n", $headers);
$headers = array();
foreach( $h as $k=>$v )
{
if( strpos($v, ':') )
{
$k = substr($v, 0, strpos($v, ':'));
$v = trim(substr($v, strpos($v, ':')+1));
}
$headers[strtoupper($k)] = $v;
}
}
if( isset($params['redirect']) && $params['redirect']==true && isset($headers['LOCATION']) )
{
$params['url'] = $headers['LOCATION'];
if( !isset($params['redirect-count']) ) $params['redirect-count'] = 0;
if( $params['redirect-count']<10 )
{
$params['redirect-count']++;
$func = __FUNCTION__;
return @is_object($this) ? $this->$func($params) : $func($params);
}
}
if( $params['return']=='headers' ) return $headers;
}
}
@fclose($fp);
}
else return FALSE;/* $errstr.$errno; */
if( $params['return']=='array' ) $res = array('headers'=>$headers, 'content'=>$res);
return $res;
}
Использование:
print_r( http_request(array('url'=>"http://denik.od.ua/", 'method'=>'GET')) );
print_r( http_request("http://denik.od.ua/") );
$data = array(
'param1' => 'val1',
'param1' => 'val2'
);
print_r( http_request(array('url'=>"http://denik.od.ua/", 'method'=>'POST', 'data'=>$data)) );
print_r( http_request(array('url'=>"denik.od.ua", 'data'=>$data)) );
Очень похожая в реализации, но все же немного другая функция, предназначена для копирования файлов/HTML-страниц с интернет потока. Работает примерно как стандартная функция copy(). При существовании файла назначения - перезаписывает его!
/**
* HTTP Request v1.0 by Denik
* Parametres:
* - [src_url] - source url
* - [dst_file] - destination file path
* - [timeout] - timeout connection (default - 30)
* return: TRUE/FALSE
**/
function http_file_down($src_url, $dst_file, $timeout = 30)
{
/* Приводим ссылку в правильный вид */
$url = parse_url($src_url);
if( ! isset($url['scheme']) ) $url['scheme'] = 'http';
if( ! isset($url['path']) ) $url['path'] = '/';
if( ! isset($url['host']) && isset($url['path']) )
{
if( strpos($url['path'], '/') )
{
$url['host'] = substr($url['path'], 0, strpos($url['path'], '/'));
$url['path'] = substr($url['path'], strpos($url['path'], '/'));
}
else
{
$url['host'] = $url['path'];
$url['path'] = '/';
}
}
$url['path'] = preg_replace("/[\\/]+/", "/", $url['path']);
if( isset($url['query']) ) $url['path'] .= "?{$url['query']}";
$port = isset($params['port']) ? $params['port']
: ( isset($url['port']) ? $url['port'] : ($url['scheme']=='https'?443:80) );
$scheme = $url['scheme']=='https' ? 'ssl://':'';
$fp = @fsockopen($scheme.$url['host'], $port, $errno, $errstr, $timeout);
if( ! $fp ) return FALSE;
/* Mozilla */
$user_agent = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0 Mobile/7A341 Safari/528.16";
$request = "GET {$url['path']} HTTP/1.0\r\n";
$request .= "Host: {$url['host']}\r\n";
$request .= "User-Agent: {$user_agent}"."\r\n";
$request .= "Connection: close\r\n";
$request .= "\r\n";
@fwrite($fp, $request);
$headers = ""; $headers_write = true;
while( !@feof($fp) )
{
$line = @fread($fp, 1024);
if( $headers_write )
{
$headers .= $line;
if( strpos($headers, "\r\n\r\n")!==FALSE )
{
$line = substr($headers, strpos($headers, "\r\n\r\n")+4);
$headers = substr($headers, 0, strpos($headers, "\r\n\r\n"));
/* Parsing headers */
$h = explode("\r\n", $headers);
$headers = array('STATUS'=>404);
foreach( $h as $k=>$v )
{
if( strpos($v, ':') )
{
$k = substr($v, 0, strpos($v, ':'));
$v = trim(substr($v, strpos($v, ':')+1));
}
$headers[strtoupper($k)] = $v;
}
if( isset($headers[0]) ) $headers['STATUS'] = intval(trim(substr($headers[0], strpos($headers[0], ' ')+1)));
if( $headers['STATUS']==404 ) {@fclose($fp); return FALSE;}
// Header Redirect (301)
if( isset($headers['LOCATION']) )
{
$src_url = $headers['LOCATION'];
$attempt = md5(__METHOD__);
if( !isset($GLOBALS[$attempt]) ) $GLOBALS[$attempt] = 0;
if( $GLOBALS[$attempt]<10 )
{
$GLOBALS[$attempt]++;
$func = __FUNCTION__;
return @is_object($this) ? $this->$func($src_url, $dst_file, $timeout) : $func($src_url, $dst_file, $timeout);
}
}
$file = @fopen($dst_file, "w+");
if( ! $file ) {@fclose($fp); return FALSE;}
$headers_write = FALSE;
}
}
if( ! $headers_write )
{
/* Это уже части файла */
@fwrite($file, $line);
}
}
@fclose($file);
@fclose($fp);
return TRUE;
}
Надеюсь, кому-то все это когда-нибудь пригодиться... Может быть даже и мне))) Удачного программирования!