1,102 → 1,81 |
<?php |
// +-----------------------------------------------------------------------+ |
// | Copyright (c) 2007-2008, Christian Schmidt, Peytz & Co. A/S | |
// | All rights reserved. | |
// | | |
// | Redistribution and use in source and binary forms, with or without | |
// | modification, are permitted provided that the following conditions | |
// | are met: | |
// | | |
// | o Redistributions of source code must retain the above copyright | |
// | notice, this list of conditions and the following disclaimer. | |
// | o 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.| |
// | o The names of the authors may not 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 | |
// | OWNER 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. | |
// | | |
// +-----------------------------------------------------------------------+ |
// | Author: Christian Schmidt <schmidt at php dot net> | |
// +-----------------------------------------------------------------------+ |
// |
// $Id$ |
// |
// Net_URL2 Class (PHP5 Only) |
|
// This code is released under the BSD License - http://www.opensource.org/licenses/bsd-license.php |
// declare(encoding='UTF-8'); |
/** |
* @license BSD License |
*/ |
* classe Url, gérant le découpage des paramètres, leurs modification etc... |
* Traduction et conversion d'une classe (NET_Url2) issue de Pear |
* |
* PHP Version 5 |
* |
* @category Class |
* @package Framework |
// auteur principal |
* @author Christian Schmidt <schmidt@php.net> |
// autre auteurs |
* @author aurelien <aurelien@tela-botanica.org> |
* @copyright 2009 Tela-Botanica |
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL |
* @license http://www.gnu.org/licenses/gpl.html Licence GNU-GPL |
* @version SVN: $Id$ |
* @link /doc/framework/ |
* |
*/ |
class Url |
{ |
/** |
* Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default |
* is true. |
* Parsing strict dans resoudre() (voir RFC 3986, section 5.2.2). Par défaut |
* à true. |
*/ |
const OPTION_STRICT = 'strict'; |
const OPTION_STRICTE = 'strict'; |
|
/** |
* Represent arrays in query using PHP's [] notation. Default is true. |
* Répresenter les tableaux dans les requêtes en utilisant la notation php []. Par défaut à true. |
*/ |
const OPTION_USE_BRACKETS = 'use_brackets'; |
const OPTION_UTILISER_CROCHETS = 'use_brackets'; |
|
/** |
* URL-encode query variable keys. Default is true. |
* URL-encoder les clés des variables dans les requêtes. Par défaut à true. |
*/ |
const OPTION_ENCODE_KEYS = 'encode_keys'; |
const OPTION_ENCODER_CLES = 'encode_keys'; |
|
/** |
* Query variable separators when parsing the query string. Every character |
* is considered a separator. Default is specified by the |
* arg_separator.input php.ini setting (this defaults to "&"). |
* Séparateurs de variables lors du parsing de la requête. Chaque caractère |
* est considéré comme un séparateur. Par défaut, spécifié par le paramêtre |
* arg_separator.input dans php.ini (par défaut "&"). |
*/ |
const OPTION_SEPARATOR_INPUT = 'input_separator'; |
const OPTION_SEPARATEUR_ENTREE = 'input_separator'; |
|
/** |
* Query variable separator used when generating the query string. Default |
* is specified by the arg_separator.output php.ini setting (this defaults |
* to "&"). |
* Séparateur de variables lors de la génération de la requête. Par défaut, spécifié |
* par le paramètre arg_separator.output dans php.ini (par défaut "&"). |
*/ |
const OPTION_SEPARATOR_OUTPUT = 'output_separator'; |
const OPTION_SEPARATEUR_SORTIE = 'output_separator'; |
|
/** |
* Default options corresponds to how PHP handles $_GET. |
* Options par défaut correspondant au comportement de php |
* vis à vis de $_GET |
*/ |
private $options = array( |
self::OPTION_STRICT => true, |
self::OPTION_USE_BRACKETS => true, |
self::OPTION_ENCODE_KEYS => true, |
self::OPTION_SEPARATOR_INPUT => 'x&', |
self::OPTION_SEPARATOR_OUTPUT => 'x&', |
self::OPTION_STRICTE => true, |
self::OPTION_UTILISER_CROCHETS => true, |
self::OPTION_ENCODER_CLES => true, |
self::OPTION_SEPARATEUR_ENTREE => 'x&', |
self::OPTION_SEPARATEUR_SORTIE => 'x&', |
); |
|
/** |
* @var string|bool |
*/ |
private $scheme = false; |
private $schema = false; |
|
/** |
* @var string|bool |
*/ |
private $userinfo = false; |
private $infoUtilisateur = false; |
|
/** |
* @var string|bool |
*/ |
private $host = false; |
private $hote = false; |
|
/** |
* @var int|bool |
106,12 → 85,12 |
/** |
* @var string |
*/ |
private $path = ''; |
private $chemin = ''; |
|
/** |
* @var string|bool |
*/ |
private $query = false; |
private $requete = false; |
|
/** |
* @var string|bool |
119,37 → 98,37 |
private $fragment = false; |
|
/** |
* @param string $url an absolute or relative URL |
* @param string $url une URL relative ou absolue |
* @param array $options |
*/ |
public function __construct($url, $options = null) |
{ |
$this->setOption(self::OPTION_SEPARATOR_INPUT, |
$this->setOption(self::OPTION_SEPARATEUR_ENTREE, |
ini_get('arg_separator.input')); |
$this->setOption(self::OPTION_SEPARATOR_OUTPUT, |
$this->setOption(self::OPTION_SEPARATEUR_SORTIE, |
ini_get('arg_separator.output')); |
if (is_array($options)) { |
foreach ($options as $optionName => $value) { |
$this->setOption($optionName); |
foreach ($options as $nomOption => $valeur) { |
$this->setOption($nomOption); |
} |
} |
|
if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) { |
$this->scheme = $reg[1]; |
$this->schema = $reg[1]; |
$url = substr($url, strlen($reg[0])); |
} |
|
if (preg_match('@^//([^/#?]+)@', $url, $reg)) { |
$this->setAuthority($reg[1]); |
$this->setAutorite($reg[1]); |
$url = substr($url, strlen($reg[0])); |
} |
|
$i = strcspn($url, '?#'); |
$this->path = substr($url, 0, $i); |
$this->chemin = substr($url, 0, $i); |
$url = substr($url, $i); |
|
if (preg_match('@^\?([^#]*)@', $url, $reg)) { |
$this->query = $reg[1]; |
$this->requete = $reg[1]; |
$url = substr($url, strlen($reg[0])); |
} |
|
159,103 → 138,102 |
} |
|
/** |
* Returns the scheme, e.g. "http" or "urn", or false if there is no |
* scheme specified, i.e. if this is a relative URL. |
* Retourne le schéma, c.a.d. "http" ou "urn", ou false si aucun schéma n'est |
* spécifié, i.e. l'url est une url relative |
* |
* @return string|bool |
*/ |
public function getScheme() |
public function getSchema() |
{ |
return $this->scheme; |
return $this->schema; |
} |
|
/** |
* @param string|bool $scheme |
* @param string|bool $schema |
* |
* @return void |
* @see getScheme() |
* @see getSchema() |
*/ |
public function setScheme($scheme) |
public function setSchema($schema) |
{ |
$this->scheme = $scheme; |
$this->schema = $schema; |
} |
|
/** |
* Returns the user part of the userinfo part (the part preceding the first |
* ":"), or false if there is no userinfo part. |
* renvoie la partie user de la partie infoUtilisateur (partie précédant le premier |
* ":"), ou false si aucune partie infoUtilisateur n'est définie. |
* |
* @return string|bool |
*/ |
public function getUser() |
public function getUtilisateur() |
{ |
return $this->userinfo !== false ? preg_replace('@:.*$@', '', $this->userinfo) : false; |
return $this->infoUtilisateur !== false ? preg_replace('@:.*$@', '', $this->infoUtilisateur) : false; |
} |
|
/** |
* Returns the password part of the userinfo part (the part after the first |
* ":"), or false if there is no userinfo part (i.e. the URL does not |
* contain "@" in front of the hostname) or the userinfo part does not |
* contain ":". |
* renvoie la partie mot de passe de la partie infoUtilisateur (partie après le premier |
* ":"), , ou false si aucune partie infoUtilisateur n'est définie (i.e. l'URL ne contient |
* pas de "@" en face du nom d'hôte) ou si la partie infoUtilisateur ne contient pas de ":". |
* |
* @return string|bool |
*/ |
public function getPassword() |
public function getMotDePasse() |
{ |
return $this->userinfo !== false ? substr(strstr($this->userinfo, ':'), 1) : false; |
return $this->infoUtilisateur !== false ? substr(strstr($this->infoUtilisateur, ':'), 1) : false; |
} |
|
/** |
* Returns the userinfo part, or false if there is none, i.e. if the |
* authority part does not contain "@". |
* Renvoie la partie userinfio, ou false si celle-ci n'existe pas, i.e. si la partie |
* autorité ne contient pas de "@" |
* |
* @return string|bool |
*/ |
public function getUserinfo() |
public function getInfoUtilisateur() |
{ |
return $this->userinfo; |
return $this->infoUtilisateur; |
} |
|
/** |
* Sets the userinfo part. If two arguments are passed, they are combined |
* in the userinfo part as username ":" password. |
* Setteur pour la partie infoUtilisateur. Si deux argument sont passé, ils sont combinés |
* dans la partie infoUtilisateur de cette manière username ":" password. |
* |
* @param string|bool $userinfo userinfo or username |
* @param string|bool $password |
* @param string|bool $infoUtilisateur infoUtilisateur ou username |
* @param string|bool $motDePasse |
* |
* @return void |
*/ |
public function setUserinfo($userinfo, $password = false) |
public function setInfoUtilisateur($infoUtilisateur, $motDePasse = false) |
{ |
$this->userinfo = $userinfo; |
if ($password !== false) { |
$this->userinfo .= ':' . $password; |
$this->infoUtilisateur = $infoUtilisateur; |
if ($motDePasse !== false) { |
$this->infoUtilisateur .= ':' . $motDePasse; |
} |
} |
|
/** |
* Returns the host part, or false if there is no authority part, e.g. |
* relative URLs. |
* Renvoie la partie hôte, ou false s'il n'y a pas de partie autorité, c.a.d. |
* l'URL est relative. |
* |
* @return string|bool |
*/ |
public function getHost() |
public function getHote() |
{ |
return $this->host; |
return $this->hote; |
} |
|
/** |
* @param string|bool $host |
* @param string|bool $hote |
* |
* @return void |
*/ |
public function setHost($host) |
public function setHote($hote) |
{ |
$this->host = $host; |
$this->hote = $hote; |
} |
|
/** |
* Returns the port number, or false if there is no port number specified, |
* i.e. if the default port is to be used. |
* Renvoie le numéro de port, ou false si aucun numéro de port n'est spécifié, |
* i.e. le port par défaut doit utilisé. |
* |
* @return int|bool |
*/ |
275,49 → 253,49 |
} |
|
/** |
* Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or |
* false if there is no authority none. |
* Renvoie la partie autorité, i.e. [ infoUtilisateur "@" ] hote [ ":" port ], ou |
* false si celle-ci est absente. |
* |
* @return string|bool |
*/ |
public function getAuthority() |
public function getAutorite() |
{ |
if (!$this->host) { |
if (!$this->hote) { |
return false; |
} |
|
$authority = ''; |
$autorite = ''; |
|
if ($this->userinfo !== false) { |
$authority .= $this->userinfo . '@'; |
if ($this->infoUtilisateur !== false) { |
$autorite .= $this->infoUtilisateur . '@'; |
} |
|
$authority .= $this->host; |
$autorite .= $this->hote; |
|
if ($this->port !== false) { |
$authority .= ':' . $this->port; |
$autorite .= ':' . $this->port; |
} |
|
return $authority; |
return $autorite; |
} |
|
/** |
* @param string|false $authority |
* @param string|false $autorite |
* |
* @return void |
*/ |
public function setAuthority($authority) |
public function setAutorite($autorite) |
{ |
$this->user = false; |
$this->pass = false; |
$this->host = false; |
$this->hote = false; |
$this->port = false; |
if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $authority, $reg)) { |
if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $autorite, $reg)) { |
if ($reg[1]) { |
$this->userinfo = $reg[2]; |
$this->infoUtilisateur = $reg[2]; |
} |
|
$this->host = $reg[3]; |
$this->hote = $reg[3]; |
if (isset($reg[5])) { |
$this->port = intval($reg[5]); |
} |
325,50 → 303,50 |
} |
|
/** |
* Returns the path part (possibly an empty string). |
* Renvoie la partie chemin (chemin) (éventuellement vide). |
* |
* @return string |
*/ |
public function getPath() |
public function getChemin() |
{ |
return $this->path; |
return $this->chemin; |
} |
|
/** |
* @param string $path |
* @param string $chemin |
* |
* @return void |
*/ |
public function setPath($path) |
public function setChemin($chemin) |
{ |
$this->path = $path; |
$this->chemin = $chemin; |
} |
|
/** |
* Returns the query string (excluding the leading "?"), or false if "?" |
* isn't present in the URL. |
* renvoie la chaine de requête (requete string) (sans le premier "?"), ou false si "?" |
* n'est pas présent dans l'url. |
* |
* @return string|bool |
* @see self::getQueryVariables() |
* @see self::getVariablesRequete() |
*/ |
public function getQuery() |
public function getRequete() |
{ |
return $this->query; |
return $this->requete; |
} |
|
/** |
* @param string|bool $query |
* @param string|bool $requete |
* |
* @return void |
* @see self::setQueryVariables() |
* @see self::setVariablesRequete() |
*/ |
public function setQuery($query) |
public function setRequete($requete) |
{ |
$this->query = $query; |
$this->requete = $requete; |
} |
|
/** |
* Returns the fragment name, or false if "#" isn't present in the URL. |
* Renvoie le nom du fragment, ou false si "#" n'est pas present dans l'URL. |
* |
* @return string|bool |
*/ |
388,141 → 366,141 |
} |
|
/** |
* Returns the query string like an array as the variables would appear in |
* $_GET in a PHP script. |
* Renvoie la requete string sous forme d'un tableau de variables telles qu'elles apparaitraient |
* dans le $_GET d'un script PHP |
* |
* @return array |
*/ |
public function getQueryVariables() |
public function getVariablesRequete() |
{ |
$pattern = '/[' . |
preg_quote($this->getOption(self::OPTION_SEPARATOR_INPUT), '/') . |
preg_quote($this->getOption(self::OPTION_SEPARATEUR_ENTREE), '/') . |
']/'; |
$parts = preg_split($pattern, $this->query, -1, PREG_SPLIT_NO_EMPTY); |
$return = array(); |
$parties = preg_split($pattern, $this->requete, -1, PREG_SPLIT_NO_EMPTY); |
$retour = array(); |
|
foreach ($parts as $part) { |
if (strpos($part, '=') !== false) { |
list($key, $value) = explode('=', $part, 2); |
foreach ($parties as $partie) { |
if (strpos($partie, '=') !== false) { |
list($cle, $valeur) = explode('=', $partie, 2); |
} else { |
$key = $part; |
$value = null; |
$cle = $partie; |
$valeur = null; |
} |
|
if ($this->getOption(self::OPTION_ENCODE_KEYS)) { |
$key = rawurldecode($key); |
if ($this->getOption(self::OPTION_ENCODER_CLES)) { |
$cle = rawurldecode($cle); |
} |
$value = rawurldecode($value); |
$valeur = rawurldecode($valeur); |
|
if ($this->getOption(self::OPTION_USE_BRACKETS) && |
preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) { |
if ($this->getOption(self::OPTION_UTILISER_CROCHETS) && |
preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $cle, $matches)) { |
|
$key = $matches[1]; |
$cle = $matches[1]; |
$idx = $matches[2]; |
|
// Ensure is an array |
if (empty($return[$key]) || !is_array($return[$key])) { |
$return[$key] = array(); |
// On s'assure que c'est bien un tableau |
if (empty($retour[$cle]) || !is_array($retour[$cle])) { |
$retour[$cle] = array(); |
} |
|
// Add data |
// Ajout des données |
if ($idx === '') { |
$return[$key][] = $value; |
$retour[$cle][] = $valeur; |
} else { |
$return[$key][$idx] = $value; |
$retour[$cle][$idx] = $valeur; |
} |
} elseif (!$this->getOption(self::OPTION_USE_BRACKETS) |
&& !empty($return[$key]) |
} elseif (!$this->getOption(self::OPTION_UTILISER_CROCHETS) |
&& !empty($retour[$cle]) |
) { |
$return[$key] = (array) $return[$key]; |
$return[$key][] = $value; |
$retour[$cle] = (array) $retour[$cle]; |
$retour[$cle][] = $valeur; |
} else { |
$return[$key] = $value; |
$retour[$cle] = $valeur; |
} |
} |
|
return $return; |
return $retour; |
} |
|
/** |
* @param array $array (name => value) array |
* @param array $tableau (nom => valeur) tableau |
* |
* @return void |
*/ |
public function setQueryVariables(array $array) |
public function setVariablesRequete(array $tableau) |
{ |
if (!$array) { |
$this->query = false; |
if (!$tableau) { |
$this->requete = false; |
} else { |
foreach ($array as $name => $value) { |
if ($this->getOption(self::OPTION_ENCODE_KEYS)) { |
$name = rawurlencode($name); |
foreach ($tableau as $nom => $valeur) { |
if ($this->getOption(self::OPTION_ENCODER_CLES)) { |
$nom = rawurlencode($nom); |
} |
|
if (is_array($value)) { |
foreach ($value as $k => $v) { |
$parts[] = $this->getOption(self::OPTION_USE_BRACKETS) |
? sprintf('%s[%s]=%s', $name, $k, $v) |
: ($name . '=' . $v); |
if (is_array($valeur)) { |
foreach ($valeur as $k => $v) { |
$parties[] = $this->getOption(self::OPTION_UTILISER_CROCHETS) |
? sprintf('%s[%s]=%s', $nom, $k, $v) |
: ($nom . '=' . $v); |
} |
} elseif (!is_null($value)) { |
$parts[] = $name . '=' . $value; |
} elseif (!is_null($valeur)) { |
$parties[] = $nom . '=' . $valeur; |
} else { |
$parts[] = $name; |
$parties[] = $nom; |
} |
} |
$this->query = implode($this->getOption(self::OPTION_SEPARATOR_OUTPUT), |
$parts); |
$this->requete = implode($this->getOption(self::OPTION_SEPARATEUR_SORTIE), |
$parties); |
} |
} |
|
/** |
* @param string $name |
* @param mixed $value |
* @param string $nom |
* @param mixed $valeur |
* |
* @return array |
*/ |
public function setQueryVariable($name, $value) |
public function setVariableRequete($nom, $valeur) |
{ |
$array = $this->getQueryVariables(); |
$array[$name] = $value; |
$this->setQueryVariables($array); |
$tableau = $this->getVariablesRequete(); |
$tableau[$nom] = $valeur; |
$this->setVariablesRequete($tableau); |
} |
|
/** |
* @param string $name |
* @param string $nom |
* |
* @return void |
*/ |
public function unsetQueryVariable($name) |
public function unsetVariableRequete($nom) |
{ |
$array = $this->getQueryVariables(); |
unset($array[$name]); |
$this->setQueryVariables($array); |
$tableau = $this->getVariablesRequete(); |
unset($tableau[$nom]); |
$this->setVariablesRequete($tableau); |
} |
|
/** |
* Returns a string representation of this URL. |
* Renvoie un représentation sous forme de chaine de l'URL |
* |
* @return string |
*/ |
public function getURL() |
{ |
// See RFC 3986, section 5.3 |
// Voir RFC 3986, section 5.3 |
$url = ""; |
|
if ($this->scheme !== false) { |
$url .= $this->scheme . ':'; |
if ($this->schema !== false) { |
$url .= $this->schema . ':'; |
} |
|
$authority = $this->getAuthority(); |
if ($authority !== false) { |
$url .= '//' . $authority; |
$autorite = $this->getAutorite(); |
if ($autorite !== false) { |
$url .= '//' . $autorite; |
} |
$url .= $this->path; |
$url .= $this->chemin; |
|
if ($this->query !== false) { |
$url .= '?' . $this->query; |
if ($this->requete !== false) { |
$url .= '?' . $this->requete; |
} |
|
if ($this->fragment !== false) { |
533,215 → 511,215 |
} |
|
/** |
* Returns a normalized string representation of this URL. This is useful |
* for comparison of URLs. |
* Renvoie une représentation de cette URL sous forme de chaine normalisée. Utile pour la |
* comparaison d'URLs |
* |
* @return string |
*/ |
public function getNormalizedURL() |
public function getURLNormalisee() |
{ |
$url = clone $this; |
$url->normalize(); |
$url->normaliser(); |
return $url->getUrl(); |
} |
|
/** |
* Returns a normalized Net_URL2 instance. |
* Renvoie une instance normalisée de Url |
* |
* @return Net_URL2 |
* @return Url |
*/ |
public function normalize() |
public function normaliser() |
{ |
// See RFC 3886, section 6 |
|
// Schemes are case-insensitive |
if ($this->scheme) { |
$this->scheme = strtolower($this->scheme); |
// les cchémas sont insesibles à la casse |
if ($this->schema) { |
$this->schema = strtolower($this->schema); |
} |
|
// Hostnames are case-insensitive |
if ($this->host) { |
$this->host = strtolower($this->host); |
// les noms d'hotes sont insensibles à la casse |
if ($this->hote) { |
$this->hote = strtolower($this->hote); |
} |
|
// Remove default port number for known schemes (RFC 3986, section 6.2.3) |
// Supprimer le numéro de port par défaut pour les schemas connus (RFC 3986, section 6.2.3) |
if ($this->port && |
$this->scheme && |
$this->port == getservbyname($this->scheme, 'tcp')) { |
$this->schema && |
$this->port == getservbyname($this->schema, 'tcp')) { |
|
$this->port = false; |
} |
|
// Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1) |
foreach (array('userinfo', 'host', 'path') as $part) { |
if ($this->$part) { |
$this->$part = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$part); |
// normalisation dans le cas d'un encodage avec %XX pourcentage (RFC 3986, section 6.2.2.1) |
foreach (array('infoUtilisateur', 'hote', 'chemin') as $partie) { |
if ($this->$partie) { |
$this->$partie = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$partie); |
} |
} |
|
// Path segment normalization (RFC 3986, section 6.2.2.3) |
$this->path = self::removeDotSegments($this->path); |
// normalisation des segments du chemin (RFC 3986, section 6.2.2.3) |
$this->chemin = self::supprimerSegmentsAPoints($this->chemin); |
|
// Scheme based normalization (RFC 3986, section 6.2.3) |
if ($this->host && !$this->path) { |
$this->path = '/'; |
// normalisation basée sur le schéma (RFC 3986, section 6.2.3) |
if ($this->hote && !$this->chemin) { |
$this->chemin = '/'; |
} |
} |
|
/** |
* Returns whether this instance represents an absolute URL. |
* Renvoie vrai ou faux suivant que l'instance en cours représente une URL relative ou absolue. |
* |
* @return bool |
*/ |
public function isAbsolute() |
public function etreAbsolue() |
{ |
return (bool) $this->scheme; |
return (bool) $this->schema; |
} |
|
/** |
* Returns an Net_URL2 instance representing an absolute URL relative to |
* this URL. |
* Renvoie une instance de Url représentant une URL absolue relative à |
* cette URL. |
* |
* @param Net_URL2|string $reference relative URL |
* @param Url|string $reference URL relative |
* |
* @return Net_URL2 |
* @return Url |
*/ |
public function resolve($reference) |
public function resoudre($reference) |
{ |
if (is_string($reference)) { |
$reference = new self($reference); |
} |
if (!$this->isAbsolute()) { |
throw new Exception('Base-URL must be absolute'); |
if (!$this->etreAbsolue()) { |
throw new Exception('L\'URL de base doit être absolue !'); |
} |
|
// A non-strict parser may ignore a scheme in the reference if it is |
// identical to the base URI's scheme. |
if (!$this->getOption(self::OPTION_STRICT) && $reference->scheme == $this->scheme) { |
$reference->scheme = false; |
// Un parseur non strict peut choisir d'ignorer un schema dans la référence |
// si celui ci est identique au schéma de base de l'URI. |
if (!$this->getOption(self::OPTION_STRICTE) && $reference->schema == $this->schema) { |
$reference->schema = false; |
} |
|
$target = new self(''); |
if ($reference->scheme !== false) { |
$target->scheme = $reference->scheme; |
$target->setAuthority($reference->getAuthority()); |
$target->path = self::removeDotSegments($reference->path); |
$target->query = $reference->query; |
$cible = new self(''); |
if ($reference->schema !== false) { |
$cible->schema = $reference->schema; |
$cible->setAutorite($reference->getAutorite()); |
$cible->chemin = self::supprimerSegmentsAPoints($reference->chemin); |
$cible->requete = $reference->requete; |
} else { |
$authority = $reference->getAuthority(); |
if ($authority !== false) { |
$target->setAuthority($authority); |
$target->path = self::removeDotSegments($reference->path); |
$target->query = $reference->query; |
$autorite = $reference->getAutorite(); |
if ($autorite !== false) { |
$cible->setAutorite($autorite); |
$cible->chemin = self::supprimerSegmentsAPoints($reference->chemin); |
$cible->requete = $reference->requete; |
} else { |
if ($reference->path == '') { |
$target->path = $this->path; |
if ($reference->query !== false) { |
$target->query = $reference->query; |
if ($reference->chemin == '') { |
$cible->chemin = $this->chemin; |
if ($reference->requete !== false) { |
$cible->requete = $reference->requete; |
} else { |
$target->query = $this->query; |
$cible->requete = $this->requete; |
} |
} else { |
if (substr($reference->path, 0, 1) == '/') { |
$target->path = self::removeDotSegments($reference->path); |
if (substr($reference->chemin, 0, 1) == '/') { |
$cible->chemin = self::supprimerSegmentsAPoints($reference->chemin); |
} else { |
// Merge paths (RFC 3986, section 5.2.3) |
if ($this->host !== false && $this->path == '') { |
$target->path = '/' . $this->path; |
// Concaténation chemins (RFC 3986, section 5.2.3) |
if ($this->hote !== false && $this->chemin == '') { |
$cible->chemin = '/' . $this->chemin; |
} else { |
$i = strrpos($this->path, '/'); |
$i = strrpos($this->chemin, '/'); |
if ($i !== false) { |
$target->path = substr($this->path, 0, $i + 1); |
$cible->chemin = substr($this->chemin, 0, $i + 1); |
} |
$target->path .= $reference->path; |
$cible->chemin .= $reference->chemin; |
} |
$target->path = self::removeDotSegments($target->path); |
$cible->chemin = self::supprimerSegmentsAPoints($cible->chemin); |
} |
$target->query = $reference->query; |
$cible->requete = $reference->requete; |
} |
$target->setAuthority($this->getAuthority()); |
$cible->setAutorite($this->getAutorite()); |
} |
$target->scheme = $this->scheme; |
$cible->schema = $this->schema; |
} |
|
$target->fragment = $reference->fragment; |
$cible->fragment = $reference->fragment; |
|
return $target; |
return $cible; |
} |
|
/** |
* Removes dots as described in RFC 3986, section 5.2.4, e.g. |
* La suppression des segments à points est décrite dans la RFC 3986, section 5.2.4, e.g. |
* "/foo/../bar/baz" => "/bar/baz" |
* |
* @param string $path a path |
* @param string $chemin un chemin |
* |
* @return string a path |
* @return string un chemin |
*/ |
private static function removeDotSegments($path) |
private static function supprimerSegmentsAPoints($chemin) |
{ |
$output = ''; |
$sortie = ''; |
|
// Make sure not to be trapped in an infinite loop due to a bug in this |
// method |
// Assurons de ne pas nous retrouver piégés dans une boucle infinie due à un bug de |
// cette méthode |
$j = 0; |
while ($path && $j++ < 100) { |
// Step A |
if (substr($path, 0, 2) == './') { |
$path = substr($path, 2); |
} elseif (substr($path, 0, 3) == '../') { |
$path = substr($path, 3); |
while ($chemin && $j++ < 100) { |
// Étape A |
if (substr($chemin, 0, 2) == './') { |
$chemin = substr($chemin, 2); |
} elseif (substr($chemin, 0, 3) == '../') { |
$chemin = substr($chemin, 3); |
|
// Step B |
} elseif (substr($path, 0, 3) == '/./' || $path == '/.') { |
$path = '/' . substr($path, 3); |
// Étape B |
} elseif (substr($chemin, 0, 3) == '/./' || $chemin == '/.') { |
$chemin = '/' . substr($chemin, 3); |
|
// Step C |
} elseif (substr($path, 0, 4) == '/../' || $path == '/..') { |
$path = '/' . substr($path, 4); |
$i = strrpos($output, '/'); |
$output = $i === false ? '' : substr($output, 0, $i); |
// Étape C |
} elseif (substr($chemin, 0, 4) == '/../' || $chemin == '/..') { |
$chemin = '/' . substr($chemin, 4); |
$i = strrpos($sortie, '/'); |
$sortie = $i === false ? '' : substr($sortie, 0, $i); |
|
// Step D |
} elseif ($path == '.' || $path == '..') { |
$path = ''; |
// Étape D |
} elseif ($chemin == '.' || $chemin == '..') { |
$chemin = ''; |
|
// Step E |
// Étape E |
} else { |
$i = strpos($path, '/'); |
$i = strpos($chemin, '/'); |
if ($i === 0) { |
$i = strpos($path, '/', 1); |
$i = strpos($chemin, '/', 1); |
} |
if ($i === false) { |
$i = strlen($path); |
$i = strlen($chemin); |
} |
$output .= substr($path, 0, $i); |
$path = substr($path, $i); |
$sortie .= substr($chemin, 0, $i); |
$chemin = substr($chemin, $i); |
} |
} |
|
return $output; |
return $sortie; |
} |
|
/** |
* Returns a Net_URL2 instance representing the canonical URL of the |
* currently executing PHP script. |
* Renvoie une instance de Url representant l'URL canonique du script PHP |
* en cours d'éxécution |
* |
* @return string |
*/ |
public static function getCanonical() |
public static function getCanonique() |
{ |
if (!isset($_SERVER['REQUEST_METHOD'])) { |
// ALERT - no current URL |
throw new Exception('Script was not called through a webserver'); |
// ALERT - pas d'URL en cours |
throw new Exception('Le script n\'a pas été appellé à travers un serveur web'); |
} |
|
// Begin with a relative URL |
// on part d'une URL relative |
$url = new self($_SERVER['PHP_SELF']); |
$url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; |
$url->host = $_SERVER['SERVER_NAME']; |
$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http'; |
$url->hote = $_SERVER['SERVER_NAME']; |
$port = intval($_SERVER['SERVER_PORT']); |
if ($url->scheme == 'http' && $port != 80 || |
$url->scheme == 'https' && $port != 443) { |
if ($url->schema == 'http' && $port != 80 || |
$url->schema == 'https' && $port != 443) { |
|
$url->port = $port; |
} |
749,66 → 727,66 |
} |
|
/** |
* Returns the URL used to retrieve the current request. |
* Renvoie l'URL utilisée pour récupérer la requête en cours |
* |
* @return string |
*/ |
public static function getRequestedURL() |
public static function getURLDemande() |
{ |
return self::getRequested()->getUrl(); |
return self::getDemande()->getUrl(); |
} |
|
/** |
* Returns a Net_URL2 instance representing the URL used to retrieve the |
* current request. |
* Renvoie une instance de Url representant l'URL utilisée pour |
* récupérer la requête en cours |
* |
* @return Net_URL2 |
* @return Url |
*/ |
public static function getRequested() |
public static function getDemande() |
{ |
if (!isset($_SERVER['REQUEST_METHOD'])) { |
// ALERT - no current URL |
throw new Exception('Script was not called through a webserver'); |
// ALERTE - pas d'URL en cours |
throw new Exception('Le script n\'a pas été appellé à travers un serveur web'); |
} |
|
// Begin with a relative URL |
// On part d'une URL relative |
$url = new self($_SERVER['REQUEST_URI']); |
$url->scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; |
// Set host and possibly port |
$url->setAuthority($_SERVER['HTTP_HOST']); |
$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http'; |
// On met à jour les valeurs de l'hote et si possible du port |
$url->setAutorite($_SERVER['HTTP_hote']); |
return $url; |
} |
|
/** |
* Sets the specified option. |
* Met à jour la valeur de l'option spécifiée. |
* |
* @param string $optionName a self::OPTION_ constant |
* @param mixed $value option value |
* @param string $nomOption une des constantes commençant par self::OPTION_ |
* @param mixed $valeur valeur de l'option |
* |
* @return void |
* @see self::OPTION_STRICT |
* @see self::OPTION_USE_BRACKETS |
* @see self::OPTION_ENCODE_KEYS |
* @see self::OPTION_STRICTE |
* @see self::OPTION_UTILISER_CROCHETS |
* @see self::OPTION_ENCODER_CLES |
*/ |
function setOption($optionName, $value) |
function setOption($nomOption, $valeur) |
{ |
if (!array_key_exists($optionName, $this->options)) { |
if (!array_key_exists($nomOption, $this->options)) { |
return false; |
} |
$this->options[$optionName] = $value; |
$this->options[$nomOption] = $valeur; |
} |
|
/** |
* Returns the value of the specified option. |
* Renvoie la valeur de l'option specifiée. |
* |
* @param string $optionName The name of the option to retrieve |
* @param string $nomOption Nom de l'option demandée |
* |
* @return mixed |
*/ |
function getOption($optionName) |
function getOption($nomOption) |
{ |
return isset($this->options[$optionName]) |
? $this->options[$optionName] : false; |
return isset($this->options[$nomOption]) |
? $this->options[$nomOption] : false; |
} |
|
public function __toString() { |