Subversion Repositories Applications.framework

Rev

Rev 274 | Rev 286 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 274 Rev 279
1
<?php
1
<?php
2
// declare(encoding='UTF-8');
2
// declare(encoding='UTF-8');
3
/**
3
/**
4
 * Classe Url, gérant le découpage des paramètres, leurs modification etc...
4
 * Classe Url, gérant le découpage des paramètres, leurs modification etc...
5
 * Traduction et conversion d'une classe (NET_Url2) issue de Pear
5
 * Traduction et conversion d'une classe (NET_Url2) issue de Pear
6
 *
6
 *
7
 * @category	Php 5.2
7
 * @category	Php 5.2
8
 * @package	Framework
8
 * @package	Framework
9
 * @author		Christian SCHMIDT <schmidt@php.net> (Auteur classe originale)
9
 * @author		Christian SCHMIDT <schmidt@php.net> (Auteur classe originale)
10
 * @author		Aurélien PERONNET <aurelien@tela-botanica.org>
10
 * @author		Aurélien PERONNET <aurelien@tela-botanica.org>
11
 * @author		Jean-Pascal MILCENT <jpm@tela-botanica.org>
11
 * @author		Jean-Pascal MILCENT <jpm@tela-botanica.org>
12
 * @copyright	Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
12
 * @copyright	Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
13
 * @license	http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
13
 * @license	http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
14
 * @license	http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
14
 * @license	http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
15
 * @version	SVN: $Id: Url.php 274 2010-12-28 15:37:22Z jpm $
15
 * @version	SVN: $Id: Url.php 279 2010-12-28 16:10:59Z jpm $
16
 * @link		/doc/framework/
16
 * @link		/doc/framework/
17
*/
17
*/
18
class Url {
18
class Url {
19
 
19
 
20
	/**
20
	/**
21
	 * Répresenter les tableaux dans les requêtes en utilisant la notation php []. Par défaut à true.
21
	 * Répresenter les tableaux dans les requêtes en utilisant la notation php []. Par défaut à true.
22
	 */
22
	 */
23
	const OPTION_UTILISER_CROCHETS = 'use_brackets';
23
	const OPTION_UTILISER_CROCHETS = 'use_brackets';
24
 
24
 
25
	/**
25
	/**
26
	 * URL-encoder les clés des variables dans les requêtes. Par défaut à true.
26
	 * URL-encoder les clés des variables dans les requêtes. Par défaut à true.
27
	 */
27
	 */
28
	const OPTION_ENCODER_CLES = 'encode_keys';
28
	const OPTION_ENCODER_CLES = 'encode_keys';
29
 
29
 
30
	/**
30
	/**
31
	 * Séparateurs de variables lors du parsing de la requête. Chaque caractère
31
	 * Séparateurs de variables lors du parsing de la requête. Chaque caractère
32
	 * est considéré comme un séparateur. Par défaut, spécifié par le paramêtre
32
	 * est considéré comme un séparateur. Par défaut, spécifié par le paramêtre
33
	 * arg_separator.input dans php.ini (par défaut "&").
33
	 * arg_separator.input dans php.ini (par défaut "&").
34
	 */
34
	 */
35
	const OPTION_SEPARATEUR_ENTREE = 'input_separator';
35
	const OPTION_SEPARATEUR_ENTREE = 'input_separator';
36
 
36
 
37
	/**
37
	/**
38
	 * Séparateur de variables lors de la génération de la requête. Par défaut, spécifié
38
	 * Séparateur de variables lors de la génération de la requête. Par défaut, spécifié
39
	 * par le paramètre arg_separator.output dans php.ini (par défaut "&").
39
	 * par le paramètre arg_separator.output dans php.ini (par défaut "&").
40
	 */
40
	 */
41
	const OPTION_SEPARATEUR_SORTIE = 'output_separator';
41
	const OPTION_SEPARATEUR_SORTIE = 'output_separator';
42
 
42
 
43
	/**
43
	/**
44
	 * Options par défaut correspondant au comportement de php
44
	 * Options par défaut correspondant au comportement de php
45
	 * vis à vis de $_GET
45
	 * vis à vis de $_GET
46
	 */
46
	 */
47
	private $options = array(
47
	private $options = array(
48
		self::OPTION_UTILISER_CROCHETS => true,
48
		self::OPTION_UTILISER_CROCHETS => true,
49
		self::OPTION_ENCODER_CLES => true,
49
		self::OPTION_ENCODER_CLES => true,
50
		self::OPTION_SEPARATEUR_ENTREE => '&',
50
		self::OPTION_SEPARATEUR_ENTREE => '&',
51
		self::OPTION_SEPARATEUR_SORTIE => '&');
51
		self::OPTION_SEPARATEUR_SORTIE => '&');
52
 
52
 
53
	/**
53
	/**
54
	 * @var  string|bool
54
	 * @var  string|bool
55
	 */
55
	 */
56
	private $schema = false;
56
	private $schema = false;
57
 
57
 
58
	/**
58
	/**
59
	 * @var  string|bool
59
	 * @var  string|bool
60
	 */
60
	 */
61
	private $infoUtilisateur = false;
61
	private $infoUtilisateur = false;
62
 
62
 
63
	/**
63
	/**
64
	 * @var  string|bool
64
	 * @var  string|bool
65
	 */
65
	 */
66
	private $hote = false;
66
	private $hote = false;
67
 
67
 
68
	/**
68
	/**
69
	 * @var  int|bool
69
	 * @var  int|bool
70
	 */
70
	 */
71
	private $port = false;
71
	private $port = false;
72
 
72
 
73
	/**
73
	/**
74
	 * @var  string
74
	 * @var  string
75
	 */
75
	 */
76
	private $chemin = '';
76
	private $chemin = '';
77
 
77
 
78
	/**
78
	/**
79
	 * @var  string|bool
79
	 * @var  string|bool
80
	 */
80
	 */
81
	private $requete = false;
81
	private $requete = false;
82
 
82
 
83
	/**
83
	/**
84
	 * @var  string|bool
84
	 * @var  string|bool
85
	 */
85
	 */
86
	private $fragment = false;
86
	private $fragment = false;
87
 
87
 
88
	/** Tableau des noms des paramètres à définir dans le fichier de config car obligatoirement nécessaire à cette classe.*/
88
	/** Tableau des noms des paramètres à définir dans le fichier de config car obligatoirement nécessaire à cette classe.*/
89
	private $parametres_obligatoires = array('url_arg_separateur_entree', 'url_arg_separateur_sortie');
89
	private $parametres_obligatoires = array('url_arg_separateur_entree', 'url_arg_separateur_sortie');
90
	
90
	
91
	/**
91
	/**
92
	 * @param string $url	 une URL relative ou absolue
92
	 * @param string $url	 une URL relative ou absolue
93
	 * @param array  $options
93
	 * @param array  $options
94
	 */
94
	 */
95
	public function __construct($url, $options = null) {
95
	public function __construct($url, $options = null) {
96
		Config::verifierPresenceParametres($this->parametres_obligatoires);
96
		Config::verifierPresenceParametres($this->parametres_obligatoires);
97
		
97
		
98
		$this->setOption(self::OPTION_SEPARATEUR_ENTREE,
98
		$this->setOption(self::OPTION_SEPARATEUR_ENTREE,
99
						 Config::get('url_arg_separateur_entree'));
99
						 Config::get('url_arg_separateur_entree'));
100
		$this->setOption(self::OPTION_SEPARATEUR_SORTIE,
100
		$this->setOption(self::OPTION_SEPARATEUR_SORTIE,
101
						 Config::get('url_arg_separateur_sortie'));
101
						 Config::get('url_arg_separateur_sortie'));
102
		if (is_array($options)) {
102
		if (is_array($options)) {
103
			foreach ($options as $nomOption => $valeur) {
103
			foreach ($options as $nomOption => $valeur) {
104
				$this->setOption($nomOption);
104
				$this->setOption($nomOption);
105
			}
105
			}
106
		}
106
		}
107
 
107
 
108
		if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) {
108
		if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) {
109
			$this->schema = $reg[1];
109
			$this->schema = $reg[1];
110
			$url = substr($url, strlen($reg[0]));
110
			$url = substr($url, strlen($reg[0]));
111
		}
111
		}
112
 
112
 
113
		if (preg_match('@^//([^/#?]+)@', $url, $reg)) {
113
		if (preg_match('@^//([^/#?]+)@', $url, $reg)) {
114
			$this->setAutorite($reg[1]);
114
			$this->setAutorite($reg[1]);
115
			$url = substr($url, strlen($reg[0]));
115
			$url = substr($url, strlen($reg[0]));
116
		}
116
		}
117
 
117
 
118
		$i = strcspn($url, '?#');
118
		$i = strcspn($url, '?#');
119
		$this->chemin = substr($url, 0, $i);
119
		$this->chemin = substr($url, 0, $i);
120
		$url = substr($url, $i);
120
		$url = substr($url, $i);
121
 
121
 
122
		if (preg_match('@^\?([^#]*)@', $url, $reg)) {
122
		if (preg_match('@^\?([^#]*)@', $url, $reg)) {
123
			$this->requete = $reg[1];
123
			$this->requete = $reg[1];
124
			$url = substr($url, strlen($reg[0]));
124
			$url = substr($url, strlen($reg[0]));
125
		}
125
		}
126
 
126
 
127
		if ($url) {
127
		if ($url) {
128
			$this->fragment = substr($url, 1);
128
			$this->fragment = substr($url, 1);
129
		}
129
		}
130
	}
130
	}
131
	
131
	
132
 
132
 
133
	/**
133
	/**
134
	 * Met à jour la valeur de l'option spécifiée.
134
	 * Met à jour la valeur de l'option spécifiée.
135
	 *
135
	 *
136
	 * @param string $nomOption une des constantes commençant par self::OPTION_
136
	 * @param string $nomOption une des constantes commençant par self::OPTION_
137
	 * @param mixed  $valeur	  valeur de l'option
137
	 * @param mixed  $valeur	  valeur de l'option
138
	 *
138
	 *
139
	 * @return void
139
	 * @return void
140
	 * @see  self::OPTION_STRICTE
140
	 * @see  self::OPTION_STRICTE
141
	 * @see  self::OPTION_UTILISER_CROCHETS
141
	 * @see  self::OPTION_UTILISER_CROCHETS
142
	 * @see  self::OPTION_ENCODER_CLES
142
	 * @see  self::OPTION_ENCODER_CLES
143
	 */
143
	 */
144
	public function setOption($nomOption, $valeur) {
144
	public function setOption($nomOption, $valeur) {
145
		if (!array_key_exists($nomOption, $this->options)) {
145
		if (!array_key_exists($nomOption, $this->options)) {
146
			return false;
146
			return false;
147
		}
147
		}
148
		$this->options[$nomOption] = $valeur;
148
		$this->options[$nomOption] = $valeur;
149
	}
149
	}
150
 
150
 
151
	/**
151
	/**
152
	 * Renvoie la partie autorité, i.e. [ infoUtilisateur "@" ] hote [ ":" port ], ou
152
	 * Renvoie la partie autorité, i.e. [ infoUtilisateur "@" ] hote [ ":" port ], ou
153
	 * false si celle-ci est absente.
153
	 * false si celle-ci est absente.
154
	 *
154
	 *
155
	 * @return string|bool
155
	 * @return string|bool
156
	 */
156
	 */
157
	private function getAutorite() {
157
	private function getAutorite() {
158
		if (!$this->hote) {
158
		if (!$this->hote) {
159
			return false;
159
			return false;
160
		}
160
		}
161
 
161
 
162
		$autorite = '';
162
		$autorite = '';
163
 
163
 
164
		if ($this->infoUtilisateur !== false) {
164
		if ($this->infoUtilisateur !== false) {
165
			$autorite .= $this->infoUtilisateur . '@';
165
			$autorite .= $this->infoUtilisateur . '@';
166
		}
166
		}
167
 
167
 
168
		$autorite .= $this->hote;
168
		$autorite .= $this->hote;
169
 
169
 
170
		if ($this->port !== false) {
170
		if ($this->port !== false) {
171
			$autorite .= ':' . $this->port;
171
			$autorite .= ':' . $this->port;
172
		}
172
		}
173
 
173
 
174
		return $autorite;
174
		return $autorite;
175
	}
175
	}
176
 
176
 
177
	/**
177
	/**
178
	 * @param string|false $autorite
178
	 * @param string|false $autorite
179
	 *
179
	 *
180
	 * @return void
180
	 * @return void
181
	 */
181
	 */
182
	private function setAutorite($autorite) {
182
	private function setAutorite($autorite) {
183
		$this->user = false;
183
		$this->user = false;
184
		$this->pass = false;
184
		$this->pass = false;
185
		$this->hote = false;
185
		$this->hote = false;
186
		$this->port = false;
186
		$this->port = false;
187
		if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $autorite, $reg)) {
187
		if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $autorite, $reg)) {
188
			if ($reg[1]) {
188
			if ($reg[1]) {
189
				$this->infoUtilisateur = $reg[2];
189
				$this->infoUtilisateur = $reg[2];
190
			}
190
			}
191
 
191
 
192
			$this->hote = $reg[3];
192
			$this->hote = $reg[3];
193
			if (isset($reg[5])) {
193
			if (isset($reg[5])) {
194
				$this->port = intval($reg[5]);
194
				$this->port = intval($reg[5]);
195
			}
195
			}
196
		}
196
		}
197
	}
197
	}
198
 
198
 
199
	/**
199
	/**
200
	 * Renvoie vrai ou faux suivant que l'instance en cours représente une URL relative ou absolue.
200
	 * Renvoie vrai ou faux suivant que l'instance en cours représente une URL relative ou absolue.
201
	 *
201
	 *
202
	 * @return  bool
202
	 * @return  bool
203
	 */
203
	 */
204
	private function etreAbsolue() {
204
	private function etreAbsolue() {
205
		return (bool) $this->schema;
205
		return (bool) $this->schema;
206
	}
206
	}
207
	
207
	
208
	/**
208
	/**
209
	 * La suppression des segments à points est décrite dans la RFC 3986, section 5.2.4, e.g.
209
	 * La suppression des segments à points est décrite dans la RFC 3986, section 5.2.4, e.g.
210
	 * "/foo/../bar/baz" => "/bar/baz"
210
	 * "/foo/../bar/baz" => "/bar/baz"
211
	 *
211
	 *
212
	 * @param string $chemin un chemin
212
	 * @param string $chemin un chemin
213
	 *
213
	 *
214
	 * @return string un chemin
214
	 * @return string un chemin
215
	 */
215
	 */
216
	private static function supprimerSegmentsAPoints($chemin) {
216
	private static function supprimerSegmentsAPoints($chemin) {
217
		$sortie = '';
217
		$sortie = '';
218
 
218
 
219
		// Assurons nous de ne pas nous retrouver piégés dans une boucle infinie due à un bug de cette méthode
219
		// Assurons nous de ne pas nous retrouver piégés dans une boucle infinie due à un bug de cette méthode
220
		$j = 0;
220
		$j = 0;
221
		while ($chemin && $j++ < 100) {
221
		while ($chemin && $j++ < 100) {
222
			if (substr($chemin, 0, 2) == './') {// Étape A
222
			if (substr($chemin, 0, 2) == './') {// Étape A
223
				$chemin = substr($chemin, 2);
223
				$chemin = substr($chemin, 2);
224
			} else if (substr($chemin, 0, 3) == '../') {
224
			} else if (substr($chemin, 0, 3) == '../') {
225
				$chemin = substr($chemin, 3);
225
				$chemin = substr($chemin, 3);
226
			} else if (substr($chemin, 0, 3) == '/./' || $chemin == '/.') {// Étape B
226
			} else if (substr($chemin, 0, 3) == '/./' || $chemin == '/.') {// Étape B
227
				$chemin = '/' . substr($chemin, 3);
227
				$chemin = '/' . substr($chemin, 3);
228
			} else if (substr($chemin, 0, 4) == '/../' || $chemin == '/..') {// Étape C
228
			} else if (substr($chemin, 0, 4) == '/../' || $chemin == '/..') {// Étape C
229
				$chemin = '/' . substr($chemin, 4);
229
				$chemin = '/' . substr($chemin, 4);
230
				$i = strrpos($sortie, '/');
230
				$i = strrpos($sortie, '/');
231
				$sortie = $i === false ? '' : substr($sortie, 0, $i);
231
				$sortie = $i === false ? '' : substr($sortie, 0, $i);
232
			} else if ($chemin == '.' || $chemin == '..') {// Étape D
232
			} else if ($chemin == '.' || $chemin == '..') {// Étape D
233
				$chemin = '';
233
				$chemin = '';
234
			} else {// Étape E
234
			} else {// Étape E
235
				$i = strpos($chemin, '/');
235
				$i = strpos($chemin, '/');
236
				if ($i === 0) {
236
				if ($i === 0) {
237
					$i = strpos($chemin, '/', 1);
237
					$i = strpos($chemin, '/', 1);
238
				}
238
				}
239
				if ($i === false) {
239
				if ($i === false) {
240
					$i = strlen($chemin);
240
					$i = strlen($chemin);
241
				}
241
				}
242
				$sortie .= substr($chemin, 0, $i);
242
				$sortie .= substr($chemin, 0, $i);
243
				$chemin = substr($chemin, $i);
243
				$chemin = substr($chemin, $i);
244
			}
244
			}
245
		}
245
		}
246
 
246
 
247
		return $sortie;
247
		return $sortie;
248
	}
248
	}
249
	
249
	
250
	/**
250
	/**
251
	 * (Re-)Création de la partie requête de l'URL à partir des données du tableau (passé en paramètre).
251
	 * (Re-)Création de la partie requête de l'URL à partir des données du tableau (passé en paramètre).
252
	 * 
252
	 * 
253
	 * @param array (nom => valeur) tableau de clés & valeurs pour la partie requête de l'url.
253
	 * @param array (nom => valeur) tableau de clés & valeurs pour la partie requête de l'url.
254
	 * @return void (Re-)Création de la partie requête.
254
	 * @return void (Re-)Création de la partie requête.
255
	 */
255
	 */
256
	public function setRequete(Array $parametres) {
256
	public function setRequete(Array $parametres) {
257
		if (!$parametres) {
257
		if (!$parametres) {
258
			$this->requete = false;
258
			$this->requete = false;
259
		} else {
259
		} else {
260
			foreach ($parametres as $nom => $valeur) {
260
			foreach ($parametres as $nom => $valeur) {
261
				if ($this->getOption(self::OPTION_ENCODER_CLES)) {
261
				if ($this->getOption(self::OPTION_ENCODER_CLES)) {
262
					$nom = rawurlencode($nom);
262
					$nom = rawurlencode($nom);
263
				}
263
				}
264
 
264
 
265
				if (is_array($valeur)) {
265
				if (is_array($valeur)) {
266
					foreach ($valeur as $k => $v) {
266
					foreach ($valeur as $k => $v) {
267
						if ($this->getOption(self::OPTION_UTILISER_CROCHETS)) {
267
						if ($this->getOption(self::OPTION_UTILISER_CROCHETS)) {
268
							$parties[] = sprintf('%s[%s]=%s', $nom, $k, $v);
268
							$parties[] = sprintf('%s[%s]=%s', $nom, $k, $v);
269
						} else {
269
						} else {
270
							$parties[] = $nom.'='.$v;
270
							$parties[] = $nom.'='.$v;
271
						}
271
						}
272
					}
272
					}
273
				} else if (!is_null($valeur)) {
273
				} else if (!is_null($valeur)) {
274
					$parties[] = $nom . '=' . $valeur;
274
					$parties[] = $nom . '=' . $valeur;
275
				} else {
275
				} else {
276
					$parties[] = $nom;
276
					$parties[] = $nom;
277
				}
277
				}
278
			}
278
			}
279
			$this->requete = implode($this->getOption(self::OPTION_SEPARATEUR_SORTIE), $parties);
279
			$this->requete = implode($this->getOption(self::OPTION_SEPARATEUR_SORTIE), $parties);
280
		}
280
		}
281
	}
281
	}
282
	
282
	
283
	/**
283
	/**
284
	 * (Re-)Création de la partie requête de l'URL à partir de la fusion du tableau (passé en paramètre) et 
284
	 * (Re-)Création de la partie requête de l'URL à partir de la fusion du tableau (passé en paramètre) et 
285
	 * les valeurs présentes dans $_GET.
285
	 * les valeurs présentes dans $_GET.
286
	 * 
286
	 * 
287
	 * @param array (nom => valeur) tableau de clés & valeurs pour la partie requête de l'url.
287
	 * @param array (nom => valeur) tableau de clés & valeurs pour la partie requête de l'url.
288
	 * @return void (Re-)Création de la partie requête.
288
	 * @return void (Re-)Création de la partie requête.
289
	 */
289
	 */
290
	public function fusionnerRequete(Array $parametres) {
290
	public function fusionnerRequete(Array $parametres) {
291
		if ($parametres) {
291
		if ($parametres) {
292
			$requete = $parametres + $_GET;
292
			$requete = $parametres + $_GET;
293
			$this->setRequete($requete);
293
			$this->setRequete($requete);
294
		}
294
		}
295
	}
295
	}
296
 
296
 
297
	/**
297
	/**
298
	 * Normalise les données de l'instance d'Url faisant appel à cette méthode.
298
	 * Normalise les données de l'instance d'Url faisant appel à cette méthode.
299
	 *
299
	 *
300
	 * @return  void l'instance d'Url courrante est normalisée.
300
	 * @return  void l'instance d'Url courrante est normalisée.
301
	 */
301
	 */
302
	public function normaliser() {
302
	public function normaliser() {
303
		// Voir RFC 3886, section 6
303
		// Voir RFC 3886, section 6
304
 
304
 
305
		// les cchémas sont insesibles à la casse
305
		// les cchémas sont insesibles à la casse
306
		if ($this->schema) {
306
		if ($this->schema) {
307
			$this->schema = strtolower($this->schema);
307
			$this->schema = strtolower($this->schema);
308
		}
308
		}
309
 
309
 
310
		// les noms d'hotes sont insensibles à la casse
310
		// les noms d'hotes sont insensibles à la casse
311
		if ($this->hote) {
311
		if ($this->hote) {
312
			$this->hote = strtolower($this->hote);
312
			$this->hote = strtolower($this->hote);
313
		}
313
		}
314
 
314
 
315
		// Supprimer le numéro de port par défaut pour les schemas connus (RFC 3986, section 6.2.3)
315
		// Supprimer le numéro de port par défaut pour les schemas connus (RFC 3986, section 6.2.3)
316
		if ($this->port && $this->schema && $this->port == getservbyname($this->schema, 'tcp')) {
316
		if ($this->port && $this->schema && $this->port == getservbyname($this->schema, 'tcp')) {
317
			$this->port = false;
317
			$this->port = false;
318
		}
318
		}
319
 
319
 
320
		// normalisation dans le cas d'un encodage avec %XX pourcentage (RFC 3986, section 6.2.2.1)
320
		// normalisation dans le cas d'un encodage avec %XX pourcentage (RFC 3986, section 6.2.2.1)
321
		foreach (array('infoUtilisateur', 'hote', 'chemin') as $partie) {
321
		foreach (array('infoUtilisateur', 'hote', 'chemin') as $partie) {
322
			if ($this->$partie) {
322
			if ($this->$partie) {
323
				$this->$partie  = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$partie);
323
				$this->$partie  = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$partie);
324
			}
324
			}
325
		}
325
		}
326
 
326
 
327
		// normalisation des segments du chemin (RFC 3986, section 6.2.2.3)
327
		// normalisation des segments du chemin (RFC 3986, section 6.2.2.3)
328
		$this->chemin = self::supprimerSegmentsAPoints($this->chemin);
328
		$this->chemin = self::supprimerSegmentsAPoints($this->chemin);
329
 
329
 
330
		// normalisation basée sur le schéma (RFC 3986, section 6.2.3)
330
		// normalisation basée sur le schéma (RFC 3986, section 6.2.3)
331
		if ($this->hote && !$this->chemin) {
331
		if ($this->hote && !$this->chemin) {
332
			$this->chemin = '/';
332
			$this->chemin = '/';
333
		}
333
		}
334
	}
334
	}
335
 
335
 
336
	/**
336
	/**
337
	 * Renvoie une instance d'objet Url representant l'URL canonique du script PHP en cours d'éxécution.
337
	 * Renvoie une instance d'objet Url representant l'URL canonique du script PHP en cours d'éxécution.
338
	 *
338
	 *
339
	 * @return Url retourne un objet Url ou null en cas d'erreur.
339
	 * @return Url retourne un objet Url ou null en cas d'erreur.
340
	 */
340
	 */
341
	public static function getCanonique() {
341
	public static function getCanonique() {
342
		$url = null;
342
		$url = null;
343
		if (!isset($_SERVER['REQUEST_METHOD'])) {
343
		if (!isset($_SERVER['REQUEST_METHOD'])) {
344
			trigger_error("Le script n'a pas été appellé à travers un serveur web", E_USER_WARNING);
344
			trigger_error("Le script n'a pas été appellé à travers un serveur web", E_USER_WARNING);
345
		} else {
345
		} else {
346
			// À partir d'une URL relative
346
			// À partir d'une URL relative
347
			$url = new self($_SERVER['PHP_SELF']);
347
			$url = new self($_SERVER['PHP_SELF']);
348
			$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http';
348
			$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http';
349
			$url->hote = $_SERVER['SERVER_NAME'];
349
			$url->hote = $_SERVER['SERVER_NAME'];
350
			$port = intval($_SERVER['SERVER_PORT']);
350
			$port = intval($_SERVER['SERVER_PORT']);
351
			if ($url->schema == 'http' && $port != 80 || $url->schema == 'https' && $port != 443) {
351
			if ($url->schema == 'http' && $port != 80 || $url->schema == 'https' && $port != 443) {
352
				$url->port = $port;
352
				$url->port = $port;
353
			}
353
			}
354
		}
354
		}
355
		return $url;
355
		return $url;
356
	}
356
	}
357
 
357
 
358
	/**
358
	/**
359
	 * Renvoie une instance d'objet Url representant l'URL utilisée pour récupérer la requête en cours.
359
	 * Renvoie une instance d'objet Url representant l'URL utilisée pour récupérer la requête en cours.
360
	 *
360
	 *
361
	 * @return Url retourne un objet Url ou null en cas d'erreur.
361
	 * @return Url retourne un objet Url ou null en cas d'erreur.
362
	 */
362
	 */
363
	public static function getDemande() {
363
	public static function getDemande() {
364
		$url = null;
364
		$url = null;
365
		if (!isset($_SERVER['REQUEST_METHOD'])) {
365
		if (!isset($_SERVER['REQUEST_METHOD'])) {
366
			trigger_error("Le script n'a pas été appellé à travers un serveur web", E_USER_WARNING);
366
			trigger_error("Le script n'a pas été appellé à travers un serveur web", E_USER_WARNING);
367
		} else {
367
		} else {
368
			// On part d'une URL relative
368
			// On part d'une URL relative
369
			$url = new self($_SERVER['REQUEST_URI']);
369
			$url = new self($_SERVER['REQUEST_URI']);
370
			$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http';
370
			$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http';
371
			// On met à jour les valeurs de l'hôte et si possible du port
371
			// On met à jour les valeurs de l'hôte et si possible du port
372
			$url->setAutorite($_SERVER['HTTP_hote']);
372
			$url->setAutorite($_SERVER['HTTP_hote']);
373
		}
373
		}
374
		return $url;
374
		return $url;
375
	}
375
	}
376
 
376
 
377
	
377
	
378
	/**
378
	/**
379
	 * Renvoie un représentation sous forme de chaine de l'URL.
379
	 * Renvoie un représentation sous forme de chaine de l'URL.
380
	 *
380
	 *
381
	 * @return  string l'url
381
	 * @return  string l'url
382
	 */
382
	 */
383
	public function getURL() {
383
	public function getURL() {
384
		// Voir RFC 3986, section 5.3
384
		// Voir RFC 3986, section 5.3
385
		$url = "";
385
		$url = '';
386
		
386
		
387
		if ($this->schema !== false) {
387
		if ($this->schema !== false) {
388
			$url .= $this->schema . ':';
388
			$url .= $this->schema . ':';
389
		}
389
		}
390
 
390
 
391
		$autorite = $this->getAutorite();
391
		$autorite = $this->getAutorite();
392
		if ($autorite !== false) {
392
		if ($autorite !== false) {
393
			$url .= '//' . $autorite;
393
			$url .= '//' . $autorite;
394
		}
394
		}
395
		$url .= $this->chemin;
395
		$url .= $this->chemin;
396
 
396
 
397
		if ($this->requete !== false) {
397
		if ($this->requete !== false) {
398
			$url .= '?' . $this->requete;
398
			$url .= '?' . $this->requete;
399
		}
399
		}
400
 
400
 
401
		if ($this->fragment !== false) {
401
		if ($this->fragment !== false) {
402
			$url .= '#' . $this->fragment;
402
			$url .= '#' . $this->fragment;
403
		}
403
		}
404
 
404
 
405
		return $url;
405
		return $url;
406
	}
406
	}
407
}
407
}
408
?>
408
?>