ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
URL.php
Go to the documentation of this file.
1 <?php
2 // +-----------------------------------------------------------------------+
3 // | Copyright (c) 2002-2004, Richard Heyes |
4 // | All rights reserved. |
5 // | |
6 // | Redistribution and use in source and binary forms, with or without |
7 // | modification, are permitted provided that the following conditions |
8 // | are met: |
9 // | |
10 // | o Redistributions of source code must retain the above copyright |
11 // | notice, this list of conditions and the following disclaimer. |
12 // | o Redistributions in binary form must reproduce the above copyright |
13 // | notice, this list of conditions and the following disclaimer in the |
14 // | documentation and/or other materials provided with the distribution.|
15 // | o The names of the authors may not be used to endorse or promote |
16 // | products derived from this software without specific prior written |
17 // | permission. |
18 // | |
19 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
20 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
21 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
22 // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
23 // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
24 // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
25 // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 // | |
31 // +-----------------------------------------------------------------------+
32 // | Author: Richard Heyes <richard at php net> |
33 // +-----------------------------------------------------------------------+
34 //
35 // $Id: URL.php,v 1.49 2007/06/28 14:43:07 davidc Exp $
36 //
37 // Net_URL Class
38 
39 
40 class Net_URL
41 {
42  var $options = array('encode_query_keys' => false);
47  var $url;
48 
53  var $protocol;
54 
59  var $username;
60 
65  var $password;
66 
71  var $host;
72 
77  var $port;
78 
83  var $path;
84 
90 
95  var $anchor;
96 
102 
108  function Net_URL($url = null, $useBrackets = true)
109  {
110  $this->__construct($url, $useBrackets);
111  }
112 
124  function __construct($url = null, $useBrackets = true)
125  {
126  $this->url = $url;
127  $this->useBrackets = $useBrackets;
128 
129  $this->initialize();
130  }
131 
132  function initialize()
133  {
134  $HTTP_SERVER_VARS = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS'];
135 
136  $this->user = '';
137  $this->pass = '';
138  $this->host = '';
139  $this->port = 80;
140  $this->path = '';
141  $this->querystring = array();
142  $this->anchor = '';
143 
144  // Only use defaults if not an absolute URL given
145  if (!preg_match('/^[a-z0-9]+:\/\//i', $this->url)) {
146  $this->protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http');
147 
151  if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) &&
152  preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches))
153  {
154  $host = $matches[1];
155  if (!empty($matches[3])) {
156  $port = $matches[3];
157  } else {
158  $port = $this->getStandardPort($this->protocol);
159  }
160  }
161 
162  $this->user = '';
163  $this->pass = '';
164  $this->host = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost');
165  $this->port = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol));
166  $this->path = !empty($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : '/';
167  $this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null;
168  $this->anchor = '';
169  }
170 
171  // Parse the url and store the various parts
172  if (!empty($this->url)) {
173  $urlinfo = parse_url($this->url);
174 
175  // Default querystring
176  $this->querystring = array();
177 
178  foreach ($urlinfo as $key => $value) {
179  switch ($key) {
180  case 'scheme':
181  $this->protocol = $value;
182  $this->port = $this->getStandardPort($value);
183  break;
184 
185  case 'user':
186  case 'pass':
187  case 'host':
188  case 'port':
189  $this->$key = $value;
190  break;
191 
192  case 'path':
193  if ($value{0} == '/') {
194  $this->path = $value;
195  } else {
196  $path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path);
197  $this->path = sprintf('%s/%s', $path, $value);
198  }
199  break;
200 
201  case 'query':
202  $this->querystring = $this->_parseRawQueryString($value);
203  break;
204 
205  case 'fragment':
206  $this->anchor = $value;
207  break;
208  }
209  }
210  }
211  }
218  function getURL()
219  {
220  $querystring = $this->getQueryString();
221 
222  $this->url = $this->protocol . '://'
223  . $this->user . (!empty($this->pass) ? ':' : '')
224  . $this->pass . (!empty($this->user) ? '@' : '')
225  . $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port)
226  . $this->path
227  . (!empty($querystring) ? '?' . $querystring : '')
228  . (!empty($this->anchor) ? '#' . $this->anchor : '');
229 
230  return $this->url;
231  }
232 
245  function addQueryString($name, $value, $preencoded = false)
246  {
247  if ($this->getOption('encode_query_keys')) {
248  $name = rawurlencode($name);
249  }
250 
251  if ($preencoded) {
252  $this->querystring[$name] = $value;
253  } else {
254  $this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value);
255  }
256  }
257 
264  function removeQueryString($name)
265  {
266  if ($this->getOption('encode_query_keys')) {
267  $name = rawurlencode($name);
268  }
269 
270  if (isset($this->querystring[$name])) {
271  unset($this->querystring[$name]);
272  }
273  }
274 
282  {
283  $this->querystring = $this->_parseRawQueryString($querystring);
284  }
285 
292  function getQueryString()
293  {
294  if (!empty($this->querystring)) {
295  foreach ($this->querystring as $name => $value) {
296  // Encode var name
297  $name = rawurlencode($name);
298 
299  if (is_array($value)) {
300  foreach ($value as $k => $v) {
301  $querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v);
302  }
303  } elseif (!is_null($value)) {
304  $querystring[] = $name . '=' . $value;
305  } else {
306  $querystring[] = $name;
307  }
308  }
309  $querystring = implode(ini_get('arg_separator.output'), $querystring);
310  } else {
311  $querystring = '';
312  }
313 
314  return $querystring;
315  }
316 
325  {
326  $parts = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY);
327  $return = array();
328 
329  foreach ($parts as $part) {
330  if (strpos($part, '=') !== false) {
331  $value = substr($part, strpos($part, '=') + 1);
332  $key = substr($part, 0, strpos($part, '='));
333  } else {
334  $value = null;
335  $key = $part;
336  }
337 
338  if (!$this->getOption('encode_query_keys')) {
339  $key = rawurldecode($key);
340  }
341 
342  if (preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) {
343  $key = $matches[1];
344  $idx = $matches[2];
345 
346  // Ensure is an array
347  if (empty($return[$key]) || !is_array($return[$key])) {
348  $return[$key] = array();
349  }
350 
351  // Add data
352  if ($idx === '') {
353  $return[$key][] = $value;
354  } else {
355  $return[$key][$idx] = $value;
356  }
357  } elseif (!$this->useBrackets AND !empty($return[$key])) {
358  $return[$key] = (array)$return[$key];
359  $return[$key][] = $value;
360  } else {
361  $return[$key] = $value;
362  }
363  }
364 
365  return $return;
366  }
367 
381  function resolvePath($path)
382  {
383  $path = explode('/', str_replace('//', '/', $path));
384 
385  for ($i=0; $i<count($path); $i++) {
386  if ($path[$i] == '.') {
387  unset($path[$i]);
388  $path = array_values($path);
389  $i--;
390 
391  } elseif ($path[$i] == '..' AND ($i > 1 OR ($i == 1 AND $path[0] != '') ) ) {
392  unset($path[$i]);
393  unset($path[$i-1]);
394  $path = array_values($path);
395  $i -= 2;
396 
397  } elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') {
398  unset($path[$i]);
399  $path = array_values($path);
400  $i--;
401 
402  } else {
403  continue;
404  }
405  }
406 
407  return implode('/', $path);
408  }
409 
418  function getStandardPort($scheme)
419  {
420  switch (strtolower($scheme)) {
421  case 'http': return 80;
422  case 'https': return 443;
423  case 'ftp': return 21;
424  case 'imap': return 143;
425  case 'imaps': return 993;
426  case 'pop3': return 110;
427  case 'pop3s': return 995;
428  default: return null;
429  }
430  }
431 
438  function setProtocol($protocol, $port = null)
439  {
440  $this->protocol = $protocol;
441  $this->port = is_null($port) ? $this->getStandardPort($protocol) : $port;
442  }
443 
454  function setOption($optionName, $value)
455  {
456  if (!array_key_exists($optionName, $this->options)) {
457  return false;
458  }
459 
460  $this->options[$optionName] = $value;
461  $this->initialize();
462  }
463 
475  function getOption($optionName)
476  {
477  if (!isset($this->options[$optionName])) {
478  return false;
479  }
480 
481  return $this->options[$optionName];
482  }
483 
484 }
485 ?>