Subversion Repositories Applications.framework

Rev

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

Rev 285 Rev 286
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 285 2011-01-03 14:17:18Z gduche $
15
 * @version	SVN: $Id: Url.php 286 2011-01-05 11:37:57Z 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 = 'utiliser_crochets';
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 = 'encoder_cles';
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 = 'separateur_entree';
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 = 'separateur_sortie';
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,
-
 
99
						 Config::get('url_arg_separateur_entree'));
98
		$this->setOption(self::OPTION_SEPARATEUR_ENTREE, Config::get('url_arg_separateur_entree'));
100
		$this->setOption(self::OPTION_SEPARATEUR_SORTIE,
-
 
101
						 Config::get('url_arg_separateur_sortie'));
99
		$this->setOption(self::OPTION_SEPARATEUR_SORTIE, Config::get('url_arg_separateur_sortie'));
102
		if (is_array($options)) {
100
		if (is_array($options)) {
103
			foreach ($options as $nomOption => $valeur) {
101
			foreach ($options as $nomOption => $valeur) {
104
				$this->setOption($nomOption);
102
				$this->setOption($nomOption);
105
			}
103
			}
106
		}
104
		}
107
 
105
 
108
		if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) {
106
		if (preg_match('@^([a-z][a-z0-9.+-]*):@i', $url, $reg)) {
109
			$this->schema = $reg[1];
107
			$this->schema = $reg[1];
110
			$url = substr($url, strlen($reg[0]));
108
			$url = substr($url, strlen($reg[0]));
111
		}
109
		}
112
 
110
 
113
		if (preg_match('@^//([^/#?]+)@', $url, $reg)) {
111
		if (preg_match('@^//([^/#?]+)@', $url, $reg)) {
114
			$this->setAutorite($reg[1]);
112
			$this->setAutorite($reg[1]);
115
			$url = substr($url, strlen($reg[0]));
113
			$url = substr($url, strlen($reg[0]));
116
		}
114
		}
117
 
115
 
118
		$i = strcspn($url, '?#');
116
		$i = strcspn($url, '?#');
119
		$this->chemin = substr($url, 0, $i);
117
		$this->chemin = substr($url, 0, $i);
120
		$url = substr($url, $i);
118
		$url = substr($url, $i);
121
 
119
 
122
		if (preg_match('@^\?([^#]*)@', $url, $reg)) {
120
		if (preg_match('@^\?([^#]*)@', $url, $reg)) {
123
			$this->requete = $reg[1];
121
			$this->requete = $reg[1];
124
			$url = substr($url, strlen($reg[0]));
122
			$url = substr($url, strlen($reg[0]));
125
		}
123
		}
126
 
124
 
127
		if ($url) {
125
		if ($url) {
128
			$this->fragment = substr($url, 1);
126
			$this->fragment = substr($url, 1);
129
		}
127
		}
130
	}
128
	}
-
 
129
	
-
 
130
	/**
-
 
131
	 * Renvoie la valeur de l'option specifiée.
-
 
132
	 *
-
 
133
	 * @param string $nomOption Nom de l'option demandée
-
 
134
	 *
-
 
135
	 * @return  mixed
-
 
136
	 */
-
 
137
	public function getOption($nomOption) {
-
 
138
		return isset($this->options[$nomOption]) ? $this->options[$nomOption] : false;
131
	
139
	}
132
 
140
 
133
	/**
141
	/**
134
	 * Met à jour la valeur de l'option spécifiée.
142
	 * Met à jour la valeur de l'option spécifiée.
135
	 *
143
	 *
136
	 * @param string $nomOption une des constantes commençant par self::OPTION_
144
	 * @param string $nomOption une des constantes commençant par self::OPTION_
137
	 * @param mixed  $valeur	  valeur de l'option
145
	 * @param mixed  $valeur	  valeur de l'option
138
	 *
146
	 *
139
	 * @return void
147
	 * @return void
140
	 * @see  self::OPTION_STRICTE
148
	 * @see  self::OPTION_STRICTE
141
	 * @see  self::OPTION_UTILISER_CROCHETS
149
	 * @see  self::OPTION_UTILISER_CROCHETS
142
	 * @see  self::OPTION_ENCODER_CLES
150
	 * @see  self::OPTION_ENCODER_CLES
143
	 */
151
	 */
144
	public function setOption($nomOption, $valeur) {
152
	public function setOption($nomOption, $valeur) {
145
		if (!array_key_exists($nomOption, $this->options)) {
153
		if (!array_key_exists($nomOption, $this->options)) {
146
			return false;
154
			return false;
147
		}
155
		}
148
		$this->options[$nomOption] = $valeur;
156
		$this->options[$nomOption] = $valeur;
149
	}
157
	}
150
 
158
 
151
	/**
159
	/**
152
	 * Renvoie la partie autorité, i.e. [ infoUtilisateur "@" ] hote [ ":" port ], ou
160
	 * Renvoie la partie autorité, i.e. [ infoUtilisateur "@" ] hote [ ":" port ], ou
153
	 * false si celle-ci est absente.
161
	 * false si celle-ci est absente.
154
	 *
162
	 *
155
	 * @return string|bool
163
	 * @return string|bool
156
	 */
164
	 */
157
	private function getAutorite() {
165
	private function getAutorite() {
158
		if (!$this->hote) {
166
		if (!$this->hote) {
159
			return false;
167
			return false;
160
		}
168
		}
161
 
169
 
162
		$autorite = '';
170
		$autorite = '';
163
 
171
 
164
		if ($this->infoUtilisateur !== false) {
172
		if ($this->infoUtilisateur !== false) {
165
			$autorite .= $this->infoUtilisateur . '@';
173
			$autorite .= $this->infoUtilisateur . '@';
166
		}
174
		}
167
 
175
 
168
		$autorite .= $this->hote;
176
		$autorite .= $this->hote;
169
 
177
 
170
		if ($this->port !== false) {
178
		if ($this->port !== false) {
171
			$autorite .= ':' . $this->port;
179
			$autorite .= ':' . $this->port;
172
		}
180
		}
173
 
181
 
174
		return $autorite;
182
		return $autorite;
175
	}
183
	}
176
 
184
 
177
	/**
185
	/**
178
	 * @param string|false $autorite
186
	 * @param string|false $autorite
179
	 *
187
	 *
180
	 * @return void
188
	 * @return void
181
	 */
189
	 */
182
	private function setAutorite($autorite) {
190
	private function setAutorite($autorite) {
183
		$this->user = false;
191
		$this->user = false;
184
		$this->pass = false;
192
		$this->pass = false;
185
		$this->hote = false;
193
		$this->hote = false;
186
		$this->port = false;
194
		$this->port = false;
187
		if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $autorite, $reg)) {
195
		if (preg_match('@^(([^\@]+)\@)?([^:]+)(:(\d*))?$@', $autorite, $reg)) {
188
			if ($reg[1]) {
196
			if ($reg[1]) {
189
				$this->infoUtilisateur = $reg[2];
197
				$this->infoUtilisateur = $reg[2];
190
			}
198
			}
191
 
199
 
192
			$this->hote = $reg[3];
200
			$this->hote = $reg[3];
193
			if (isset($reg[5])) {
201
			if (isset($reg[5])) {
194
				$this->port = intval($reg[5]);
202
				$this->port = intval($reg[5]);
195
			}
203
			}
196
		}
204
		}
197
	}
205
	}
198
 
206
 
199
	/**
207
	/**
200
	 * Renvoie vrai ou faux suivant que l'instance en cours représente une URL relative ou absolue.
208
	 * Renvoie vrai ou faux suivant que l'instance en cours représente une URL relative ou absolue.
201
	 *
209
	 *
202
	 * @return  bool
210
	 * @return  bool
203
	 */
211
	 */
204
	private function etreAbsolue() {
212
	private function etreAbsolue() {
205
		return (bool) $this->schema;
213
		return (bool) $this->schema;
206
	}
214
	}
207
	
215
	
208
	/**
216
	/**
209
	 * La suppression des segments à points est décrite dans la RFC 3986, section 5.2.4, e.g.
217
	 * La suppression des segments à points est décrite dans la RFC 3986, section 5.2.4, e.g.
210
	 * "/foo/../bar/baz" => "/bar/baz"
218
	 * "/foo/../bar/baz" => "/bar/baz"
211
	 *
219
	 *
212
	 * @param string $chemin un chemin
220
	 * @param string $chemin un chemin
213
	 *
221
	 *
214
	 * @return string un chemin
222
	 * @return string un chemin
215
	 */
223
	 */
216
	private static function supprimerSegmentsAPoints($chemin) {
224
	private static function supprimerSegmentsAPoints($chemin) {
217
		$sortie = '';
225
		$sortie = '';
218
 
226
 
219
		// Assurons nous de ne pas nous retrouver piégés dans une boucle infinie due à un bug de cette méthode
227
		// Assurons nous de ne pas nous retrouver piégés dans une boucle infinie due à un bug de cette méthode
220
		$j = 0;
228
		$j = 0;
221
		while ($chemin && $j++ < 100) {
229
		while ($chemin && $j++ < 100) {
222
			if (substr($chemin, 0, 2) == './') {// Étape A
230
			if (substr($chemin, 0, 2) == './') {// Étape A
223
				$chemin = substr($chemin, 2);
231
				$chemin = substr($chemin, 2);
224
			} else if (substr($chemin, 0, 3) == '../') {
232
			} else if (substr($chemin, 0, 3) == '../') {
225
				$chemin = substr($chemin, 3);
233
				$chemin = substr($chemin, 3);
226
			} else if (substr($chemin, 0, 3) == '/./' || $chemin == '/.') {// Étape B
234
			} else if (substr($chemin, 0, 3) == '/./' || $chemin == '/.') {// Étape B
227
				$chemin = '/' . substr($chemin, 3);
235
				$chemin = '/' . substr($chemin, 3);
228
			} else if (substr($chemin, 0, 4) == '/../' || $chemin == '/..') {// Étape C
236
			} else if (substr($chemin, 0, 4) == '/../' || $chemin == '/..') {// Étape C
229
				$chemin = '/' . substr($chemin, 4);
237
				$chemin = '/' . substr($chemin, 4);
230
				$i = strrpos($sortie, '/');
238
				$i = strrpos($sortie, '/');
231
				$sortie = $i === false ? '' : substr($sortie, 0, $i);
239
				$sortie = $i === false ? '' : substr($sortie, 0, $i);
232
			} else if ($chemin == '.' || $chemin == '..') {// Étape D
240
			} else if ($chemin == '.' || $chemin == '..') {// Étape D
233
				$chemin = '';
241
				$chemin = '';
234
			} else {// Étape E
242
			} else {// Étape E
235
				$i = strpos($chemin, '/');
243
				$i = strpos($chemin, '/');
236
				if ($i === 0) {
244
				if ($i === 0) {
237
					$i = strpos($chemin, '/', 1);
245
					$i = strpos($chemin, '/', 1);
238
				}
246
				}
239
				if ($i === false) {
247
				if ($i === false) {
240
					$i = strlen($chemin);
248
					$i = strlen($chemin);
241
				}
249
				}
242
				$sortie .= substr($chemin, 0, $i);
250
				$sortie .= substr($chemin, 0, $i);
243
				$chemin = substr($chemin, $i);
251
				$chemin = substr($chemin, $i);
244
			}
252
			}
245
		}
253
		}
246
 
254
 
247
		return $sortie;
255
		return $sortie;
248
	}
256
	}
249
	
257
	
250
	/**
258
	/**
251
	 * (Re-)Création de la partie requête de l'URL à partir des données du tableau (passé en paramètre).
259
	 * (Re-)Création de la partie requête de l'URL à partir des données du tableau (passé en paramètre).
252
	 * 
260
	 * 
253
	 * @param array (nom => valeur) tableau de clés & valeurs pour la partie requête de l'url.
261
	 * @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.
262
	 * @return void (Re-)Création de la partie requête.
255
	 */
263
	 */
256
	public function setRequete(Array $parametres) {
264
	public function setRequete(Array $parametres) {
257
		if (!$parametres) {
265
		if (!$parametres) {
258
			$this->requete = false;
266
			$this->requete = false;
259
		} else {
267
		} else {
260
			foreach ($parametres as $nom => $valeur) {
268
			foreach ($parametres as $nom => $valeur) {
261
				if ($this->getOption(self::OPTION_ENCODER_CLES)) {
269
				if ($this->getOption(self::OPTION_ENCODER_CLES)) {
262
					$nom = rawurlencode($nom);
270
					$nom = rawurlencode($nom);
263
				}
271
				}
264
 
272
 
265
				if (is_array($valeur)) {
273
				if (is_array($valeur)) {
266
					foreach ($valeur as $k => $v) {
274
					foreach ($valeur as $k => $v) {
267
						if ($this->getOption(self::OPTION_UTILISER_CROCHETS)) {
275
						if ($this->getOption(self::OPTION_UTILISER_CROCHETS)) {
268
							$parties[] = sprintf('%s[%s]=%s', $nom, $k, $v);
276
							$parties[] = sprintf('%s[%s]=%s', $nom, $k, $v);
269
						} else {
277
						} else {
270
							$parties[] = $nom.'='.$v;
278
							$parties[] = $nom.'='.$v;
271
						}
279
						}
272
					}
280
					}
273
				} else if (!is_null($valeur)) {
281
				} else if (!is_null($valeur)) {
274
					$parties[] = $nom . '=' . $valeur;
282
					$parties[] = $nom . '=' . $valeur;
275
				} else {
283
				} else {
276
					$parties[] = $nom;
284
					$parties[] = $nom;
277
				}
285
				}
278
			}
286
			}
279
			$this->requete = implode($this->getOption(self::OPTION_SEPARATEUR_SORTIE), $parties);
287
			$this->requete = implode($this->getOption(self::OPTION_SEPARATEUR_SORTIE), $parties);
280
		}
288
		}
281
	}
289
	}
282
	
290
	
283
	/**
291
	/**
284
	 * (Re-)Création de la partie requête de l'URL à partir de la fusion du tableau (passé en paramètre) et 
292
	 * (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.
293
	 * les valeurs présentes dans $_GET.
286
	 * 
294
	 * 
287
	 * @param array (nom => valeur) tableau de clés & valeurs pour la partie requête de l'url.
295
	 * @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.
296
	 * @return void (Re-)Création de la partie requête.
289
	 */
297
	 */
290
	public function fusionnerRequete(Array $parametres) {
298
	public function fusionnerRequete(Array $parametres) {
291
		if ($parametres) {
299
		if ($parametres) {
292
			$requete = $parametres + $_GET;
300
			$requete = $parametres + $_GET;
293
			$this->setRequete($requete);
301
			$this->setRequete($requete);
294
		}
302
		}
295
	}
303
	}
296
 
304
 
297
	/**
305
	/**
298
	 * Normalise les données de l'instance d'Url faisant appel à cette méthode.
306
	 * Normalise les données de l'instance d'Url faisant appel à cette méthode.
299
	 *
307
	 *
300
	 * @return  void l'instance d'Url courrante est normalisée.
308
	 * @return  void l'instance d'Url courrante est normalisée.
301
	 */
309
	 */
302
	public function normaliser() {
310
	public function normaliser() {
303
		// Voir RFC 3886, section 6
311
		// Voir RFC 3886, section 6
304
 
312
 
305
		// les cchémas sont insesibles à la casse
313
		// les cchémas sont insesibles à la casse
306
		if ($this->schema) {
314
		if ($this->schema) {
307
			$this->schema = strtolower($this->schema);
315
			$this->schema = strtolower($this->schema);
308
		}
316
		}
309
 
317
 
310
		// les noms d'hotes sont insensibles à la casse
318
		// les noms d'hotes sont insensibles à la casse
311
		if ($this->hote) {
319
		if ($this->hote) {
312
			$this->hote = strtolower($this->hote);
320
			$this->hote = strtolower($this->hote);
313
		}
321
		}
314
 
322
 
315
		// Supprimer le numéro de port par défaut pour les schemas connus (RFC 3986, section 6.2.3)
323
		// 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')) {
324
		if ($this->port && $this->schema && $this->port == getservbyname($this->schema, 'tcp')) {
317
			$this->port = false;
325
			$this->port = false;
318
		}
326
		}
319
 
327
 
320
		// normalisation dans le cas d'un encodage avec %XX pourcentage (RFC 3986, section 6.2.2.1)
328
		// 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) {
329
		foreach (array('infoUtilisateur', 'hote', 'chemin') as $partie) {
322
			if ($this->$partie) {
330
			if ($this->$partie) {
323
				$this->$partie  = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$partie);
331
				$this->$partie  = preg_replace('/%[0-9a-f]{2}/ie', 'strtoupper("\0")', $this->$partie);
324
			}
332
			}
325
		}
333
		}
326
 
334
 
327
		// normalisation des segments du chemin (RFC 3986, section 6.2.2.3)
335
		// normalisation des segments du chemin (RFC 3986, section 6.2.2.3)
328
		$this->chemin = self::supprimerSegmentsAPoints($this->chemin);
336
		$this->chemin = self::supprimerSegmentsAPoints($this->chemin);
329
 
337
 
330
		// normalisation basée sur le schéma (RFC 3986, section 6.2.3)
338
		// normalisation basée sur le schéma (RFC 3986, section 6.2.3)
331
		if ($this->hote && !$this->chemin) {
339
		if ($this->hote && !$this->chemin) {
332
			$this->chemin = '/';
340
			$this->chemin = '/';
333
		}
341
		}
334
	}
342
	}
335
 
343
 
336
	/**
344
	/**
337
	 * Renvoie une instance d'objet Url representant l'URL canonique du script PHP en cours d'éxécution.
345
	 * Renvoie une instance d'objet Url representant l'URL canonique du script PHP en cours d'éxécution.
338
	 *
346
	 *
339
	 * @return Url retourne un objet Url ou null en cas d'erreur.
347
	 * @return Url retourne un objet Url ou null en cas d'erreur.
340
	 */
348
	 */
341
	public static function getCanonique() {
349
	public static function getCanonique() {
342
		$url = null;
350
		$url = null;
343
		if (!isset($_SERVER['REQUEST_METHOD'])) {
351
		if (!isset($_SERVER['REQUEST_METHOD'])) {
344
			trigger_error("Le script n'a pas été appellé à travers un serveur web", E_USER_WARNING);
352
			trigger_error("Le script n'a pas été appellé à travers un serveur web", E_USER_WARNING);
345
		} else {
353
		} else {
346
			// À partir d'une URL relative
354
			// À partir d'une URL relative
347
			$url = new self($_SERVER['PHP_SELF']);
355
			$url = new self($_SERVER['PHP_SELF']);
348
			$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http';
356
			$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http';
349
			$url->hote = $_SERVER['SERVER_NAME'];
357
			$url->hote = $_SERVER['SERVER_NAME'];
350
			$port = intval($_SERVER['SERVER_PORT']);
358
			$port = intval($_SERVER['SERVER_PORT']);
351
			if ($url->schema == 'http' && $port != 80 || $url->schema == 'https' && $port != 443) {
359
			if ($url->schema == 'http' && $port != 80 || $url->schema == 'https' && $port != 443) {
352
				$url->port = $port;
360
				$url->port = $port;
353
			}
361
			}
354
		}
362
		}
355
		return $url;
363
		return $url;
356
	}
364
	}
357
 
365
 
358
	/**
366
	/**
359
	 * Renvoie une instance d'objet Url representant l'URL utilisée pour récupérer la requête en cours.
367
	 * Renvoie une instance d'objet Url representant l'URL utilisée pour récupérer la requête en cours.
360
	 *
368
	 *
361
	 * @return Url retourne un objet Url ou null en cas d'erreur.
369
	 * @return Url retourne un objet Url ou null en cas d'erreur.
362
	 */
370
	 */
363
	public static function getDemande() {
371
	public static function getDemande() {
364
		$url = null;
372
		$url = null;
365
		if (!isset($_SERVER['REQUEST_METHOD'])) {
373
		if (!isset($_SERVER['REQUEST_METHOD'])) {
366
			trigger_error("Le script n'a pas été appellé à travers un serveur web", E_USER_WARNING);
374
			trigger_error("Le script n'a pas été appellé à travers un serveur web", E_USER_WARNING);
367
		} else {
375
		} else {
368
			// On part d'une URL relative
376
			// On part d'une URL relative
369
			$url = new self($_SERVER['REQUEST_URI']);
377
			$url = new self($_SERVER['REQUEST_URI']);
370
			$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http';
378
			$url->schema = isset($_SERVER['HTTPS']) ? 'https' : 'http';
371
			// On met à jour les valeurs de l'hôte et si possible du port
379
			// On met à jour les valeurs de l'hôte et si possible du port
372
			$url->setAutorite($_SERVER['HTTP_hote']);
380
			$url->setAutorite($_SERVER['HTTP_hote']);
373
		}
381
		}
374
		return $url;
382
		return $url;
375
	}
383
	}
376
 
384
 
377
	
385
	
378
	/**
386
	/**
379
	 * Renvoie un représentation sous forme de chaine de l'URL.
387
	 * Renvoie un représentation sous forme de chaine de l'URL.
380
	 *
388
	 *
381
	 * @return  string l'url
389
	 * @return  string l'url
382
	 */
390
	 */
383
	public function getURL() {
391
	public function getURL() {
384
		// Voir RFC 3986, section 5.3
392
		// Voir RFC 3986, section 5.3
385
		$url = '';
393
		$url = '';
386
		
394
		
387
		if ($this->schema !== false) {
395
		if ($this->schema !== false) {
388
			$url .= $this->schema . ':';
396
			$url .= $this->schema . ':';
389
		}
397
		}
390
 
398
 
391
		$autorite = $this->getAutorite();
399
		$autorite = $this->getAutorite();
392
		if ($autorite !== false) {
400
		if ($autorite !== false) {
393
			$url .= '//' . $autorite;
401
			$url .= '//' . $autorite;
394
		}
402
		}
395
		$url .= $this->chemin;
403
		$url .= $this->chemin;
396
 
404
 
397
		if ($this->requete !== false) {
405
		if ($this->requete !== false) {
398
			$url .= '?' . $this->requete;
406
			$url .= '?' . $this->requete;
399
		}
407
		}
400
 
408
 
401
		if ($this->fragment !== false) {
409
		if ($this->fragment !== false) {
402
			$url .= '#' . $this->fragment;
410
			$url .= '#' . $this->fragment;
403
		}
411
		}
404
 
412
 
405
		return $url;
413
		return $url;
406
	}
414
	}
407
	
-
 
408
	/**
-
 
409
	 * Renvoie la valeur de l'option specifiée.
-
 
410
	 *
-
 
411
	 * @param string $nomOption Nom de l'option demandée
-
 
412
	 *
-
 
413
	 * @return  mixed
-
 
414
	 */
-
 
415
	function getOption($nomOption) {
-
 
416
		return isset($this->options[$nomOption])
-
 
417
			? $this->options[$nomOption] : false;
-
 
418
	}
-
 
419
}
415
}
420
?>
416
?>