Subversion Repositories Applications.framework

Rev

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

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