@ 2013-09-13T13:04:22Z <?php
class URI implements \ArrayAccess, \Iterator, \Countable, \JsonSerializable
{
const SCHEME = 0x01;
const USER = 0x02;
const PASS = 0x04;
const HOST = 0x08;
const PORT = 0x10;
const PATH = 0x20;
const QUERY = 0x40;
const FRAGMENT = 0x80;
// The private props and magic methods are only implemented like this to give type validation,
// these are effectively public properties
private $scheme;
private $user;
private $pass;
private $host;
private $port;
private $path;
private $query;
private $fragment;
// obviously these two properties would be handled internally in a native impl
private static $constPropMap = [
self::SCHEME => 'scheme',
self::USER => 'user',
self::PASS => 'pass',
self::HOST => 'host',
self::PORT => 'port',
self::PATH => 'path',
self::QUERY => 'query',
self::FRAGMENT => 'fragment',
];
private $iterationPointer = self::SCHEME;
private function validateScheme($value)
{
// in the generic URI syntax, only the format of the scheme is rigid
return (bool) preg_match('/^[a-z][a-z0-9+.\-]*$/i', $value);
}
public function __construct($uri)
{
$parts = [];
$this->query = new QueryLevel;
if (((string) $uri) !== '' && false === $parts = parse_url($uri)) {
throw new \InvalidArgumentException('Invalid URI');
}
foreach ($parts as $name => $value) {
$this->__set($name, urldecode($value));
}
}
public function __get($name)
{
if (!in_array($name, self::$constPropMap)) {
trigger_error('Undefined property: ' . __CLASS__ . '::$' . $name, E_USER_NOTICE);
return null;
}
return $this->$name;
}
public function __set($name, $value)
{
if ($value === null) {
$this->$name = null;
} else if ($name === 'port') {
$this->port = (int) $value;
} else if ($name === 'query') {
parse_str($value, $query);
$this->query = new QueryLevel($query);
} else if (in_array($name, self::$constPropMap)) {
if ($name === 'scheme' && !$this->validateScheme($value)) {
throw new \InvalidArgumentException('Invalid URI scheme');
}
$this->$name = (string) $value;
} else {
// because PHP allows expando properties on anything afaik :-(
$this->$name = $value;
}
}
public function __toString()
{
$result = '';
if (isset($this->scheme)) {
$result = $this->scheme . ':';
}
if (isset($this->host)) {
$result .= '//';
if (isset($this->user)) {
$result .= urlencode($this->user);
if (isset($this->pass)) {
$result .= ':' . urlencode($this->pass);
}
$result .= '@';
}
$result .= urlencode($this->host);
if (isset($this->port)) {
$result .= ':' . $this->port;
}
}
if (isset($this->path)) {
$result .= $this->path;
}
if (!empty($this->query)) {
$result .= '?' . $this->query;
}
if (isset($this->fragment)) {
$result .= '#' . urlencode($this->fragment);
}
return $result;
}
/* ArrayAccess */
public function offsetExists($name)
{
return isset($this->$name) || isset(self::$constPropMap[$name]);
}
public function offsetGet($name)
{
if (isset(self::$constPropMap[$name])) {
return $this->__get(self::$constPropMap[$name]);
} else {
return $this->__get($name);
}
}
public function offsetSet($name, $value)
{
if (isset(self::$constPropMap[$name])) {
$this->__set(self::$constPropMap[$name], $value);
} else {
$this->__set($name, $value);
}
}
public function offsetUnset($name)
{
if (isset(self::$constPropMap[$name])) {
$this->__set(self::$constPropMap[$name], null);
} else if (in_array($name, self::$constPropMap)) {
$this->__set($name, null);
} else {
unset($this->$name);
}
}
/* Iterator */
public function current()
{
return $this->{self::$constPropMap[$this->iterationPointer]};
}
public function key()
{
return self::$constPropMap[$this->iterationPointer];
}
public function next()
{
$this->iterationPointer *= 2;
}
public function rewind()
{
$this->iterationPointer = self::SCHEME;
}
public function valid()
{
return $this->iterationPointer <= self::FRAGMENT;
}
/* Countable */
public function count()
{
$result = 0;
foreach (self::$constPropMap as $const => $name) {
if ($this->$name !== null) {
$result++;
}
}
return $result;
}
/* JsonSerializable */
public function jsonSerialize()
{
return $this->__toString();
}
}
class QueryLevel implements \ArrayAccess, \Iterator, \Countable
{
private $elements = [];
private $iterationValid;
private function encodeElement($name, $value, $nameFormat = '%s')
{
$result = null;
if ($value !== null) {
$name = sprintf($nameFormat, $name);
if ($value instanceof QueryLevel) {
$result = [];
foreach ($value as $subName => $subValue) {
$result[] = $this->encodeElement($subName, $subValue, $name . '[%s]');
}
$result = implode('&', $result);
} else {
if (is_bool($value)) {
$value = (int) $value;
}
$result = urlencode($name) . '=' . urlencode($value);
}
}
return $result;
}
public function __construct($elements = [])
{
if (!is_array($elements) && !($elements instanceof QueryLevel)) {
if (is_object($elements)) {
$elements = get_object_vars($elements);
} else {
$elements = (array) $elements;
}
}
foreach ($elements as $name => $value) {
$this->__set($name, $value);
}
}
public function __get($name)
{
if (!array_key_exists($name, $this->elements)) {
trigger_error('Undefined property: ' . __CLASS__ . '::$' . $name, E_USER_NOTICE);
return null;
}
return $this->elements[$name];
}
public function __set($name, $value)
{
if (is_scalar($value) || $value === null) {
$this->elements[$name] = $value;
} else {
$this->elements[$name] = new static($value);
}
}
public function __toString()
{
$result = [];
foreach ($this->elements as $name => $value) {
if (!is_numeric($name) && null !== $encoded = $this->encodeElement($name, $value)) {
$result[] = $encoded;
}
}
return implode('&', $result);
}
/* ArrayAccess */
public function offsetExists($name)
{
return isset($this->elements[$name]);
}
public function offsetGet($name)
{
return $this->__get($name);
}
public function offsetSet($name, $value)
{
$this->__set($name, $value);
}
public function offsetUnset($name)
{
unset($this->elements[$name]);
}
/* Iterator */
public function current()
{
return current($this->elements);
}
public function key()
{
return key($this->elements);
}
public function next()
{
next($this->elements);
}
public function rewind()
{
reset($this->elements);
}
public function valid()
{
return key($this->elements) !== false;
}
/* Countable */
public function count()
{
return count($this->elements);
}
}
$uri = new URI('http://www.google.com/');
$uri['query']['foo'] = [1,2,3,4,5];
echo $uri;
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).
Version System time (s) User time (s) Memory (MiB) 8.3.6 0.050 0.616 77.60 8.3.5 0.110 0.652 77.25 8.3.4 0.043 0.305 47.72 8.3.3 0.040 0.315 47.82 8.3.2 0.030 0.135 48.89 8.3.1 0.013 0.148 49.38 8.3.0 0.017 0.154 49.61 8.2.18 0.099 0.574 77.61 8.2.17 0.043 0.289 47.71 8.2.16 0.013 0.308 48.03 8.2.15 0.023 0.159 47.56 8.2.14 0.030 0.154 47.50 8.2.13 0.024 0.161 48.93 8.2.12 0.017 0.163 46.78 8.2.11 0.020 0.247 49.25 8.2.10 0.040 0.239 46.44 8.2.9 0.010 0.262 47.86 8.2.8 0.020 0.247 46.34 8.2.7 0.023 0.257 46.45 8.2.6 0.007 0.276 46.52 8.2.5 0.017 0.249 46.33 8.2.4 0.016 0.240 46.61 8.2.3 0.030 0.251 46.61 8.2.2 0.003 0.267 46.36 8.2.1 0.010 0.256 46.43 8.2.0 0.013 0.258 46.38 8.1.28 0.054 0.325 56.63 8.1.27 0.020 0.089 42.57 8.1.26 0.020 0.098 39.48 8.1.25 0.023 0.100 42.48 8.1.24 0.010 0.144 38.81 8.1.23 0.023 0.126 39.42 8.1.22 0.000 0.160 37.86 8.1.21 0.013 0.146 37.68 8.1.20 0.030 0.144 37.55 8.1.19 0.013 0.141 37.71 8.1.18 0.010 0.151 37.43 8.1.17 0.010 0.160 38.67 8.1.16 0.020 0.130 42.01 8.1.15 0.013 0.146 38.67 8.1.14 0.007 0.156 37.47 8.1.13 0.013 0.140 37.73 8.1.12 0.016 0.142 37.58 8.1.11 0.013 0.150 37.47 8.1.10 0.016 0.145 37.55 8.1.9 0.020 0.145 37.57 8.1.8 0.010 0.143 37.63 8.1.7 0.013 0.149 37.53 8.1.6 0.010 0.157 37.66 8.1.5 0.020 0.140 37.69 8.1.4 0.013 0.146 37.52 8.1.3 0.023 0.137 37.59 8.1.2 0.013 0.143 37.73 8.1.1 0.036 0.301 57.75 8.1.0 0.007 0.298 57.75 8.0.30 0.013 0.289 57.23 8.0.29 0.010 0.315 57.08 8.0.28 0.027 0.301 58.39 8.0.27 0.013 0.317 57.11 8.0.26 0.023 0.357 56.77 8.0.25 0.013 0.310 57.00 8.0.24 0.027 0.304 56.92 8.0.23 0.033 0.306 56.99 8.0.22 0.027 0.292 56.92 8.0.21 0.020 0.318 56.91 8.0.20 0.020 0.307 57.06 8.0.19 0.023 0.303 56.95 8.0.18 0.037 0.297 56.88 8.0.17 0.027 0.313 56.96 8.0.16 0.017 0.300 56.91 8.0.15 0.023 0.299 56.86 8.0.14 0.027 0.301 56.82 8.0.13 0.037 0.622 93.62 8.0.12 0.030 0.316 56.96 8.0.11 0.027 0.301 56.88 8.0.10 0.020 0.301 56.77 8.0.9 0.017 0.313 57.02 8.0.8 0.049 0.492 56.85 8.0.7 0.010 0.329 56.86 8.0.6 0.020 0.292 56.79 8.0.5 0.013 0.301 56.88 8.0.3 0.071 0.638 57.01 8.0.2 0.067 0.512 56.95 8.0.1 0.023 0.292 56.85 8.0.0 0.068 0.530 56.88 7.4.33 0.023 0.292 53.73 7.4.32 0.033 0.286 56.69 7.4.30 0.026 0.294 56.62 7.4.29 0.040 0.364 56.61 7.4.28 0.027 0.295 56.62 7.4.27 0.027 0.306 56.62 7.4.26 0.027 0.306 56.64 7.4.25 0.020 0.299 56.52 7.4.24 0.023 0.295 56.58 7.4.23 0.010 0.319 56.52 7.4.22 0.059 0.543 56.50 7.4.21 0.044 0.446 56.72 7.4.20 0.017 0.303 56.60 7.4.19 0.017 0.315 56.79 7.4.16 0.056 0.451 56.63 7.4.15 0.033 0.606 56.64 7.4.14 0.072 0.615 56.56 7.4.13 0.072 0.565 56.50 7.4.12 0.062 0.524 56.64 7.4.11 0.067 0.561 56.49 7.4.10 0.076 0.651 56.36 7.4.9 0.076 0.470 56.64 7.4.8 0.065 0.503 56.67 7.4.7 0.059 0.505 56.72 7.4.6 0.070 0.515 56.63 7.4.5 0.014 0.259 56.65 7.4.4 0.017 0.468 56.22 7.4.3 0.073 0.577 56.63 7.4.0 0.027 0.524 54.88 7.3.33 0.054 0.553 93.73 7.3.32 0.043 0.584 93.58 7.3.31 0.017 0.292 56.34 7.3.30 0.023 0.291 56.38 7.3.29 0.056 0.457 56.34 7.3.28 0.062 0.549 56.38 7.3.27 0.060 0.487 56.62 7.3.26 0.092 0.616 56.31 7.3.25 0.068 0.492 56.54 7.3.24 0.079 0.691 56.63 7.3.23 0.040 0.490 56.25 7.3.21 0.064 0.533 56.41 7.3.20 0.092 0.599 56.41 7.3.19 0.073 0.508 56.39 7.3.18 0.072 0.482 56.39 7.3.17 0.077 0.731 56.54 7.3.16 0.063 0.496 56.33 7.3.12 0.022 0.485 54.62 7.3.11 0.040 0.696 55.15 7.3.10 0.026 0.570 54.83 7.3.9 0.020 0.569 54.75 7.3.8 0.013 0.465 54.81 7.3.7 0.040 0.669 55.05 7.3.6 0.030 0.596 55.01 7.3.5 0.033 0.660 54.82 7.3.4 0.023 0.476 55.05 7.3.3 0.017 0.438 54.64 7.3.2 0.017 0.423 56.87 7.3.1 0.045 0.472 56.90 7.3.0 0.046 0.436 56.76 7.2.33 0.053 0.550 53.06 7.2.32 0.141 1.053 52.95 7.2.31 0.059 0.549 53.04 7.2.30 0.046 0.578 53.07 7.2.29 0.062 0.886 53.14 7.2.25 0.033 0.748 51.36 7.2.24 0.037 0.767 51.44 7.2.23 0.027 0.658 51.60 7.2.22 0.040 0.709 51.39 7.2.21 0.040 0.686 51.39 7.2.20 0.043 0.670 51.61 7.2.19 0.037 0.674 51.17 7.2.18 0.020 0.552 51.11 7.2.17 0.037 0.731 51.35 7.2.13 0.106 0.498 52.87 7.2.12 0.090 0.490 52.61 7.2.11 0.132 0.475 53.01 7.2.10 0.133 0.507 52.89 7.2.9 0.121 0.500 53.03 7.2.8 0.119 0.495 52.93 7.2.7 0.117 0.524 52.59 7.2.6 0.129 0.474 52.85 7.2.5 0.129 0.507 52.88 7.2.4 0.145 0.500 53.11 7.2.3 0.118 0.487 52.61 7.2.2 0.140 0.496 52.82 7.2.1 0.094 0.479 52.89 7.2.0 0.365 0.440 53.60 7.1.33 0.013 0.795 51.78 7.1.32 0.017 0.760 52.11 7.1.31 0.013 0.949 51.79 7.1.30 0.010 0.907 52.00 7.1.29 0.010 0.841 51.66 7.1.28 0.010 0.933 52.07 7.1.27 0.013 0.848 52.14 7.1.26 0.013 0.777 52.03 7.1.25 0.117 0.733 51.62 7.1.10 0.155 0.175 42.18 7.1.7 0.003 0.348 53.14 7.1.6 0.003 0.389 53.64 7.1.5 0.010 0.367 53.09 7.0.20 0.007 0.433 52.70
preferences:dark mode live preview
34.85 ms | 401 KiB | 5 Q