Packages

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
      • Adapters
      • Extensions
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Diagnostics
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
      • PhpGenerator
  • NetteModule
  • None
  • PHP

Classes

  • NHttpContext
  • NHttpRequest
  • NHttpRequestFactory
  • NHttpResponse
  • NHttpUploadedFile
  • NSession
  • NSessionSection
  • NUrl
  • NUrlScript
  • NUserStorage

Interfaces

  • IHttpRequest
  • IHttpResponse
  • ISessionStorage
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  *
  6:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  * @package Nette\Http
 11:  */
 12: 
 13: 
 14: 
 15: /**
 16:  * URI Syntax (RFC 3986).
 17:  *
 18:  * <pre>
 19:  * scheme  user  password  host  port  basePath   relativeUrl
 20:  *   |      |      |        |      |    |             |
 21:  * /--\   /--\ /------\ /-------\ /--\/--\/----------------------------\
 22:  * http://john:x0y17575@nette.org:8042/en/manual.php?name=param#fragment  <-- absoluteUrl
 23:  *        \__________________________/\____________/^\________/^\______/
 24:  *                     |                     |           |         |
 25:  *                 authority               path        query    fragment
 26:  * </pre>
 27:  *
 28:  * - authority:   [user[:password]@]host[:port]
 29:  * - hostUrl:     http://user:password@nette.org:8042
 30:  * - basePath:    /en/ (everything before relative URI not including the script name)
 31:  * - baseUrl:     http://user:password@nette.org:8042/en/
 32:  * - relativeUrl: manual.php
 33:  *
 34:  * @author     David Grudl
 35:  *
 36:  * @property   string $scheme
 37:  * @property   string $user
 38:  * @property   string $password
 39:  * @property   string $host
 40:  * @property   string $port
 41:  * @property   string $path
 42:  * @property   string $query
 43:  * @property   string $fragment
 44:  * @property-read string $absoluteUrl
 45:  * @property-read string $authority
 46:  * @property-read string $hostUrl
 47:  * @property-read string $basePath
 48:  * @property-read string $baseUrl
 49:  * @property-read string $relativeUrl
 50:  * @package Nette\Http
 51:  */
 52: class NUrl extends NFreezableObject
 53: {
 54:     /** @var array */
 55:     public static $defaultPorts = array(
 56:         'http' => 80,
 57:         'https' => 443,
 58:         'ftp' => 21,
 59:         'news' => 119,
 60:         'nntp' => 119,
 61:     );
 62: 
 63:     /** @var string */
 64:     private $scheme = '';
 65: 
 66:     /** @var string */
 67:     private $user = '';
 68: 
 69:     /** @var string */
 70:     private $pass = '';
 71: 
 72:     /** @var string */
 73:     private $host = '';
 74: 
 75:     /** @var int */
 76:     private $port = NULL;
 77: 
 78:     /** @var string */
 79:     private $path = '';
 80: 
 81:     /** @var string */
 82:     private $query = '';
 83: 
 84:     /** @var string */
 85:     private $fragment = '';
 86: 
 87: 
 88: 
 89:     /**
 90:      * @param  string  URL
 91:      * @throws InvalidArgumentException
 92:      */
 93:     public function __construct($url = NULL)
 94:     {
 95:         if (is_string($url)) {
 96:             $parts = @parse_url($url); // @ - is escalated to exception
 97:             if ($parts === FALSE) {
 98:                 throw new InvalidArgumentException("Malformed or unsupported URI '$url'.");
 99:             }
100: 
101:             foreach ($parts as $key => $val) {
102:                 $this->$key = $val;
103:             }
104: 
105:             if (!$this->port && isset(self::$defaultPorts[$this->scheme])) {
106:                 $this->port = self::$defaultPorts[$this->scheme];
107:             }
108: 
109:             if ($this->path === '' && ($this->scheme === 'http' || $this->scheme === 'https')) {
110:                 $this->path = '/';
111:             }
112: 
113:         } elseif ($url instanceof self) {
114:             foreach ($this as $key => $val) {
115:                 $this->$key = $url->$key;
116:             }
117:         }
118:     }
119: 
120: 
121: 
122:     /**
123:      * Sets the scheme part of URI.
124:      * @param  string
125:      * @return NUrl  provides a fluent interface
126:      */
127:     public function setScheme($value)
128:     {
129:         $this->updating();
130:         $this->scheme = (string) $value;
131:         return $this;
132:     }
133: 
134: 
135: 
136:     /**
137:      * Returns the scheme part of URI.
138:      * @return string
139:      */
140:     public function getScheme()
141:     {
142:         return $this->scheme;
143:     }
144: 
145: 
146: 
147:     /**
148:      * Sets the user name part of URI.
149:      * @param  string
150:      * @return NUrl  provides a fluent interface
151:      */
152:     public function setUser($value)
153:     {
154:         $this->updating();
155:         $this->user = (string) $value;
156:         return $this;
157:     }
158: 
159: 
160: 
161:     /**
162:      * Returns the user name part of URI.
163:      * @return string
164:      */
165:     public function getUser()
166:     {
167:         return $this->user;
168:     }
169: 
170: 
171: 
172:     /**
173:      * Sets the password part of URI.
174:      * @param  string
175:      * @return NUrl  provides a fluent interface
176:      */
177:     public function setPassword($value)
178:     {
179:         $this->updating();
180:         $this->pass = (string) $value;
181:         return $this;
182:     }
183: 
184: 
185: 
186:     /**
187:      * Returns the password part of URI.
188:      * @return string
189:      */
190:     public function getPassword()
191:     {
192:         return $this->pass;
193:     }
194: 
195: 
196: 
197:     /**
198:      * Sets the host part of URI.
199:      * @param  string
200:      * @return NUrl  provides a fluent interface
201:      */
202:     public function setHost($value)
203:     {
204:         $this->updating();
205:         $this->host = (string) $value;
206:         return $this;
207:     }
208: 
209: 
210: 
211:     /**
212:      * Returns the host part of URI.
213:      * @return string
214:      */
215:     public function getHost()
216:     {
217:         return $this->host;
218:     }
219: 
220: 
221: 
222:     /**
223:      * Sets the port part of URI.
224:      * @param  string
225:      * @return NUrl  provides a fluent interface
226:      */
227:     public function setPort($value)
228:     {
229:         $this->updating();
230:         $this->port = (int) $value;
231:         return $this;
232:     }
233: 
234: 
235: 
236:     /**
237:      * Returns the port part of URI.
238:      * @return string
239:      */
240:     public function getPort()
241:     {
242:         return $this->port;
243:     }
244: 
245: 
246: 
247:     /**
248:      * Sets the path part of URI.
249:      * @param  string
250:      * @return NUrl  provides a fluent interface
251:      */
252:     public function setPath($value)
253:     {
254:         $this->updating();
255:         $this->path = (string) $value;
256:         return $this;
257:     }
258: 
259: 
260: 
261:     /**
262:      * Returns the path part of URI.
263:      * @return string
264:      */
265:     public function getPath()
266:     {
267:         return $this->path;
268:     }
269: 
270: 
271: 
272:     /**
273:      * Sets the query part of URI.
274:      * @param  string|array
275:      * @return NUrl  provides a fluent interface
276:      */
277:     public function setQuery($value)
278:     {
279:         $this->updating();
280:         $this->query = (string) (is_array($value) ? http_build_query($value, '', '&') : $value);
281:         return $this;
282:     }
283: 
284: 
285: 
286:     /**
287:      * Appends the query part of URI.
288:      * @param  string|array
289:      * @return void
290:      */
291:     public function appendQuery($value)
292:     {
293:         $this->updating();
294:         $value = (string) (is_array($value) ? http_build_query($value, '', '&') : $value);
295:         $this->query .= ($this->query === '' || $value === '') ? $value : '&' . $value;
296:     }
297: 
298: 
299: 
300:     /**
301:      * Returns the query part of URI.
302:      * @return string
303:      */
304:     public function getQuery()
305:     {
306:         return $this->query;
307:     }
308: 
309: 
310: 
311:     /**
312:      * Sets the fragment part of URI.
313:      * @param  string
314:      * @return NUrl  provides a fluent interface
315:      */
316:     public function setFragment($value)
317:     {
318:         $this->updating();
319:         $this->fragment = (string) $value;
320:         return $this;
321:     }
322: 
323: 
324: 
325:     /**
326:      * Returns the fragment part of URI.
327:      * @return string
328:      */
329:     public function getFragment()
330:     {
331:         return $this->fragment;
332:     }
333: 
334: 
335: 
336:     /**
337:      * Returns the entire URI including query string and fragment.
338:      * @return string
339:      */
340:     public function getAbsoluteUrl()
341:     {
342:         return $this->scheme . '://' . $this->getAuthority() . $this->path
343:             . ($this->query === '' ? '' : '?' . $this->query)
344:             . ($this->fragment === '' ? '' : '#' . $this->fragment);
345:     }
346: 
347: 
348: 
349:     /**
350:      * Returns the [user[:pass]@]host[:port] part of URI.
351:      * @return string
352:      */
353:     public function getAuthority()
354:     {
355:         $authority = $this->host;
356:         if ($this->port && isset(self::$defaultPorts[$this->scheme]) && $this->port !== self::$defaultPorts[$this->scheme]) {
357:             $authority .= ':' . $this->port;
358:         }
359: 
360:         if ($this->user !== '' && $this->scheme !== 'http' && $this->scheme !== 'https') {
361:             $authority = $this->user . ($this->pass === '' ? '' : ':' . $this->pass) . '@' . $authority;
362:         }
363: 
364:         return $authority;
365:     }
366: 
367: 
368: 
369:     /**
370:      * Returns the scheme and authority part of URI.
371:      * @return string
372:      */
373:     public function getHostUrl()
374:     {
375:         return $this->scheme . '://' . $this->getAuthority();
376:     }
377: 
378: 
379: 
380:     /**
381:      * Returns the base-path.
382:      * @return string
383:      */
384:     public function getBasePath()
385:     {
386:         $pos = strrpos($this->path, '/');
387:         return $pos === FALSE ? '' : substr($this->path, 0, $pos + 1);
388:     }
389: 
390: 
391: 
392:     /**
393:      * Returns the base-URI.
394:      * @return string
395:      */
396:     public function getBaseUrl()
397:     {
398:         return $this->scheme . '://' . $this->getAuthority() . $this->getBasePath();
399:     }
400: 
401: 
402: 
403:     /**
404:      * Returns the relative-URI.
405:      * @return string
406:      */
407:     public function getRelativeUrl()
408:     {
409:         return (string) substr($this->getAbsoluteUrl(), strlen($this->getBaseUrl()));
410:     }
411: 
412: 
413: 
414:     /**
415:      * URI comparsion (this object must be in canonical form).
416:      * @param  string
417:      * @return bool
418:      */
419:     public function isEqual($url)
420:     {
421:         // compare host + path
422:         $part = self::unescape(strtok($url, '?#'), '%/');
423:         if (strncmp($part, '//', 2) === 0) { // absolute URI without scheme
424:             if ($part !== '//' . $this->getAuthority() . $this->path) {
425:                 return FALSE;
426:             }
427: 
428:         } elseif (strncmp($part, '/', 1) === 0) { // absolute path
429:             if ($part !== $this->path) {
430:                 return FALSE;
431:             }
432: 
433:         } else {
434:             if ($part !== $this->scheme . '://' . $this->getAuthority() . $this->path) {
435:                 return FALSE;
436:             }
437:         }
438: 
439:         // compare query strings
440:         $part = preg_split('#[&;]#', self::unescape(strtr((string) strtok('?#'), '+', ' '), '%&;=+'));
441:         sort($part);
442:         $query = preg_split('#[&;]#', $this->query);
443:         sort($query);
444:         return $part === $query;
445:     }
446: 
447: 
448: 
449:     /**
450:      * Transform to canonical form.
451:      * @return void
452:      */
453:     public function canonicalize()
454:     {
455:         $this->updating();
456:         $this->path = $this->path === '' ? '/' : self::unescape($this->path, '%/');
457:         $this->host = strtolower(rawurldecode($this->host));
458:         $this->query = self::unescape(strtr($this->query, '+', ' '), '%&;=+');
459:     }
460: 
461: 
462: 
463:     /**
464:      * @return string
465:      */
466:     public function __toString()
467:     {
468:         return $this->getAbsoluteUrl();
469:     }
470: 
471: 
472: 
473:     /**
474:      * Similar to rawurldecode, but preserve reserved chars encoded.
475:      * @param  string to decode
476:      * @param  string reserved characters
477:      * @return string
478:      */
479:     public static function unescape($s, $reserved = '%;/?:@&=+$,')
480:     {
481:         // reserved (@see RFC 2396) = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
482:         // within a path segment, the characters "/", ";", "=", "?" are reserved
483:         // within a query component, the characters ";", "/", "?", ":", "@", "&", "=", "+", ",", "$" are reserved.
484:         preg_match_all('#(?<=%)[a-f0-9][a-f0-9]#i', $s, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
485:         foreach (array_reverse($matches) as $match) {
486:             $ch = chr(hexdec($match[0][0]));
487:             if (strpos($reserved, $ch) === FALSE) {
488:                 $s = substr_replace($s, $ch, $match[0][1] - 1, 3);
489:             }
490:         }
491:         return $s;
492:     }
493: 
494: 
495: 
496:     /** @deprecated */
497:     function getRelativeUri()
498:     {
499:         trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::getRelativeUrl() instead.', E_USER_WARNING);
500:         return $this->getRelativeUrl();
501:     }
502: 
503:     /** @deprecated */
504:     function getAbsoluteUri()
505:     {
506:         trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::getAbsoluteUrl() instead.', E_USER_WARNING);
507:         return $this->getAbsoluteUrl();
508:     }
509: 
510:     /** @deprecated */
511:     function getHostUri()
512:     {
513:         trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::getHostUrl() instead.', E_USER_WARNING);
514:         return $this->getHostUrl();
515:     }
516: 
517:     /** @deprecated */
518:     function getBaseUri()
519:     {
520:         trigger_error(__METHOD__ . '() is deprecated; use ' . __CLASS__ . '::getBaseUrl() instead.', E_USER_WARNING);
521:         return $this->getBaseUrl();
522:     }
523: 
524: }
525: 
Nette Framework 2.0.6 (for PHP 5.2, prefixed) API API documentation generated by ApiGen 2.7.0