dizballanze

Untitled

Oct 16th, 2011
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 17.21 KB | None | 0 0
  1. <?
  2. /**
  3. * HTTP Class
  4. *
  5. * Позволяет легко выполнять GET и POST запросы, хранить
  6. * и устанавливать cookies, следовать редиректам и
  7. * возвращать данные в необходимой кодировке. Так же имеется
  8. * встроенная функция для исправления относительных ссылок
  9. * в абсолютные.
  10. *
  11. * @author Jeck (http://jeck.ru)
  12. */
  13. class http {
  14.         public $user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.2.10) Gecko/20100914 Firefox/3.6.10 (.NET CLR 3.5.30729)';
  15.        
  16.         public $cookies = array();
  17.         public $referer = '';
  18.         public $timeout = 10;
  19.        
  20.         public $externalIp;
  21.        
  22.         public $proxy = '';
  23.         public $proxy_type = CURLPROXY_HTTP;
  24.        
  25.         public $current_url;
  26.        
  27.         // Режим следования по редиректу (true - включен, false - выключен)
  28.         public $follow_location = true;
  29.        
  30.         // Кодировка по умолчанию
  31.         public $default_encoding = 'WINDOWS-1251';
  32.        
  33.         // Кодировка страницы
  34.         public $encoding = '';
  35.        
  36.         public $info;
  37.        
  38.         private $ch;
  39.         private $result;
  40.         private $result_headers;
  41.         private $result_body;
  42.         private $location = '';
  43.        
  44.         public function get($url, $encoding=null) {
  45.                 $this->init($url);
  46.                 $this->setDefaults();
  47.                 $this->exec();
  48.                
  49.                 if ($this->follow_location && !empty($this->location)) {
  50.                         return $this->get(self::fixUrl($url,$this->location), $encoding);
  51.                 } else {
  52.                         return $this->processEncoding($this->result_body, $encoding);
  53.                 }
  54.         }
  55.        
  56.         public function post($url, $postdata, $encoding=null) {
  57.                 $this->init($url);
  58.                 $this->setPostFields($postdata);
  59.                 $this->setDefaults();
  60.                 $this->exec();
  61.                
  62.                 if ($this->follow_location && !empty($this->location)) {
  63.                         return $this->get(self::fixUrl($url, $this->location), $encoding);
  64.                 } else {
  65.                         return $this->processEncoding($this->result_body, $encoding);
  66.                 }
  67.         }
  68.        
  69.         /**
  70.                 Возвращает заголовки последнего запроса
  71.         */
  72.         public function getHeaders() {
  73.                 return $this->result_headers;
  74.         }
  75.        
  76.         /**
  77.                 Выполняет начальную инициализацию запроса
  78.         */
  79.         private function init($url) {
  80.                 $this->current_url = $url;
  81.                 $this->ch = curl_init($url);
  82.                
  83.                 // Если запрос с использованием SSL - отключаем проверку сертификата
  84.                 $scheme = parse_url($url,PHP_URL_SCHEME);
  85.                 $scheme = strtolower($scheme);
  86.                 if ($scheme == 'https') {
  87.                         curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, false);
  88.                         curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);
  89.                 }
  90.         }
  91.        
  92.         /**
  93.                 Запускает обработку запроса
  94.         */
  95.         private function exec() {
  96.                 // Установливает параметры необходимые для правильной обработки данных
  97.                 curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
  98.                 curl_setopt($this->ch, CURLOPT_HEADER, true);
  99.                
  100.                 // Выполняем запрос и получаем информацию
  101.                 $this->result = curl_exec($this->ch);
  102.                 $this->info = curl_getinfo($this->ch);
  103.                
  104.                 $this->processHeaders();
  105.                 $this->processBody();
  106.                 $this->correctEncoding();
  107.         }
  108.        
  109.         /**
  110.                 Получает заголовки запроса и обрабатывает их содержимое
  111.         */
  112.         private function processHeaders() {
  113.                 $this->location = '';
  114.                 $this->referer = $this->info['url'];
  115.                 $this->result_headers = substr($this->result,0,$this->info['header_size']);
  116.                 $headers = explode("\r\n",$this->result_headers);
  117.                 foreach ($headers as $header) {
  118.                         if (strpos($header,":") !== false) {
  119.                                 list($key,$value) = explode(":",$header,2);
  120.                                 $key = trim($key);
  121.                                 $key = strtolower($key);
  122.                                 switch ($key) {
  123.                                         case 'set-cookie':
  124.                                                 $this->processSetCookie($value);
  125.                                         break;
  126.                                         case 'content-type':
  127.                                                 $this->processContentType($value);
  128.                                         break;
  129.                                         case 'location':
  130.                                                 $this->processLocation($value);
  131.                                         break;
  132.                                 }
  133.                         }
  134.                 }
  135.         }
  136.        
  137.         /**
  138.                 Обрабатывает заголовок set-cookie
  139.         */
  140.         private function processSetCookie($string) {
  141.                 $parts = explode(';', $string);
  142.                 $domain = '.';
  143.                 $cookies = array();
  144.                 $expires = false;
  145.                 foreach ($parts as $part) {
  146.                         if (strpos($part, '=') !== false) {
  147.                                 list($key, $value) = explode('=', $part, 2);
  148.                                 $key = trim($key);
  149.                                 $value = trim($value);
  150.                         } else {
  151.                                 $key = trim($part);
  152.                                 $value = '';
  153.                         }
  154.                         if (strtolower($key) == 'domain') {
  155.                                 $domain = $value;
  156.                         }
  157.                         if (strtolower($key) == 'expires') {
  158.                                 if ($time = strtotime($value)) {
  159.                                         $expires = (boolean) time() > $time;
  160.                                 }
  161.                         }
  162.                         if (!in_array(strtolower($key), array('domain', 'expires', 'path', 'secure', 'comment'))) {
  163.                                 $cookies[$key] = $value;
  164.                         }
  165.                 }
  166.                 foreach ($cookies as $key => $value) {
  167.                         if ($expires) {
  168.                                 unset($this->cookies[$domain][$key]);
  169.                         } else {
  170.                                 $this->cookies[$domain][$key] = $value;
  171.                         }
  172.                 }
  173.         }
  174.        
  175.         /**
  176.                 Обрабатывает заголовок content-type
  177.         */
  178.         private function processContentType($string) {
  179.                 $pos = strpos($string,'charset');
  180.                 if ($pos !== false) {
  181.                         $endpos = strpos($string,';',$pos);
  182.                         if ($endpos === false) {
  183.                                 $charset = substr($string,$pos);
  184.                         } else {
  185.                                 $length = $endpos - $pos;
  186.                                 $charset = substr($string,$pos,$length);
  187.                         }
  188.                         list(,$this->encoding) = explode("=",$charset,2);
  189.                 }
  190.         }
  191.        
  192.         /**
  193.                 Обрабатывает заголовок location
  194.         */
  195.         private function processLocation($string) {
  196.                 $this->location = trim($string);
  197.         }
  198.        
  199.         /**
  200.                 Получает тело страницы
  201.         */
  202.         private function processBody() {
  203.                 $this->result_body = substr($this->result,$this->info['header_size']);
  204.                 // Определяем кодировку по meta тегам
  205.                 if (is_null($this->encoding)) {
  206.                         if (preg_match("#<meta\b[^<>]*?\bcontent=['\"]?text/html;\s*charset=([^>\s\"']+)['\"]?#is", $this->result_body, $match)) {
  207.                                 $this->encoding = strtoupper($match[1]);
  208.                         }
  209.                 }
  210.         }
  211.  
  212.         /**
  213.                 Возвращает тело страницы в нужной кодировке
  214.         */
  215.         private function processEncoding($body,$encoding) {
  216.                 if ($encoding !== null && !empty($this->encoding)) {
  217.                         return iconv($this->encoding, $encoding.'//TRANSLIT', $body);
  218.                 }
  219.                 return $body;
  220.         }
  221.        
  222.         /**
  223.                 Устанавливает начальные параметры заданные в свойствах
  224.         */
  225.         private function setDefaults() {
  226.                 $this->encoding = null;
  227.                 $this->setUserAgent();
  228.                 $this->setReferer();
  229.                 $this->setCookies();
  230.                 $this->setProxy();
  231.                 $this->setTimeout();
  232.                 $this->setExternalIp();
  233.         }
  234.        
  235.         /**
  236.                 Устанавливает UserAgent для curl
  237.         */
  238.         private function setUserAgent() {
  239.                 if (!empty($this->user_agent)) {
  240.                         curl_setopt($this->ch, CURLOPT_USERAGENT, $this->user_agent);
  241.                 }
  242.         }
  243.  
  244.         /**
  245.                 Устанавливает Referer для curl
  246.         */      
  247.         private function setReferer() {
  248.                 if (!empty($this->referer)) {
  249.                         curl_setopt($this->ch, CURLOPT_REFERER, $this->referer);
  250.                 }
  251.         }
  252.        
  253.         /**
  254.                 Преобразуем cookies в строку и устанавливаем их для curl
  255.         */      
  256.         private function setCookies() {
  257.                 if (is_array($this->cookies)) {
  258.                         $cookie_string = '';
  259.                         $currentHost = parse_url($this->current_url, PHP_URL_HOST);
  260.                         foreach ($this->cookies as $cookieDomain => $cookies) {
  261.                 if ($currentHost{0} !== '.') {
  262.                     $currentHost = '.'.$currentHost;
  263.                 }
  264.                                 if ($cookieDomain == '.' || preg_match('/'.preg_quote($cookieDomain, '/').'$/i', $currentHost)) {
  265.                                         foreach ($cookies as $key => $value) {
  266.                                                 $cookie_string .= $key.'='.$value.'; ';
  267.                                         }
  268.                                 }
  269.                         }
  270.                         if (strlen($cookie_string) > 0) {
  271.                                 $cookie_string = substr($cookie_string, 0, -2);
  272.                                 curl_setopt($this->ch, CURLOPT_COOKIE, $cookie_string);
  273.                         }
  274.                 }
  275.         }
  276.        
  277.         /**
  278.                 Преобразуем postdata в строку и устанавливаем в качестве post_fields
  279.         */      
  280.         private function setPostFields($postdata) {
  281.                 curl_setopt($this->ch, CURLOPT_POST, true);
  282.                 curl_setopt($this->ch, CURLOPT_POSTFIELDS, http_build_query($postdata, '', '&'));
  283.         }
  284.        
  285.         /**
  286.                 Устанавливаем proxy если необходимо
  287.         */      
  288.         private function setProxy() {
  289.                 if (!empty($this->proxy)) {
  290.                         curl_setopt($this->ch, CURLOPT_PROXY, $this->proxy);
  291.                         curl_setopt($this->ch, CURLOPT_PROXYTYPE, $this->proxy_type);
  292.                 }
  293.         }
  294.        
  295.         /**
  296.                 Устанавливает таймаут соединения
  297.         */      
  298.         private function setTimeout() {
  299.                 if ($this->timeout > 0) {
  300.                         curl_setopt($this->ch, CURLOPT_TIMEOUT, $this->timeout);
  301.                 }
  302.         }
  303.         /**
  304.                 Устанавливает внешний IP интерфейс
  305.         */      
  306.         private function setExternalIp() {
  307.                 if (!is_null($this->externalIp)) {
  308.                         curl_setopt($this->ch, CURLOPT_INTERFACE, $this->externalIp);
  309.                 }
  310.         }
  311.        
  312.         /**
  313.                 Корректирует кодировку если она задана в виде не подходящим для curl
  314.         */
  315.         private function correctEncoding() {
  316.                 if (!is_null($this->encoding)) {
  317.                         if (preg_match('/\d{4}$/i', $this->encoding, $match)) {
  318.                                 $this->encoding = 'WINDOWS-'.$match[0];
  319.                         }
  320.                         $this->encoding = strtoupper($this->encoding);
  321.                 } else {
  322.                         $this->encoding = $this->default_encoding;
  323.                 }
  324.         }
  325.        
  326.         /**
  327.                 Преобразовывает относительные URL в абсолютные по базе
  328.         */
  329.         final static function fixUrl($baseUrl, $url) {
  330.                 $baseParts = parse_url($baseUrl);
  331.                 if (preg_match('/^\/\//', $url)) {
  332.                         $url = $baseParts['scheme'].':'.$url;
  333.                 }
  334.                 $urlParts = parse_url($url);
  335.                 if (isset($urlParts['scheme'])) {
  336.                         return self::buidUrl($urlParts);
  337.                 }
  338.                 $parts = $baseParts;
  339.                 if (!isset($baseParts['path'])) {
  340.                         $baseParts['path'] = '';
  341.                 }
  342.                 unset($parts['fragment']);
  343.                 if (isset($urlParts['path'])) {
  344.                         unset($parts['query']);
  345.                         if (strpos($urlParts['path'], '/') === 0) {
  346.                                 $parts['path'] = $urlParts['path'];
  347.                         } else if (isset($urlParts['path']) && !empty($urlParts['path'])) {
  348.                                 $basePath = explode('/', $baseParts['path']);
  349.                                 array_pop($basePath);
  350.                                 $urlPath = explode('/', $urlParts['path']);
  351.                                 $lastSegment = count($urlPath) - 1;
  352.                                 foreach ($urlPath as $key => $pathSegment) {
  353.                                         if ($pathSegment == '.') {
  354.                                                 continue;
  355.                                         } else if ($pathSegment == '..') {
  356.                                                 if (count($basePath) > 0) {
  357.                                                         array_pop($basePath);
  358.                                                 }
  359.                                         } else if (empty($pathSegment) && $key != $lastSegment) {
  360.                                                 $basePath = array();
  361.                                         } else {
  362.                                                 array_push($basePath, $pathSegment);
  363.                                         }
  364.                                 }
  365.                                 $basePath = implode('/', $basePath);
  366.                                 if (strpos($basePath, '/') !== 0) {
  367.                                         $basePath = '/'.$basePath;
  368.                                 }
  369.                                 $parts['path'] = $basePath;
  370.                         }
  371.                 }
  372.                 if (isset($urlParts['query'])) {
  373.                         $parts['query'] = $urlParts['query'];
  374.                 }
  375.                 if (isset($urlParts['fragment'])) {
  376.                         $parts['fragment'] = $urlParts['fragment'];
  377.                 }
  378.                 return self::buidUrl($parts);
  379.         }
  380.  
  381.         final static function buidUrl($parts) {
  382.                 $url  = (isset($parts['scheme']) ? $parts['scheme'].'://' : 'http://').
  383.                                 (isset($parts['user']) ? $parts['user'].(isset($parts['pass']) ? ':' . $parts['pass'] : '') .'@' : '').
  384.                                 (isset($parts['host']) ? $parts['host'] : '').
  385.                                 (isset($parts['port']) ? ':' . $parts['port'] : '').
  386.                                 (isset($parts['path']) ? $parts['path'] : '/').
  387.                                 (isset($parts['query']) ? '?' . $parts['query'] : '').
  388.                                 (isset($parts['fragment']) ? '#' . $parts['fragment'] : '');
  389.                 return $url;
  390.         }
  391. }
  392.  
Advertisement
Add Comment
Please, Sign In to add comment