scheme = isset($matches[2]) ? $matches[2] : ''; } if (!empty($matches[3])) { $this->authority = isset($matches[4]) ? $matches[4] : ''; } $this->path = isset($matches[5]) ? $matches[5] : ''; if (!empty($matches[6])) { $this->query = isset($matches[7]) ? $matches[7] : ''; } if (!empty($matches[8])) { $this->fragment = isset($matches[9]) ? $matches[9] : ''; } } } elseif (is_array($uri)) { $this->scheme = isset($uri['scheme']) ? $uri['scheme'] : null; $this->authority = isset($uri['authority']) ? $uri['authority'] : null; $this->path = isset($uri['path']) ? $uri['path'] : null; $this->query = isset($uri['query']) ? $uri['query'] : null; $this->fragment = isset($uri['fragment']) ? $uri['fragment'] : null; } } /** Returns true if this is an absolute (complete) URI * @return boolean */ public function isAbsolute() { return $this->scheme !== null; } /** Returns true if this is an relative (partial) URI * @return boolean */ public function isRelative() { return $this->scheme === null; } /** Returns the scheme of the URI (e.g. http) * @return string */ public function getScheme() { return $this->scheme; } /** Sets the scheme of the URI (e.g. http) * @param string $scheme The new value for the scheme of the URI */ public function setScheme($scheme) { $this->scheme = $scheme; } /** Returns the authority of the URI (e.g. www.example.com:8080) * @return string */ public function getAuthority() { return $this->authority; } /** Sets the authority of the URI (e.g. www.example.com:8080) * @param string $authority The new value for the authority component of the URI */ public function setAuthority($authority) { $this->authority = $authority; } /** Returns the path of the URI (e.g. /foo/bar) * @return string */ public function getPath() { return $this->path; } /** Set the path of the URI (e.g. /foo/bar) * @param string $path The new value for the path component of the URI */ public function setPath($path) { $this->path = $path; } /** Returns the query string part of the URI (e.g. foo=bar) * @return string */ public function getQuery() { return $this->query; } /** Set the query string of the URI (e.g. foo=bar) * @param string $query The new value for the query string component of the URI */ public function setQuery($query) { $this->query = $query; } /** Returns the fragment part of the URI (i.e. after the #) * @return string */ public function getFragment() { return $this->fragment; } /** Set the fragment of the URI (i.e. after the #) * @param string $fragment The new value for the fragment component of the URI */ public function setFragment($fragment) { $this->fragment = $fragment; } /** * Normalises the path of this URI if it has one. Normalising a path means * that any unnecessary '.' and '..' segments are removed. For example, the * URI http://example.com/a/b/../c/./d would be normalised to * http://example.com/a/c/d * * @return object EasyRdf_ParsedUri */ public function normalise() { if (empty($this->path)) { return $this; } // Remove ./ from the start if (substr($this->path, 0, 2) == './') { // Remove both characters $this->path = substr($this->path, 2); } // Remove /. from the end if (substr($this->path, -2) == '/.') { // Remove only the last dot, not the slash! $this->path = substr($this->path, 0, -1); } if (substr($this->path, -3) == '/..') { $this->path .= '/'; } // Split the path into its segments $segments = explode('/', $this->path); $newSegments = array(); // Remove all unnecessary '.' and '..' segments foreach ($segments as $segment) { if ($segment == '..') { // Remove the previous part of the path $count = count($newSegments); if ($count > 0 && $newSegments[$count-1]) { array_pop($newSegments); } } elseif ($segment == '.') { // Ignore continue; } else { array_push($newSegments, $segment); } } // Construct the new normalised path $this->path = implode($newSegments, '/'); // Allow easy chaining of methods return $this; } /** * Resolves a relative URI using this URI as the base URI. */ public function resolve($relUri) { // If it is a string, then convert it to a parsed object if (is_string($relUri)) { $relUri = new EasyRdf_ParsedUri($relUri); } // This code is based on the pseudocode in section 5.2.2 of RFC3986 $target = new EasyRdf_ParsedUri(); if ($relUri->scheme) { $target->scheme = $relUri->scheme; $target->authority = $relUri->authority; $target->path = $relUri->path; $target->query = $relUri->query; } else { if ($relUri->authority) { $target->authority = $relUri->authority; $target->path = $relUri->path; $target->query = $relUri->query; } else { if (empty($relUri->path)) { $target->path = $this->path; if ($relUri->query) { $target->query = $relUri->query; } else { $target->query = $this->query; } } else { if (substr($relUri->path, 0, 1) == '/') { $target->path = $relUri->path; } else { $path = $this->path; $lastSlash = strrpos($path, '/'); if ($lastSlash !== false) { $path = substr($path, 0, $lastSlash + 1); } else { $path = '/'; } $target->path .= $path . $relUri->path; } $target->query = $relUri->query; } $target->authority = $this->authority; } $target->scheme = $this->scheme; } $target->fragment = $relUri->fragment; $target->normalise(); return $target; } /** Convert the parsed URI back into a string * * @return string The URI as a string */ public function toString() { $str = ''; if ($this->scheme !== null) { $str .= $this->scheme . ':'; } if ($this->authority !== null) { $str .= '//' . $this->authority; } $str .= $this->path; if ($this->query !== null) { $str .= '?' . $this->query; } if ($this->fragment !== null) { $str .= '#' . $this->fragment; } return $str; } /** Magic method to convert the URI, when casted, back to a string * * @return string The URI as a string */ public function __toString() { return $this->toString(); } }