HTTP
[ class tree: HTTP ] [ index: HTTP ] [ all elements ]

Source for file HTTP.php

Documentation is available at HTTP.php

  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PEAR :: HTTP                                                         |
  4. // +----------------------------------------------------------------------+
  5. // | This source file is subject to version 3.0 of the PHP license,       |
  6. // | that is available at http://www.php.net/license/3_0.txt              |
  7. // | If you did not receive a copy of the PHP license and are unable      |
  8. // | to obtain it through the world-wide-web, please send a note to       |
  9. // | license@php.net so we can mail you a copy immediately.               |
  10. // +----------------------------------------------------------------------+
  11. // | Authors: Stig Bakken <ssb@fast.no>                                   |
  12. // |          Sterling Hughes <sterling@php.net>                          |
  13. // |          Tomas V.V.Cox <cox@idecnet.com>                             |
  14. // |          Richard Heyes <richard@php.net>                             |
  15. // |          Philippe Jausions <Philippe.Jausions@11abacus.com>          |
  16. // |          Michael Wallner <mike@php.net>                              |
  17. // +----------------------------------------------------------------------+
  18. //
  19. // $Id: HTTP.php,v 1.35 2004/09/21 15:28:07 mike Exp $
  20.  
  21. /**
  22.  * HTTP
  23.  * 
  24.  * HTTP utility functions
  25.  * 
  26.  * @package     HTTP
  27.  * @category    HTTP
  28.  * @license     PHP License
  29.  * @access      public
  30.  * @version     $Revision: 1.35 $
  31.  */
  32. class HTTP
  33. {
  34.     /**
  35.      * Date
  36.      * 
  37.      * Format a RFC compliant GMT date HTTP header.  This function honors the
  38.      * "y2k_compliance" php.ini directive and formats the GMT date corresponding
  39.      * to either RFC850 or RFC822.
  40.      * 
  41.      * @static
  42.      * @access  public
  43.      * @return  mixed   GMT date string, or false for an invalid $time parameter
  44.      * @param   mixed   $time unix timestamp or date (default = current time)
  45.      */
  46.     function Date($time = null)
  47.     {
  48.         if (!isset($time)) {
  49.             $time time();
  50.         elseif (!is_numeric($time&& (-1 === $time strtotime($time))) {
  51.             return false;
  52.         }
  53.         
  54.         // RFC822 or RFC850
  55.         $format ini_get('y2k_compliance''D, d M Y' 'l, d-M-y';
  56.         
  57.         return gmdate($format .' H:i:s \G\M\T'$time);
  58.     }
  59.  
  60.     /**
  61.      * Negotiate Language
  62.      * 
  63.      * Negotiate language with the user's browser through the Accept-Language
  64.      * HTTP header or the user's host address.  Language codes are generally in
  65.      * the form "ll" for a language spoken in only one country, or "ll-CC" for a
  66.      * language spoken in a particular country.  For example, U.S. English is
  67.      * "en-US", while British English is "en-UK".  Portugese as spoken in
  68.      * Portugal is "pt-PT", while Brazilian Portugese is "pt-BR".
  69.      * 
  70.      * Quality factors in the Accept-Language: header are supported, e.g.:
  71.      *      Accept-Language: en-UK;q=0.7, en-US;q=0.6, no, dk;q=0.8
  72.      * 
  73.      * <code>
  74.      *  require_once 'HTTP.php';
  75.      *  $langs = array(
  76.      *      'en'   => 'locales/en',
  77.      *      'en-US'=> 'locales/en',
  78.      *      'en-UK'=> 'locales/en',
  79.      *      'de'   => 'locales/de',
  80.      *      'de-DE'=> 'locales/de',
  81.      *      'de-AT'=> 'locales/de',
  82.      *  );
  83.      *  $neg = HTTP::negotiateLanguage($langs);
  84.      *  $dir = $langs[$neg];
  85.      * </code>
  86.      * 
  87.      * @static
  88.      * @access  public
  89.      * @return  string  The negotiated language result or the supplied default.
  90.      * @param   array   $supported An associative array of supported languages,
  91.      *                   whose values must evaluate to true.
  92.      * @param   string  $default The default language to use if none is found.
  93.      */
  94.     function negotiateLanguage($supported$default 'en-US')
  95.     {
  96.         $supp = array();
  97.         foreach ($supported as $lang => $isSupported{
  98.             if ($isSupported{
  99.                 $supp[strToLower($lang)$lang;
  100.             }
  101.         }
  102.         
  103.         if (!count($supp)) {
  104.             return $default;
  105.         }
  106.  
  107.         $matches = array();
  108.         if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
  109.             foreach (explode(','$_SERVER['HTTP_ACCEPT_LANGUAGE']as $lang{
  110.                 @list($l$qarray_map('strtolower'
  111.                     array_map('trim'explode(';'$lang)));
  112.                 if (isset($supp[$l])) {
  113.                     if (isset($q)) {
  114.                         $matches[$l= (float) str_replace('q='''$q);
  115.                     else {
  116.                         $matches[$l= 1000 - count($matches);
  117.                     }
  118.                 }
  119.             }
  120.         }
  121.  
  122.         if (count($matches)) {
  123.             asort($matchesSORT_NUMERIC);
  124.             return $supp[array_pop(array_keys($matches))];
  125.         }
  126.         
  127.         if (isset($_SERVER['REMOTE_HOST'])) {
  128.             $lang strtolower(array_pop(explode('.'$_SERVER['REMOTE_HOST'])));
  129.             if (isset($supp[$lang])) {
  130.                 return $supp[$lang];
  131.             }
  132.         }
  133.  
  134.         return $default;
  135.     }
  136.  
  137.     /**
  138.      * Head
  139.      * 
  140.      * Sends a "HEAD" HTTP command to a server and returns the headers
  141.      * as an associative array. Example output could be:
  142.      * <code>
  143.      *     Array
  144.      *     (
  145.      *         [response_code] => 200          // The HTTP response code
  146.      *         [response] => HTTP/1.1 200 OK   // The full HTTP response string
  147.      *         [Date] => Fri, 11 Jan 2002 01:41:44 GMT
  148.      *         [Server] => Apache/1.3.20 (Unix) PHP/4.1.1
  149.      *         [X-Powered-By] => PHP/4.1.1
  150.      *         [Connection] => close
  151.      *         [Content-Type] => text/html
  152.      *     )
  153.      * </code>
  154.      * 
  155.      * @see HTTP_Client::head()
  156.      * @see HTTP_Request
  157.      * 
  158.      * @static
  159.      * @access  public
  160.      * @return  mixed   Returns associative array of response headers on success
  161.      *                   or PEAR error on failure.
  162.      * @param   string  $url A valid URL, e.g.: http://pear.php.net/credits.php
  163.      * @param   integer $timeout Timeout in seconds (default = 10)
  164.      */
  165.     function head($url$timeout = 10)
  166.     {
  167.         $p parse_url($url);
  168.         if (!isset($p['scheme'])) {
  169.             $p parse_url(HTTP::absoluteURI($url));
  170.         elseif ($p['scheme'!= 'http'{
  171.             return HTTP::raiseError('Unsupported protocol: '$p['scheme']);
  172.         }
  173.  
  174.         $port = isset($p['port']$p['port': 80;
  175.  
  176.         if (!$fp @fsockopen($p['host']$port$eno$estr$timeout)) {
  177.             return HTTP::raiseError("Connection error: $estr ($eno)");
  178.         }
  179.  
  180.         $path  !empty($p['path']$p['path''/';
  181.         $path .= !empty($p['query']'?' $p['query''';
  182.  
  183.         fputs($fp"HEAD $path HTTP/1.0\r\n");
  184.         fputs($fp'Host: ' $p['host'':' $port "\r\n");
  185.         fputs($fp"Connection: close\r\n\r\n");
  186.  
  187.         $response rtrim(fgets($fp4096));
  188.         if (preg_match("|^HTTP/[^\s]*\s(.*?)\s|"$response$status)) {
  189.             $headers['response_code'$status[1];
  190.         }
  191.         $headers['response'$response;
  192.  
  193.         while ($line fgets($fp4096)) {
  194.             if (!trim($line)) {
  195.                 break;
  196.             }
  197.             if (($pos strpos($line':')) !== false{
  198.                 $header substr($line0$pos);
  199.                 $value  trim(substr($line$pos + 1));
  200.                 $headers[$header$value;
  201.             }
  202.         }
  203.         fclose($fp);
  204.         return $headers;
  205.     }
  206.  
  207.     /**
  208.      * Redirect
  209.      * 
  210.      * This function redirects the client. This is done by issuing
  211.      * a "Location" header and exiting if wanted.  If you set $rfc2616 to true
  212.      * HTTP will output a hypertext note with the location of the redirect.
  213.      * 
  214.      * @static
  215.      * @access  public
  216.      * @return  mixed   Returns true on succes (or exits) or false if headers
  217.      *                   have already been sent.
  218.      * @param   string  $url URL where the redirect should go to.
  219.      * @param   bool    $exit Whether to exit immediately after redirection.
  220.      * @param   bool    $rfc2616 Wheter to output a hypertext note where we're
  221.      *                   redirecting to (Redirecting to <a href="...">...</a>.)
  222.      */
  223.     function redirect($url$exit = true$rfc2616 = false)
  224.     {
  225.         if (headers_sent()) {
  226.             return false;
  227.         }
  228.         
  229.         $url HTTP::absoluteURI($url);
  230.         header('Location: '$url);
  231.         
  232.         if ($rfc2616 && @$_SERVER['REQUEST_METHOD'!= 'HEAD'{
  233.             printf('Redirecting to: <a href="%s">%s</a>.'$url$url);
  234.         }
  235.         if ($exit{
  236.             exit;
  237.         }
  238.         return true;
  239.     }
  240.  
  241.     /**
  242.      * Absolute URI
  243.      * 
  244.      * This function returns the absolute URI for the partial URL passed.
  245.      * The current scheme (HTTP/HTTPS), host server, port, current script
  246.      * location are used if necessary to resolve any relative URLs.
  247.      * 
  248.      * Offsets potentially created by PATH_INFO are taken care of to resolve
  249.      * relative URLs to the current script.
  250.      * 
  251.      * You can choose a new protocol while resolving the URI.  This is
  252.      * particularly useful when redirecting a web browser using relative URIs
  253.      * and to switch from HTTP to HTTPS, or vice-versa, at the same time.
  254.      * 
  255.      * @author  Philippe Jausions <Philippe.Jausions@11abacus.com>
  256.      * @static
  257.      * @access  public
  258.      * @return  string  The absolute URI.
  259.      * @param   string  $url Absolute or relative URI the redirect should go to.
  260.      * @param   string  $protocol Protocol to use when redirecting URIs.
  261.      * @param   integer $port A new port number.
  262.      */
  263.     function absoluteURI($url = null$protocol = null$port = null)
  264.     {
  265.         // Mess around with already absolute URIs
  266.         if (preg_match('!^([a-z0-9]+)://!i'$url)) {
  267.             if (empty($protocol&& empty($port)) {
  268.                 return $url;
  269.             }
  270.             if (!empty($protocol)) {
  271.                 $url $protocol .':'array_pop(explode(':'$url2));
  272.             }
  273.             if (!empty($port)) {
  274.                 $url preg_replace('!^(([a-z0-9]+)://[^/:]+)(:[\d]+)?!i'
  275.                     '\1:'$port$url);
  276.             }
  277.             return $url;
  278.         }
  279.             
  280.         $host 'localhost';
  281.         if (!empty($_SERVER['HTTP_HOST'])) {
  282.             list($hostexplode(':'$_SERVER['HTTP_HOST']);
  283.         elseif (!empty($_SERVER['SERVER_NAME'])) {
  284.             list($hostexplode(':'$_SERVER['SERVER_NAME']);
  285.         }
  286.  
  287.         if (empty($protocol)) {
  288.             $protocol = isset($_SERVER['HTTPS']'https' 'http';
  289.             if (!isset($port|| $port != intval($port)) {
  290.                 $port = isset($_SERVER['SERVER_PORT']$_SERVER['SERVER_PORT': 80;
  291.             }
  292.         }
  293.         
  294.         if ($protocol == 'http' && $port == 80{
  295.             unset($port);
  296.         }
  297.         if ($protocol == 'https' && $port == 443{
  298.             unset($port);
  299.         }
  300.  
  301.         $server $protocol .'://'$host (isset($port':'$port '');
  302.         
  303.         if (!strlen($url)) {
  304.             $url = isset($_SERVER['REQUEST_URI']
  305.                 $_SERVER['REQUEST_URI'$_SERVER['PHP_SELF'];
  306.         }
  307.         
  308.         if ($url{0== '/'{
  309.             return $server $url;
  310.         }
  311.         
  312.         // Check for PATH_INFO
  313.         if (isset($_SERVER['PATH_INFO'])) {
  314.             $path dirname(substr($_SERVER['PHP_SELF']0-strlen($_SERVER['PATH_INFO'])));
  315.         else {
  316.             $path dirname($_SERVER['PHP_SELF']);
  317.         }
  318.         
  319.         if (substr($path-1!= '/'{
  320.             $path .= '/';
  321.         }
  322.         
  323.         return $server strtr($path'\\''/'$url;
  324.     }
  325.  
  326.     /**
  327.      * Raise Error
  328.      * 
  329.      * Lazy raising of PEAR_Errors.
  330.      * 
  331.      * @static
  332.      * @access  protected
  333.      * @return  object PEAR_Error 
  334.      * @param   mixed   $error 
  335.      * @param   int     $code 
  336.      */
  337.     function raiseError($error = null$code = null)
  338.     {
  339.         require_once 'PEAR.php';
  340.         return PEAR::raiseError($error$code);
  341.     }
  342. }
  343. ?>

Documentation generated on Mon, 11 Mar 2019 13:55:35 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.