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

Source for file URL.php

Documentation is available at URL.php

  1. <?php
  2. // +-----------------------------------------------------------------------+
  3. // | Copyright (c) 2002-2004, Richard Heyes                                |
  4. // | All rights reserved.                                                  |
  5. // |                                                                       |
  6. // | Redistribution and use in source and binary forms, with or without    |
  7. // | modification, are permitted provided that the following conditions    |
  8. // | are met:                                                              |
  9. // |                                                                       |
  10. // | o Redistributions of source code must retain the above copyright      |
  11. // |   notice, this list of conditions and the following disclaimer.       |
  12. // | o Redistributions in binary form must reproduce the above copyright   |
  13. // |   notice, this list of conditions and the following disclaimer in the |
  14. // |   documentation and/or other materials provided with the distribution.|
  15. // | o The names of the authors may not be used to endorse or promote      |
  16. // |   products derived from this software without specific prior written  |
  17. // |   permission.                                                         |
  18. // |                                                                       |
  19. // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
  20. // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
  21. // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
  22. // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
  23. // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
  24. // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
  25. // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
  26. // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
  27. // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
  28. // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
  29. // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
  30. // |                                                                       |
  31. // +-----------------------------------------------------------------------+
  32. // | Author: Richard Heyes <richard at php net>                            |
  33. // +-----------------------------------------------------------------------+
  34. //
  35. // $Id: URL.php,v 1.45 2007/05/08 01:19:39 davidc Exp $
  36. //
  37. // Net_URL Class
  38.  
  39.  
  40. class Net_URL
  41. {
  42.     var $options = array('encode_query_keys' => false);
  43.     /**
  44.     * Full url
  45.     * @var string 
  46.     */
  47.     var $url;
  48.  
  49.     /**
  50.     * Protocol
  51.     * @var string 
  52.     */
  53.     var $protocol;
  54.  
  55.     /**
  56.     * Username
  57.     * @var string 
  58.     */
  59.     var $username;
  60.  
  61.     /**
  62.     * Password
  63.     * @var string 
  64.     */
  65.     var $password;
  66.  
  67.     /**
  68.     * Host
  69.     * @var string 
  70.     */
  71.     var $host;
  72.  
  73.     /**
  74.     * Port
  75.     * @var integer 
  76.     */
  77.     var $port;
  78.  
  79.     /**
  80.     * Path
  81.     * @var string 
  82.     */
  83.     var $path;
  84.  
  85.     /**
  86.     * Query string
  87.     * @var array 
  88.     */
  89.     var $querystring;
  90.  
  91.     /**
  92.     * Anchor
  93.     * @var string 
  94.     */
  95.     var $anchor;
  96.  
  97.     /**
  98.     * Whether to use []
  99.     * @var bool 
  100.     */
  101.     var $useBrackets;
  102.  
  103.     var $url;
  104.     var $useBrackets;
  105.     /**
  106.     * PHP4 Constructor
  107.     *
  108.     * @see __construct()
  109.     */
  110.     function Net_URL($url = null$useBrackets = true)
  111.     {
  112.         $this->__construct($url$useBrackets);
  113.     }
  114.  
  115.     /**
  116.     * PHP5 Constructor
  117.     *
  118.     * Parses the given url and stores the various parts
  119.     * Defaults are used in certain cases
  120.     *
  121.     * @param string $url         Optional URL
  122.     * @param bool   $useBrackets Whether to use square brackets when
  123.     *                             multiple querystrings with the same name
  124.     *                             exist
  125.     */
  126.     function __construct($url = null$useBrackets = true)
  127.     {
  128.         $this->url $url;
  129.         $ths->useBrackets = $useBrackets;
  130.  
  131.         $this->initialize();
  132.     }
  133.  
  134.     function initialize($url = null$useBrackets = true)
  135.     {
  136.         $HTTP_SERVER_VARS  !empty($_SERVER$_SERVER $GLOBALS['HTTP_SERVER_VARS'];
  137.  
  138.         $this->useBrackets $useBrackets;
  139.         $this->url         $url;
  140.         $this->user        '';
  141.         $this->pass        '';
  142.         $this->host        '';
  143.         $this->port        = 80;
  144.         $this->path        '';
  145.         $this->querystring = array();
  146.         $this->anchor      '';
  147.  
  148.         // Only use defaults if not an absolute URL given
  149.         if (!preg_match('/^[a-z0-9]+:\/\//i'$url)) {
  150.             $this->protocol (!empty($_SERVER['HTTPS']&& $_SERVER['HTTPS'== 'on' 'https' 'http');
  151.  
  152.             /**
  153.             * Figure out host/port
  154.             */
  155.             if (!empty($HTTP_SERVER_VARS['HTTP_HOST']AND preg_match('/^(.*)(:([0-9]+))?$/U'$HTTP_SERVER_VARS['HTTP_HOST']$matches)) {
  156.                 $host $matches[1];
  157.                 if (!empty($matches[3])) {
  158.                     $port $matches[3];
  159.                 else {
  160.                     $port $this->getStandardPort($this->protocol);
  161.                 }
  162.             }
  163.  
  164.             $this->user        '';
  165.             $this->pass        '';
  166.             $this->host        !empty($host$host (isset($HTTP_SERVER_VARS['SERVER_NAME']$HTTP_SERVER_VARS['SERVER_NAME''localhost');
  167.             $this->port        !empty($port$port (isset($HTTP_SERVER_VARS['SERVER_PORT']$HTTP_SERVER_VARS['SERVER_PORT'$this->getStandardPort($this->protocol));
  168.             $this->path        !empty($HTTP_SERVER_VARS['PHP_SELF']$HTTP_SERVER_VARS['PHP_SELF''/';
  169.             $this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']$this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']: null;
  170.             $this->anchor      '';
  171.         }
  172.  
  173.         // Parse the url and store the various parts
  174.         if (!empty($url)) {
  175.             $urlinfo parse_url($url);
  176.  
  177.             // Default querystring
  178.             $this->querystring = array();
  179.  
  180.             foreach ($urlinfo as $key => $value{
  181.                 switch ($key{
  182.                     case 'scheme':
  183.                         $this->protocol $value;
  184.                         $this->port     $this->getStandardPort($value);
  185.                         break;
  186.  
  187.                     case 'user':
  188.                     case 'pass':
  189.                     case 'host':
  190.                     case 'port':
  191.                         $this->$key $value;
  192.                         break;
  193.  
  194.                     case 'path':
  195.                         if ($value{0== '/'{
  196.                             $this->path $value;
  197.                         else {
  198.                             $path dirname($this->path== DIRECTORY_SEPARATOR ? '' dirname($this->path);
  199.                             $this->path sprintf('%s/%s'$path$value);
  200.                         }
  201.                         break;
  202.  
  203.                     case 'query':
  204.                         $this->querystring $this->_parseRawQueryString($value);
  205.                         break;
  206.  
  207.                     case 'fragment':
  208.                         $this->anchor $value;
  209.                         break;
  210.                 }
  211.             }
  212.         }
  213.     }
  214.     /**
  215.     * Returns full url
  216.     *
  217.     * @return string Full url
  218.     * @access public
  219.     */
  220.     function getURL()
  221.     {
  222.         $querystring $this->getQueryString();
  223.  
  224.         $this->url $this->protocol '://'
  225.                    . $this->user (!empty($this->pass':' '')
  226.                    . $this->pass (!empty($this->user'@' '')
  227.                    . $this->host ($this->port == $this->getStandardPort($this->protocol'' ':' $this->port)
  228.                    . $this->path
  229.                    . (!empty($querystring'?' $querystring '')
  230.                    . (!empty($this->anchor'#' $this->anchor '');
  231.  
  232.         return $this->url;
  233.     }
  234.  
  235.     /**
  236.     * Adds a querystring item
  237.     *
  238.     * @param  string $name       Name of item
  239.     * @param  string $value      Value of item
  240.     * @param  bool   $preencoded Whether value is urlencoded or not, default = not
  241.     * @access public
  242.     */
  243.     function addQueryString($name$value$preencoded = false)
  244.     {
  245.         if ($this->getOption('encode_query_keys')) {
  246.             $name rawurlencode($name);
  247.         }
  248.  
  249.         if ($preencoded{
  250.             $this->querystring[$name$value;
  251.         else {
  252.             $this->querystring[$nameis_array($valuearray_map('rawurlencode'$value)rawurlencode($value);
  253.         }
  254.     }
  255.  
  256.     /**
  257.     * Removes a querystring item
  258.     *
  259.     * @param  string $name Name of item
  260.     * @access public
  261.     */
  262.     function removeQueryString($name)
  263.     {
  264.         if ($this->getOption('encode_query_keys')) {
  265.             $name rawurlencode($name);
  266.         }
  267.  
  268.         if (isset($this->querystring[$name])) {
  269.             unset($this->querystring[$name]);
  270.         }
  271.     }
  272.  
  273.     /**
  274.     * Sets the querystring to literally what you supply
  275.     *
  276.     * @param  string $querystring The querystring data. Should be of the format foo=bar&x=y etc
  277.     * @access public
  278.     */
  279.     function addRawQueryString($querystring)
  280.     {
  281.         $this->querystring $this->_parseRawQueryString($querystring);
  282.     }
  283.  
  284.     /**
  285.     * Returns flat querystring
  286.     *
  287.     * @return string Querystring
  288.     * @access public
  289.     */
  290.     function getQueryString()
  291.     {
  292.         if (!empty($this->querystring)) {
  293.             foreach ($this->querystring as $name => $value{
  294.                 // Encode var name
  295.                 $name rawurlencode($name);
  296.  
  297.                 if (is_array($value)) {
  298.                     foreach ($value as $k => $v{
  299.                         $querystring[$this->useBrackets sprintf('%s[%s]=%s'$name$k$v($name '=' $v);
  300.                     }
  301.                 elseif (!is_null($value)) {
  302.                     $querystring[$name '=' $value;
  303.                 else {
  304.                     $querystring[$name;
  305.                 }
  306.             }
  307.             $querystring implode(ini_get('arg_separator.output')$querystring);
  308.         else {
  309.             $querystring '';
  310.         }
  311.  
  312.         return $querystring;
  313.     }
  314.  
  315.     /**
  316.     * Parses raw querystring and returns an array of it
  317.     *
  318.     * @param  string  $querystring The querystring to parse
  319.     * @return array                An array of the querystring data
  320.     * @access private
  321.     */
  322.     function _parseRawQuerystring($querystring)
  323.     {
  324.         $parts  preg_split('/[' preg_quote(ini_get('arg_separator.input')'/'']/'$querystring-1PREG_SPLIT_NO_EMPTY);
  325.         $return = array();
  326.  
  327.         foreach ($parts as $part{
  328.             if (strpos($part'='!== false{
  329.                 $value substr($partstrpos($part'='+ 1);
  330.                 $key   substr($part0strpos($part'='));
  331.             else {
  332.                 $value = null;
  333.                 $key   $part;
  334.             }
  335.  
  336.             if (!$this->getOption('encode_query_keys')) {
  337.                 $key rawurldecode($key);
  338.             }
  339.  
  340.             if (preg_match('#^(.*)\[([0-9a-z_-]*)\]#i'$key$matches)) {
  341.                 $key $matches[1];
  342.                 $idx $matches[2];
  343.  
  344.                 // Ensure is an array
  345.                 if (empty($return[$key]|| !is_array($return[$key])) {
  346.                     $return[$key= array();
  347.                 }
  348.  
  349.                 // Add data
  350.                 if ($idx === ''{
  351.                     $return[$key][$value;
  352.                 else {
  353.                     $return[$key][$idx$value;
  354.                 }
  355.             elseif (!$this->useBrackets AND !empty($return[$key])) {
  356.                 $return[$key]   = (array)$return[$key];
  357.                 $return[$key][$value;
  358.             else {
  359.                 $return[$key$value;
  360.             }
  361.         }
  362.  
  363.         return $return;
  364.     }
  365.  
  366.     /**
  367.     * Resolves //, ../ and ./ from a path and returns
  368.     * the result. Eg:
  369.     *
  370.     * /foo/bar/../boo.php    => /foo/boo.php
  371.     * /foo/bar/../../boo.php => /boo.php
  372.     * /foo/bar/.././/boo.php => /foo/boo.php
  373.     *
  374.     * This method can also be called statically.
  375.     *
  376.     * @param  string $url URL path to resolve
  377.     * @return string      The result
  378.     */
  379.     function resolvePath($path)
  380.     {
  381.         $path explode('/'str_replace('//''/'$path));
  382.  
  383.         for ($i=0; $i<count($path)$i++{
  384.             if ($path[$i== '.'{
  385.                 unset($path[$i]);
  386.                 $path array_values($path);
  387.                 $i--;
  388.  
  389.             elseif ($path[$i== '..' AND ($i > 1 OR ($i == 1 AND $path[0!= '') ) ) {
  390.                 unset($path[$i]);
  391.                 unset($path[$i-1]);
  392.                 $path array_values($path);
  393.                 $i -= 2;
  394.  
  395.             elseif ($path[$i== '..' AND $i == 1 AND $path[0== ''{
  396.                 unset($path[$i]);
  397.                 $path array_values($path);
  398.                 $i--;
  399.  
  400.             else {
  401.                 continue;
  402.             }
  403.         }
  404.  
  405.         return implode('/'$path);
  406.     }
  407.  
  408.     /**
  409.     * Returns the standard port number for a protocol
  410.     *
  411.     * @param  string  $scheme The protocol to lookup
  412.     * @return integer         Port number or NULL if no scheme matches
  413.     *
  414.     * @author Philippe Jausions <Philippe.Jausions@11abacus.com>
  415.     */
  416.     function getStandardPort($scheme)
  417.     {
  418.         switch (strtolower($scheme)) {
  419.             case 'http':    return 80;
  420.             case 'https':   return 443;
  421.             case 'ftp':     return 21;
  422.             case 'imap':    return 143;
  423.             case 'imaps':   return 993;
  424.             case 'pop3':    return 110;
  425.             case 'pop3s':   return 995;
  426.             default:        return null;
  427.        }
  428.     }
  429.  
  430.     /**
  431.     * Forces the URL to a particular protocol
  432.     *
  433.     * @param string  $protocol Protocol to force the URL to
  434.     * @param integer $port     Optional port (standard port is used by default)
  435.     */
  436.     function setProtocol($protocol$port = null)
  437.     {
  438.         $this->protocol $protocol;
  439.         $this->port     is_null($port$this->getStandardPort($protocol$port;
  440.     }
  441.  
  442.     /**
  443.      * Set an option
  444.      *
  445.      * This function set an option
  446.      * to be used thorough the script.
  447.      *
  448.      * @access public
  449.      * @param  string $optionName  The optionname to set
  450.      * @param  string $value       The value of this option.
  451.      */
  452.     function setOption($optionName$value)
  453.     {
  454.         if (!array_key_exists($optionName$this->options)) {
  455.             return false;
  456.         }
  457.  
  458.         $this->options[$optionName$value;
  459.         $this->initialize();
  460.     }
  461.  
  462.     /**
  463.      * Get an option
  464.      *
  465.      * This function gets an option
  466.      * from the $this->options array
  467.      * and return it's value.
  468.      *
  469.      * @access public
  470.      * @param  string $opionName  The name of the option to retrieve
  471.      * @see    $this->options
  472.      */
  473.     function getOption($optionName)
  474.     {
  475.         if (!isset($this->options[$optionName])) {
  476.             return false;
  477.         }
  478.  
  479.         return $this->options[$optionName];
  480.     }
  481.  
  482. }
  483. ?>

Documentation generated on Mon, 07 May 2007 21:30:04 -0400 by phpDocumentor 1.3.0. PEAR Logo Copyright © PHP Group 2004.