Updating PEAR Net_URL2 to 2.1.2
Source: https://pear.php.net/package/Net_URL2 Release date: 2016-04-18
This commit is contained in:
parent
a223273544
commit
711f220397
27
extlib/Net/Net_URL2-BSD-3-CLAUSE-Heyes
Normal file
27
extlib/Net/Net_URL2-BSD-3-CLAUSE-Heyes
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
Copyright (c) 2002-2003, Richard Heyes
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
1) Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2) Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3) Neither the name of the Richard Heyes nor the names of his
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -38,9 +38,9 @@
|
||||||
* @package Net_URL2
|
* @package Net_URL2
|
||||||
* @author Christian Schmidt <schmidt@php.net>
|
* @author Christian Schmidt <schmidt@php.net>
|
||||||
* @copyright 2007-2009 Peytz & Co. A/S
|
* @copyright 2007-2009 Peytz & Co. A/S
|
||||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
* @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||||
* @version CVS: $Id: URL2.php 309223 2011-03-14 14:26:32Z till $
|
* @version CVS: $Id$
|
||||||
* @link http://www.rfc-editor.org/rfc/rfc3986.txt
|
* @link https://tools.ietf.org/html/rfc3986
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,9 +50,9 @@
|
||||||
* @package Net_URL2
|
* @package Net_URL2
|
||||||
* @author Christian Schmidt <schmidt@php.net>
|
* @author Christian Schmidt <schmidt@php.net>
|
||||||
* @copyright 2007-2009 Peytz & Co. A/S
|
* @copyright 2007-2009 Peytz & Co. A/S
|
||||||
* @license http://www.opensource.org/licenses/bsd-license.php New BSD License
|
* @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause
|
||||||
* @version Release: @package_version@
|
* @version Release: 2.1.2
|
||||||
* @link http://pear.php.net/package/Net_URL2
|
* @link https://pear.php.net/package/Net_URL2
|
||||||
*/
|
*/
|
||||||
class Net_URL2
|
class Net_URL2
|
||||||
{
|
{
|
||||||
|
@ -67,6 +67,12 @@ class Net_URL2
|
||||||
*/
|
*/
|
||||||
const OPTION_USE_BRACKETS = 'use_brackets';
|
const OPTION_USE_BRACKETS = 'use_brackets';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop zero-based integer sequences in query using PHP's [] notation. Default
|
||||||
|
* is true.
|
||||||
|
*/
|
||||||
|
const OPTION_DROP_SEQUENCE = 'drop_sequence';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL-encode query variable keys. Default is true.
|
* URL-encode query variable keys. Default is true.
|
||||||
*/
|
*/
|
||||||
|
@ -90,6 +96,7 @@ class Net_URL2
|
||||||
private $_options = array(
|
private $_options = array(
|
||||||
self::OPTION_STRICT => true,
|
self::OPTION_STRICT => true,
|
||||||
self::OPTION_USE_BRACKETS => true,
|
self::OPTION_USE_BRACKETS => true,
|
||||||
|
self::OPTION_DROP_SEQUENCE => true,
|
||||||
self::OPTION_ENCODE_KEYS => true,
|
self::OPTION_ENCODE_KEYS => true,
|
||||||
self::OPTION_SEPARATOR_INPUT => '&',
|
self::OPTION_SEPARATOR_INPUT => '&',
|
||||||
self::OPTION_SEPARATOR_OUTPUT => '&',
|
self::OPTION_SEPARATOR_OUTPUT => '&',
|
||||||
|
@ -136,7 +143,6 @@ class Net_URL2
|
||||||
* @param string $url an absolute or relative URL
|
* @param string $url an absolute or relative URL
|
||||||
* @param array $options an array of OPTION_xxx constants
|
* @param array $options an array of OPTION_xxx constants
|
||||||
*
|
*
|
||||||
* @return $this
|
|
||||||
* @uses self::parseUrl()
|
* @uses self::parseUrl()
|
||||||
*/
|
*/
|
||||||
public function __construct($url, array $options = array())
|
public function __construct($url, array $options = array())
|
||||||
|
@ -156,8 +162,9 @@ class Net_URL2
|
||||||
* This method will magically set the value of a private variable ($var)
|
* This method will magically set the value of a private variable ($var)
|
||||||
* with the value passed as the args
|
* with the value passed as the args
|
||||||
*
|
*
|
||||||
* @param string $var The private variable to set.
|
* @param string $var The private variable to set.
|
||||||
* @param mixed $arg An argument of any type.
|
* @param mixed $arg An argument of any type.
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function __set($var, $arg)
|
public function __set($var, $arg)
|
||||||
|
@ -174,10 +181,11 @@ class Net_URL2
|
||||||
* This is the magic get method to retrieve the private variable
|
* This is the magic get method to retrieve the private variable
|
||||||
* that was set by either __set() or it's setter...
|
* that was set by either __set() or it's setter...
|
||||||
*
|
*
|
||||||
* @param string $var The property name to retrieve.
|
* @param string $var The property name to retrieve.
|
||||||
* @return mixed $this->$var Either a boolean false if the
|
*
|
||||||
* property is not set or the value
|
* @return mixed $this->$var Either a boolean false if the
|
||||||
* of the private property.
|
* property is not set or the value
|
||||||
|
* of the private property.
|
||||||
*/
|
*/
|
||||||
public function __get($var)
|
public function __get($var)
|
||||||
{
|
{
|
||||||
|
@ -193,7 +201,7 @@ class Net_URL2
|
||||||
* Returns the scheme, e.g. "http" or "urn", or false if there is no
|
* Returns the scheme, e.g. "http" or "urn", or false if there is no
|
||||||
* scheme specified, i.e. if this is a relative URL.
|
* scheme specified, i.e. if this is a relative URL.
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
*/
|
*/
|
||||||
public function getScheme()
|
public function getScheme()
|
||||||
{
|
{
|
||||||
|
@ -209,7 +217,7 @@ class Net_URL2
|
||||||
* URL
|
* URL
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
* @see getScheme()
|
* @see getScheme
|
||||||
*/
|
*/
|
||||||
public function setScheme($scheme)
|
public function setScheme($scheme)
|
||||||
{
|
{
|
||||||
|
@ -221,12 +229,12 @@ class Net_URL2
|
||||||
* Returns the user part of the userinfo part (the part preceding the first
|
* Returns the user part of the userinfo part (the part preceding the first
|
||||||
* ":"), or false if there is no userinfo part.
|
* ":"), or false if there is no userinfo part.
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
*/
|
*/
|
||||||
public function getUser()
|
public function getUser()
|
||||||
{
|
{
|
||||||
return $this->_userinfo !== false
|
return $this->_userinfo !== false
|
||||||
? preg_replace('@:.*$@', '', $this->_userinfo)
|
? preg_replace('(:.*$)', '', $this->_userinfo)
|
||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +244,7 @@ class Net_URL2
|
||||||
* contain "@" in front of the hostname) or the userinfo part does not
|
* contain "@" in front of the hostname) or the userinfo part does not
|
||||||
* contain ":".
|
* contain ":".
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
*/
|
*/
|
||||||
public function getPassword()
|
public function getPassword()
|
||||||
{
|
{
|
||||||
|
@ -249,7 +257,7 @@ class Net_URL2
|
||||||
* Returns the userinfo part, or false if there is none, i.e. if the
|
* Returns the userinfo part, or false if there is none, i.e. if the
|
||||||
* authority part does not contain "@".
|
* authority part does not contain "@".
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
*/
|
*/
|
||||||
public function getUserinfo()
|
public function getUserinfo()
|
||||||
{
|
{
|
||||||
|
@ -267,10 +275,15 @@ class Net_URL2
|
||||||
*/
|
*/
|
||||||
public function setUserinfo($userinfo, $password = false)
|
public function setUserinfo($userinfo, $password = false)
|
||||||
{
|
{
|
||||||
$this->_userinfo = $userinfo;
|
|
||||||
if ($password !== false) {
|
if ($password !== false) {
|
||||||
$this->_userinfo .= ':' . $password;
|
$userinfo .= ':' . $password;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($userinfo !== false) {
|
||||||
|
$userinfo = $this->_encodeData($userinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_userinfo = $userinfo;
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,7 +291,7 @@ class Net_URL2
|
||||||
* Returns the host part, or false if there is no authority part, e.g.
|
* Returns the host part, or false if there is no authority part, e.g.
|
||||||
* relative URLs.
|
* relative URLs.
|
||||||
*
|
*
|
||||||
* @return string|bool a hostname, an IP address, or false
|
* @return string|bool a hostname, an IP address, or false
|
||||||
*/
|
*/
|
||||||
public function getHost()
|
public function getHost()
|
||||||
{
|
{
|
||||||
|
@ -303,7 +316,7 @@ class Net_URL2
|
||||||
* Returns the port number, or false if there is no port number specified,
|
* Returns the port number, or false if there is no port number specified,
|
||||||
* i.e. if the default port is to be used.
|
* i.e. if the default port is to be used.
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
*/
|
*/
|
||||||
public function getPort()
|
public function getPort()
|
||||||
{
|
{
|
||||||
|
@ -332,13 +345,13 @@ class Net_URL2
|
||||||
*/
|
*/
|
||||||
public function getAuthority()
|
public function getAuthority()
|
||||||
{
|
{
|
||||||
if (!$this->_host) {
|
if (false === $this->_host) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$authority = '';
|
$authority = '';
|
||||||
|
|
||||||
if ($this->_userinfo !== false) {
|
if (strlen($this->_userinfo)) {
|
||||||
$authority .= $this->_userinfo . '@';
|
$authority .= $this->_userinfo . '@';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,7 +368,7 @@ class Net_URL2
|
||||||
* Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify
|
* Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify
|
||||||
* false if there is no authority.
|
* false if there is no authority.
|
||||||
*
|
*
|
||||||
* @param string|false $authority a hostname or an IP addresse, possibly
|
* @param string|bool $authority a hostname or an IP address, possibly
|
||||||
* with userinfo prefixed and port number
|
* with userinfo prefixed and port number
|
||||||
* appended, e.g. "foo:bar@example.org:81".
|
* appended, e.g. "foo:bar@example.org:81".
|
||||||
*
|
*
|
||||||
|
@ -366,15 +379,24 @@ class Net_URL2
|
||||||
$this->_userinfo = false;
|
$this->_userinfo = false;
|
||||||
$this->_host = false;
|
$this->_host = false;
|
||||||
$this->_port = false;
|
$this->_port = false;
|
||||||
if (preg_match('@^(([^\@]*)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) {
|
|
||||||
if ($reg[1]) {
|
|
||||||
$this->_userinfo = $reg[2];
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_host = $reg[3];
|
if ('' === $authority) {
|
||||||
if (isset($reg[5])) {
|
$this->_host = $authority;
|
||||||
$this->_port = $reg[5];
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!preg_match('(^(([^@]*)@)?(.+?)(:(\d*))?$)', $authority, $matches)) {
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($matches[1]) {
|
||||||
|
$this->_userinfo = $this->_encodeData($matches[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->_host = $matches[3];
|
||||||
|
|
||||||
|
if (isset($matches[5]) && strlen($matches[5])) {
|
||||||
|
$this->_port = $matches[5];
|
||||||
}
|
}
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
@ -407,7 +429,7 @@ class Net_URL2
|
||||||
* is not present in the URL.
|
* is not present in the URL.
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
* @see self::getQueryVariables()
|
* @see getQueryVariables
|
||||||
*/
|
*/
|
||||||
public function getQuery()
|
public function getQuery()
|
||||||
{
|
{
|
||||||
|
@ -421,7 +443,7 @@ class Net_URL2
|
||||||
* @param string|bool $query a query string, e.g. "foo=1&bar=2"
|
* @param string|bool $query a query string, e.g. "foo=1&bar=2"
|
||||||
*
|
*
|
||||||
* @return $this
|
* @return $this
|
||||||
* @see self::setQueryVariables()
|
* @see setQueryVariables
|
||||||
*/
|
*/
|
||||||
public function setQuery($query)
|
public function setQuery($query)
|
||||||
{
|
{
|
||||||
|
@ -432,7 +454,7 @@ class Net_URL2
|
||||||
/**
|
/**
|
||||||
* Returns the fragment name, or false if "#" is not present in the URL.
|
* Returns the fragment name, or false if "#" is not present in the URL.
|
||||||
*
|
*
|
||||||
* @return string|bool
|
* @return string|bool
|
||||||
*/
|
*/
|
||||||
public function getFragment()
|
public function getFragment()
|
||||||
{
|
{
|
||||||
|
@ -458,59 +480,167 @@ class Net_URL2
|
||||||
* $_GET in a PHP script. If the URL does not contain a "?", an empty array
|
* $_GET in a PHP script. If the URL does not contain a "?", an empty array
|
||||||
* is returned.
|
* is returned.
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getQueryVariables()
|
public function getQueryVariables()
|
||||||
{
|
{
|
||||||
$pattern = '/[' .
|
$separator = $this->getOption(self::OPTION_SEPARATOR_INPUT);
|
||||||
preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') .
|
$encodeKeys = $this->getOption(self::OPTION_ENCODE_KEYS);
|
||||||
']/';
|
$useBrackets = $this->getOption(self::OPTION_USE_BRACKETS);
|
||||||
$parts = preg_split($pattern, $this->_query, -1, PREG_SPLIT_NO_EMPTY);
|
|
||||||
$return = array();
|
$return = array();
|
||||||
|
|
||||||
foreach ($parts as $part) {
|
for ($part = strtok($this->_query, $separator);
|
||||||
if (strpos($part, '=') !== false) {
|
strlen($part);
|
||||||
list($key, $value) = explode('=', $part, 2);
|
$part = strtok($separator)
|
||||||
} else {
|
) {
|
||||||
$key = $part;
|
list($key, $value) = explode('=', $part, 2) + array(1 => '');
|
||||||
$value = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->getOption(self::OPTION_ENCODE_KEYS)) {
|
if ($encodeKeys) {
|
||||||
$key = rawurldecode($key);
|
$key = rawurldecode($key);
|
||||||
}
|
}
|
||||||
$value = rawurldecode($value);
|
$value = rawurldecode($value);
|
||||||
|
|
||||||
if ($this->getOption(self::OPTION_USE_BRACKETS) &&
|
if ($useBrackets) {
|
||||||
preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) {
|
$return = $this->_queryArrayByKey($key, $value, $return);
|
||||||
|
} else {
|
||||||
$key = $matches[1];
|
if (isset($return[$key])) {
|
||||||
$idx = $matches[2];
|
$return[$key] = (array) $return[$key];
|
||||||
|
|
||||||
// Ensure is an array
|
|
||||||
if (empty($return[$key]) || !is_array($return[$key])) {
|
|
||||||
$return[$key] = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add data
|
|
||||||
if ($idx === '') {
|
|
||||||
$return[$key][] = $value;
|
$return[$key][] = $value;
|
||||||
} else {
|
} else {
|
||||||
$return[$key][$idx] = $value;
|
$return[$key] = $value;
|
||||||
}
|
}
|
||||||
} elseif (!$this->getOption(self::OPTION_USE_BRACKETS)
|
|
||||||
&& !empty($return[$key])
|
|
||||||
) {
|
|
||||||
$return[$key] = (array) $return[$key];
|
|
||||||
$return[$key][] = $value;
|
|
||||||
} else {
|
|
||||||
$return[$key] = $value;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $return;
|
return $return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a single query key=value pair into an existing php array
|
||||||
|
*
|
||||||
|
* @param string $key query-key
|
||||||
|
* @param string $value query-value
|
||||||
|
* @param array $array of existing query variables (if any)
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
private function _queryArrayByKey($key, $value, array $array = array())
|
||||||
|
{
|
||||||
|
if (!strlen($key)) {
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
$offset = $this->_queryKeyBracketOffset($key);
|
||||||
|
if ($offset === false) {
|
||||||
|
$name = $key;
|
||||||
|
} else {
|
||||||
|
$name = substr($key, 0, $offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strlen($name)) {
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$offset) {
|
||||||
|
// named value
|
||||||
|
$array[$name] = $value;
|
||||||
|
} else {
|
||||||
|
// array
|
||||||
|
$brackets = substr($key, $offset);
|
||||||
|
if (!isset($array[$name])) {
|
||||||
|
$array[$name] = null;
|
||||||
|
}
|
||||||
|
$array[$name] = $this->_queryArrayByBrackets(
|
||||||
|
$brackets, $value, $array[$name]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a key-buffer to place value in array
|
||||||
|
*
|
||||||
|
* @param string $buffer to consume all keys from
|
||||||
|
* @param string $value to be set/add
|
||||||
|
* @param array $array to traverse and set/add value in
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function _queryArrayByBrackets($buffer, $value, array $array = null)
|
||||||
|
{
|
||||||
|
$entry = &$array;
|
||||||
|
|
||||||
|
for ($iteration = 0; strlen($buffer); $iteration++) {
|
||||||
|
$open = $this->_queryKeyBracketOffset($buffer);
|
||||||
|
if ($open !== 0) {
|
||||||
|
// Opening bracket [ must exist at offset 0, if not, there is
|
||||||
|
// no bracket to parse and the value dropped.
|
||||||
|
// if this happens in the first iteration, this is flawed, see
|
||||||
|
// as well the second exception below.
|
||||||
|
if ($iteration) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
throw new Exception(
|
||||||
|
'Net_URL2 Internal Error: '. __METHOD__ .'(): ' .
|
||||||
|
'Opening bracket [ must exist at offset 0'
|
||||||
|
);
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
$close = strpos($buffer, ']', 1);
|
||||||
|
if (!$close) {
|
||||||
|
// this error condition should never be reached as this is a
|
||||||
|
// private method and bracket pairs are checked beforehand.
|
||||||
|
// See as well the first exception for the opening bracket.
|
||||||
|
// @codeCoverageIgnoreStart
|
||||||
|
throw new Exception(
|
||||||
|
'Net_URL2 Internal Error: '. __METHOD__ .'(): ' .
|
||||||
|
'Closing bracket ] must exist, not found'
|
||||||
|
);
|
||||||
|
// @codeCoverageIgnoreEnd
|
||||||
|
}
|
||||||
|
|
||||||
|
$index = substr($buffer, 1, $close - 1);
|
||||||
|
if (strlen($index)) {
|
||||||
|
$entry = &$entry[$index];
|
||||||
|
} else {
|
||||||
|
if (!is_array($entry)) {
|
||||||
|
$entry = array();
|
||||||
|
}
|
||||||
|
$entry[] = &$new;
|
||||||
|
$entry = &$new;
|
||||||
|
unset($new);
|
||||||
|
}
|
||||||
|
$buffer = substr($buffer, $close + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
$entry = $value;
|
||||||
|
|
||||||
|
return $array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query-key has brackets ("...[]")
|
||||||
|
*
|
||||||
|
* @param string $key query-key
|
||||||
|
*
|
||||||
|
* @return bool|int offset of opening bracket, false if no brackets
|
||||||
|
*/
|
||||||
|
private function _queryKeyBracketOffset($key)
|
||||||
|
{
|
||||||
|
if (false !== $open = strpos($key, '[')
|
||||||
|
and false === strpos($key, ']', $open + 1)
|
||||||
|
) {
|
||||||
|
$open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $open;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the query string to the specified variable in the query string.
|
* Sets the query string to the specified variable in the query string.
|
||||||
*
|
*
|
||||||
|
@ -548,7 +678,7 @@ class Net_URL2
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the specifed variable from the query string.
|
* Removes the specified variable from the query string.
|
||||||
*
|
*
|
||||||
* @param string $name a query string variable, e.g. "foo" in "?foo=1"
|
* @param string $name a query string variable, e.g. "foo" in "?foo=1"
|
||||||
*
|
*
|
||||||
|
@ -564,22 +694,23 @@ class Net_URL2
|
||||||
/**
|
/**
|
||||||
* Returns a string representation of this URL.
|
* Returns a string representation of this URL.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getURL()
|
public function getURL()
|
||||||
{
|
{
|
||||||
// See RFC 3986, section 5.3
|
// See RFC 3986, section 5.3
|
||||||
$url = "";
|
$url = '';
|
||||||
|
|
||||||
if ($this->_scheme !== false) {
|
if ($this->_scheme !== false) {
|
||||||
$url .= $this->_scheme . ':';
|
$url .= $this->_scheme . ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
$authority = $this->getAuthority();
|
$authority = $this->getAuthority();
|
||||||
if ($authority !== false) {
|
if ($authority === false && strtolower($this->_scheme) === 'file') {
|
||||||
$url .= '//' . $authority;
|
$authority = '';
|
||||||
}
|
}
|
||||||
$url .= $this->_path;
|
|
||||||
|
$url .= $this->_buildAuthorityAndPath($authority, $this->_path);
|
||||||
|
|
||||||
if ($this->_query !== false) {
|
if ($this->_query !== false) {
|
||||||
$url .= '?' . $this->_query;
|
$url .= '?' . $this->_query;
|
||||||
|
@ -592,11 +723,31 @@ class Net_URL2
|
||||||
return $url;
|
return $url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put authority and path together, wrapping authority
|
||||||
|
* into proper separators/terminators.
|
||||||
|
*
|
||||||
|
* @param string|bool $authority authority
|
||||||
|
* @param string $path path
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function _buildAuthorityAndPath($authority, $path)
|
||||||
|
{
|
||||||
|
if ($authority === false) {
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
$terminator = ($path !== '' && $path[0] !== '/') ? '/' : '';
|
||||||
|
|
||||||
|
return '//' . $authority . $terminator . $path;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a string representation of this URL.
|
* Returns a string representation of this URL.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
* @see toString()
|
* @link https://php.net/language.oop5.magic#object.tostring
|
||||||
*/
|
*/
|
||||||
public function __toString()
|
public function __toString()
|
||||||
{
|
{
|
||||||
|
@ -607,64 +758,112 @@ class Net_URL2
|
||||||
* Returns a normalized string representation of this URL. This is useful
|
* Returns a normalized string representation of this URL. This is useful
|
||||||
* for comparison of URLs.
|
* for comparison of URLs.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getNormalizedURL()
|
public function getNormalizedURL()
|
||||||
{
|
{
|
||||||
$url = clone $this;
|
$url = clone $this;
|
||||||
$url->normalize();
|
$url->normalize();
|
||||||
return $url->getUrl();
|
return $url->getURL();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a normalized Net_URL2 instance.
|
* Normalizes the URL
|
||||||
*
|
*
|
||||||
* @return Net_URL2
|
* See RFC 3986, Section 6. Normalization and Comparison
|
||||||
|
*
|
||||||
|
* @link https://tools.ietf.org/html/rfc3986#section-6
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function normalize()
|
public function normalize()
|
||||||
{
|
{
|
||||||
// See RFC 3886, section 6
|
// See RFC 3986, section 6
|
||||||
|
|
||||||
// Schemes are case-insensitive
|
// Scheme is case-insensitive
|
||||||
if ($this->_scheme) {
|
if ($this->_scheme) {
|
||||||
$this->_scheme = strtolower($this->_scheme);
|
$this->_scheme = strtolower($this->_scheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hostnames are case-insensitive
|
// Hostname is case-insensitive
|
||||||
if ($this->_host) {
|
if ($this->_host) {
|
||||||
$this->_host = strtolower($this->_host);
|
$this->_host = strtolower($this->_host);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove default port number for known schemes (RFC 3986, section 6.2.3)
|
// Remove default port number for known schemes (RFC 3986, section 6.2.3)
|
||||||
if ($this->_port &&
|
if ('' === $this->_port
|
||||||
$this->_scheme &&
|
|| $this->_port
|
||||||
$this->_port == getservbyname($this->_scheme, 'tcp')) {
|
&& $this->_scheme
|
||||||
|
&& $this->_port == getservbyname($this->_scheme, 'tcp')
|
||||||
|
) {
|
||||||
$this->_port = false;
|
$this->_port = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
|
// Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
|
||||||
foreach (array('_userinfo', '_host', '_path') as $part) {
|
// Normalize percentage-encoded unreserved characters (section 6.2.2.2)
|
||||||
if ($this->$part) {
|
$fields = array(&$this->_userinfo, &$this->_host, &$this->_path,
|
||||||
$this->$part = preg_replace('/%[0-9a-f]{2}/ie',
|
&$this->_query, &$this->_fragment);
|
||||||
'strtoupper("\0")',
|
foreach ($fields as &$field) {
|
||||||
$this->$part);
|
if ($field !== false) {
|
||||||
|
$field = $this->_normalize("$field");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
unset($field);
|
||||||
|
|
||||||
// Path segment normalization (RFC 3986, section 6.2.2.3)
|
// Path segment normalization (RFC 3986, section 6.2.2.3)
|
||||||
$this->_path = self::removeDotSegments($this->_path);
|
$this->_path = self::removeDotSegments($this->_path);
|
||||||
|
|
||||||
// Scheme based normalization (RFC 3986, section 6.2.3)
|
// Scheme based normalization (RFC 3986, section 6.2.3)
|
||||||
if ($this->_host && !$this->_path) {
|
if (false !== $this->_host && '' === $this->_path) {
|
||||||
$this->_path = '/';
|
$this->_path = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// path should start with '/' if there is authority (section 3.3.)
|
||||||
|
if (strlen($this->getAuthority())
|
||||||
|
&& strlen($this->_path)
|
||||||
|
&& $this->_path[0] !== '/'
|
||||||
|
) {
|
||||||
|
$this->_path = '/' . $this->_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1)
|
||||||
|
* Normalize percentage-encoded unreserved characters (section 6.2.2.2)
|
||||||
|
*
|
||||||
|
* @param string|array $mixed string or array of strings to normalize
|
||||||
|
*
|
||||||
|
* @return string|array
|
||||||
|
* @see normalize
|
||||||
|
* @see _normalizeCallback()
|
||||||
|
*/
|
||||||
|
private function _normalize($mixed)
|
||||||
|
{
|
||||||
|
return preg_replace_callback(
|
||||||
|
'((?:%[0-9a-fA-Z]{2})+)', array($this, '_normalizeCallback'),
|
||||||
|
$mixed
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for _normalize() of %XX percentage-encodings
|
||||||
|
*
|
||||||
|
* @param array $matches as by preg_replace_callback
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @see normalize
|
||||||
|
* @see _normalize
|
||||||
|
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
|
||||||
|
*/
|
||||||
|
private function _normalizeCallback($matches)
|
||||||
|
{
|
||||||
|
return self::urlencode(urldecode($matches[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this instance represents an absolute URL.
|
* Returns whether this instance represents an absolute URL.
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isAbsolute()
|
public function isAbsolute()
|
||||||
{
|
{
|
||||||
|
@ -677,20 +876,25 @@ class Net_URL2
|
||||||
*
|
*
|
||||||
* @param Net_URL2|string $reference relative URL
|
* @param Net_URL2|string $reference relative URL
|
||||||
*
|
*
|
||||||
* @return Net_URL2
|
* @throws Exception
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function resolve($reference)
|
public function resolve($reference)
|
||||||
{
|
{
|
||||||
if (!$reference instanceof Net_URL2) {
|
if (!$reference instanceof Net_URL2) {
|
||||||
$reference = new self($reference);
|
$reference = new self($reference);
|
||||||
}
|
}
|
||||||
if (!$this->isAbsolute()) {
|
if (!$reference->_isFragmentOnly() && !$this->isAbsolute()) {
|
||||||
throw new Exception('Base-URL must be absolute');
|
throw new Exception(
|
||||||
|
'Base-URL must be absolute if reference is not fragment-only'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A non-strict parser may ignore a scheme in the reference if it is
|
// A non-strict parser may ignore a scheme in the reference if it is
|
||||||
// identical to the base URI's scheme.
|
// identical to the base URI's scheme.
|
||||||
if (!$this->getOption(self::OPTION_STRICT) && $reference->_scheme == $this->_scheme) {
|
if (!$this->getOption(self::OPTION_STRICT)
|
||||||
|
&& $reference->_scheme == $this->_scheme
|
||||||
|
) {
|
||||||
$reference->_scheme = false;
|
$reference->_scheme = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -720,7 +924,7 @@ class Net_URL2
|
||||||
} else {
|
} else {
|
||||||
// Merge paths (RFC 3986, section 5.2.3)
|
// Merge paths (RFC 3986, section 5.2.3)
|
||||||
if ($this->_host !== false && $this->_path == '') {
|
if ($this->_host !== false && $this->_path == '') {
|
||||||
$target->_path = '/' . $this->_path;
|
$target->_path = '/' . $reference->_path;
|
||||||
} else {
|
} else {
|
||||||
$i = strrpos($this->_path, '/');
|
$i = strrpos($this->_path, '/');
|
||||||
if ($i !== false) {
|
if ($i !== false) {
|
||||||
|
@ -742,6 +946,25 @@ class Net_URL2
|
||||||
return $target;
|
return $target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* URL is fragment-only
|
||||||
|
*
|
||||||
|
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private function _isFragmentOnly()
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
$this->_fragment !== false
|
||||||
|
&& $this->_query === false
|
||||||
|
&& $this->_path === ''
|
||||||
|
&& $this->_port === false
|
||||||
|
&& $this->_host === false
|
||||||
|
&& $this->_userinfo === false
|
||||||
|
&& $this->_scheme === false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes dots as described in RFC 3986, section 5.2.4, e.g.
|
* Removes dots as described in RFC 3986, section 5.2.4, e.g.
|
||||||
* "/foo/../bar/baz" => "/bar/baz"
|
* "/foo/../bar/baz" => "/bar/baz"
|
||||||
|
@ -752,43 +975,52 @@ class Net_URL2
|
||||||
*/
|
*/
|
||||||
public static function removeDotSegments($path)
|
public static function removeDotSegments($path)
|
||||||
{
|
{
|
||||||
|
$path = (string) $path;
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
// Make sure not to be trapped in an infinite loop due to a bug in this
|
// Make sure not to be trapped in an infinite loop due to a bug in this
|
||||||
// method
|
// method
|
||||||
|
$loopLimit = 256;
|
||||||
$j = 0;
|
$j = 0;
|
||||||
while ($path && $j++ < 100) {
|
while ('' !== $path && $j++ < $loopLimit) {
|
||||||
if (substr($path, 0, 2) == './') {
|
if (substr($path, 0, 2) === './') {
|
||||||
// Step 2.A
|
// Step 2.A
|
||||||
$path = substr($path, 2);
|
$path = substr($path, 2);
|
||||||
} elseif (substr($path, 0, 3) == '../') {
|
} elseif (substr($path, 0, 3) === '../') {
|
||||||
// Step 2.A
|
// Step 2.A
|
||||||
$path = substr($path, 3);
|
$path = substr($path, 3);
|
||||||
} elseif (substr($path, 0, 3) == '/./' || $path == '/.') {
|
} elseif (substr($path, 0, 3) === '/./' || $path === '/.') {
|
||||||
// Step 2.B
|
// Step 2.B
|
||||||
$path = '/' . substr($path, 3);
|
$path = '/' . substr($path, 3);
|
||||||
} elseif (substr($path, 0, 4) == '/../' || $path == '/..') {
|
} elseif (substr($path, 0, 4) === '/../' || $path === '/..') {
|
||||||
// Step 2.C
|
// Step 2.C
|
||||||
$path = '/' . substr($path, 4);
|
$path = '/' . substr($path, 4);
|
||||||
$i = strrpos($output, '/');
|
$i = strrpos($output, '/');
|
||||||
$output = $i === false ? '' : substr($output, 0, $i);
|
$output = $i === false ? '' : substr($output, 0, $i);
|
||||||
} elseif ($path == '.' || $path == '..') {
|
} elseif ($path === '.' || $path === '..') {
|
||||||
// Step 2.D
|
// Step 2.D
|
||||||
$path = '';
|
$path = '';
|
||||||
} else {
|
} else {
|
||||||
// Step 2.E
|
// Step 2.E
|
||||||
$i = strpos($path, '/');
|
$i = strpos($path, '/', $path[0] === '/');
|
||||||
if ($i === 0) {
|
|
||||||
$i = strpos($path, '/', 1);
|
|
||||||
}
|
|
||||||
if ($i === false) {
|
if ($i === false) {
|
||||||
$i = strlen($path);
|
$output .= $path;
|
||||||
|
$path = '';
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
$output .= substr($path, 0, $i);
|
$output .= substr($path, 0, $i);
|
||||||
$path = substr($path, $i);
|
$path = substr($path, $i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($path !== '') {
|
||||||
|
$message = sprintf(
|
||||||
|
'Unable to remove dot segments; hit loop limit %d (left: %s)',
|
||||||
|
$j, var_export($path, true)
|
||||||
|
);
|
||||||
|
trigger_error($message, E_USER_WARNING);
|
||||||
|
}
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -797,12 +1029,13 @@ class Net_URL2
|
||||||
* Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP
|
* Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP
|
||||||
* 5.2.x and earlier.
|
* 5.2.x and earlier.
|
||||||
*
|
*
|
||||||
* @param $raw the string to encode
|
* @param string $string string to encode
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function urlencode($string)
|
public static function urlencode($string)
|
||||||
{
|
{
|
||||||
$encoded = rawurlencode($string);
|
$encoded = rawurlencode($string);
|
||||||
|
|
||||||
// This is only necessary in PHP < 5.3.
|
// This is only necessary in PHP < 5.3.
|
||||||
$encoded = str_replace('%7E', '~', $encoded);
|
$encoded = str_replace('%7E', '~', $encoded);
|
||||||
|
@ -813,7 +1046,8 @@ class Net_URL2
|
||||||
* Returns a Net_URL2 instance representing the canonical URL of the
|
* Returns a Net_URL2 instance representing the canonical URL of the
|
||||||
* currently executing PHP script.
|
* currently executing PHP script.
|
||||||
*
|
*
|
||||||
* @return string
|
* @throws Exception
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function getCanonical()
|
public static function getCanonical()
|
||||||
{
|
{
|
||||||
|
@ -827,9 +1061,9 @@ class Net_URL2
|
||||||
$url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
|
$url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http';
|
||||||
$url->_host = $_SERVER['SERVER_NAME'];
|
$url->_host = $_SERVER['SERVER_NAME'];
|
||||||
$port = $_SERVER['SERVER_PORT'];
|
$port = $_SERVER['SERVER_PORT'];
|
||||||
if ($url->_scheme == 'http' && $port != 80 ||
|
if ($url->_scheme == 'http' && $port != 80
|
||||||
$url->_scheme == 'https' && $port != 443) {
|
|| $url->_scheme == 'https' && $port != 443
|
||||||
|
) {
|
||||||
$url->_port = $port;
|
$url->_port = $port;
|
||||||
}
|
}
|
||||||
return $url;
|
return $url;
|
||||||
|
@ -849,7 +1083,8 @@ class Net_URL2
|
||||||
* Returns a Net_URL2 instance representing the URL used to retrieve the
|
* Returns a Net_URL2 instance representing the URL used to retrieve the
|
||||||
* current request.
|
* current request.
|
||||||
*
|
*
|
||||||
* @return Net_URL2
|
* @throws Exception
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public static function getRequested()
|
public static function getRequested()
|
||||||
{
|
{
|
||||||
|
@ -871,7 +1106,7 @@ class Net_URL2
|
||||||
*
|
*
|
||||||
* @param string $optionName The name of the option to retrieve
|
* @param string $optionName The name of the option to retrieve
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getOption($optionName)
|
public function getOption($optionName)
|
||||||
{
|
{
|
||||||
|
@ -885,7 +1120,7 @@ class Net_URL2
|
||||||
*
|
*
|
||||||
* @param array $data An array, which has to be converted into
|
* @param array $data An array, which has to be converted into
|
||||||
* QUERY_STRING. Anything is possible.
|
* QUERY_STRING. Anything is possible.
|
||||||
* @param string $seperator See {@link self::OPTION_SEPARATOR_OUTPUT}
|
* @param string $separator Separator {@link self::OPTION_SEPARATOR_OUTPUT}
|
||||||
* @param string $key For stacked values (arrays in an array).
|
* @param string $key For stacked values (arrays in an array).
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
|
@ -893,12 +1128,17 @@ class Net_URL2
|
||||||
protected function buildQuery(array $data, $separator, $key = null)
|
protected function buildQuery(array $data, $separator, $key = null)
|
||||||
{
|
{
|
||||||
$query = array();
|
$query = array();
|
||||||
|
$drop_names = (
|
||||||
|
$this->_options[self::OPTION_DROP_SEQUENCE] === true
|
||||||
|
&& array_keys($data) === array_keys(array_values($data))
|
||||||
|
);
|
||||||
foreach ($data as $name => $value) {
|
foreach ($data as $name => $value) {
|
||||||
if ($this->getOption(self::OPTION_ENCODE_KEYS) === true) {
|
if ($this->getOption(self::OPTION_ENCODE_KEYS) === true) {
|
||||||
$name = rawurlencode($name);
|
$name = rawurlencode($name);
|
||||||
}
|
}
|
||||||
if ($key !== null) {
|
if ($key !== null) {
|
||||||
if ($this->getOption(self::OPTION_USE_BRACKETS) === true) {
|
if ($this->getOption(self::OPTION_USE_BRACKETS) === true) {
|
||||||
|
$drop_names && $name = '';
|
||||||
$name = $key . '[' . $name . ']';
|
$name = $key . '[' . $name . ']';
|
||||||
} else {
|
} else {
|
||||||
$name = $key;
|
$name = $key;
|
||||||
|
@ -914,29 +1154,66 @@ class Net_URL2
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method uses a funky regex to parse the url into the designated parts.
|
* This method uses a regex to parse the url into the designated parts.
|
||||||
*
|
*
|
||||||
* @param string $url
|
* @param string $url URL
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
* @uses self::$_scheme, self::setAuthority(), self::$_path, self::$_query,
|
* @uses self::$_scheme, self::setAuthority(), self::$_path, self::$_query,
|
||||||
* self::$_fragment
|
* self::$_fragment
|
||||||
* @see self::__construct()
|
* @see __construct
|
||||||
*/
|
*/
|
||||||
protected function parseUrl($url)
|
protected function parseUrl($url)
|
||||||
{
|
{
|
||||||
// The regular expression is copied verbatim from RFC 3986, appendix B.
|
// The regular expression is copied verbatim from RFC 3986, appendix B.
|
||||||
// The expression does not validate the URL but matches any string.
|
// The expression does not validate the URL but matches any string.
|
||||||
preg_match('!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?!',
|
preg_match(
|
||||||
$url,
|
'(^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)',
|
||||||
$matches);
|
$url, $matches
|
||||||
|
);
|
||||||
|
|
||||||
// "path" is always present (possibly as an empty string); the rest
|
// "path" is always present (possibly as an empty string); the rest
|
||||||
// are optional.
|
// are optional.
|
||||||
$this->_scheme = !empty($matches[1]) ? $matches[2] : false;
|
$this->_scheme = !empty($matches[1]) ? $matches[2] : false;
|
||||||
$this->setAuthority(!empty($matches[3]) ? $matches[4] : false);
|
$this->setAuthority(!empty($matches[3]) ? $matches[4] : false);
|
||||||
$this->_path = $matches[5];
|
$this->_path = $this->_encodeData($matches[5]);
|
||||||
$this->_query = !empty($matches[6]) ? $matches[7] : false;
|
$this->_query = !empty($matches[6])
|
||||||
|
? $this->_encodeData($matches[7])
|
||||||
|
: false
|
||||||
|
;
|
||||||
$this->_fragment = !empty($matches[8]) ? $matches[9] : false;
|
$this->_fragment = !empty($matches[8]) ? $matches[9] : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode characters that might have been forgotten to encode when passing
|
||||||
|
* in an URL. Applied onto Userinfo, Path and Query.
|
||||||
|
*
|
||||||
|
* @param string $url URL
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @see parseUrl
|
||||||
|
* @see setAuthority
|
||||||
|
* @link https://pear.php.net/bugs/bug.php?id=20425
|
||||||
|
*/
|
||||||
|
private function _encodeData($url)
|
||||||
|
{
|
||||||
|
return preg_replace_callback(
|
||||||
|
'([\x-\x20\x22\x3C\x3E\x7F-\xFF]+)',
|
||||||
|
array($this, '_encodeCallback'), $url
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* callback for encoding character data
|
||||||
|
*
|
||||||
|
* @param array $matches Matches
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @see _encodeData
|
||||||
|
* @SuppressWarnings(PHPMD.UnusedPrivateMethod)
|
||||||
|
*/
|
||||||
|
private function _encodeCallback(array $matches)
|
||||||
|
{
|
||||||
|
return rawurlencode($matches[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user