uiharu/lib/uri.php

183 lines
4.9 KiB
PHP

<?php
class Uri implements JsonSerializable {
private $scheme = '';
private $user = '';
private $password = '';
private $host = '';
private $port = null;
private $path = '';
private $query = '';
private $fragment = '';
private $originalString = '';
public function __construct(string $uriString = '') {
$this->originalString = $uriString;
if(!empty($uriString)) {
$uri = parse_url($uriString);
if($uri === false)
throw new InvalidArgumentException('URI cannot be parsed.');
$this->setScheme($uri['scheme'] ?? '');
$this->setUserInfo($uri['user'] ?? '', $uri['pass'] ?? null);
$this->setHost($uri['host'] ?? '');
$this->setPort($uri['port'] ?? null);
$this->setPath($uri['path'] ?? '');
$this->setQuery($uri['query'] ?? '');
$this->setFragment($uri['fragment'] ?? '');
}
}
public function getHash(): string {
return hash('sha256', (string)$this);
}
public function jsonSerialize(): stdClass {
$obj = new stdClass;
$obj->uri = (string)$this;
if($this->scheme !== '')
$obj->scheme = $this->scheme;
if($this->user !== '')
$obj->user = $this->user;
if($this->password !== null)
$obj->password = $this->password;
if($this->host !== '')
$obj->host = $this->host;
if($this->port !== null)
$obj->port = $this->port;
if($this->path !== '')
$obj->path = $this->path;
if($this->query !== '')
$obj->query = $this->query;
if($this->fragment !== '')
$obj->fragment = $this->fragment;
//$obj->hash = $this->getHash();
return $obj;
}
public function getOriginalString(): string {
return $this->originalString;
}
public function getScheme() {
return $this->scheme;
}
public function setScheme(string $scheme): self {
$this->scheme = $scheme;
return $this;
}
public function getAuthority() {
$authority = '';
if(!empty($userInfo = $this->getUserInfo()))
$authority .= $userInfo . '@';
$authority .= $this->getHost();
if(($port = $this->getPort()) !== null)
$authority .= ':' . $port;
return $authority;
}
public function getUserInfo() {
$userInfo = $this->user;
if(!empty($this->password))
$userInfo .= ':' . $this->password;
return $userInfo;
}
public function setUserInfo(string $user, ?string $password = null): self {
$this->user = $user;
$this->password = $password;
return $this;
}
public function getHost() {
return $this->host;
}
public function setHost(string $host): self {
$this->host = $host;
return $this;
}
public function getPort() {
return $this->port;
}
public function setPort(?int $port): self {
if($port !== null && ($port < 1 || $port > 0xFFFF))
throw new InvalidArgumentException('Invalid port.');
$this->port = $port;
return $this;
}
public function getPath() {
return $this->path;
}
public function setPath(string $path): self {
$this->path = $path;
return $this;
}
public function getQuery() {
return $this->query;
}
public function setQuery(string $query): self {
$this->query = $query;
return $this;
}
public function getFragment() {
return $this->fragment;
}
public function setFragment(string $fragment): self {
$this->fragment = $fragment;
return $this;
}
public function __toString() {
$string = '';
if(!empty($scheme = $this->getScheme()))
$string .= $scheme . ':';
$authority = $this->getAuthority();
$hasAuthority = !empty($authority);
if($hasAuthority)
$string .= '//' . $authority;
$path = $this->getPath();
$hasPath = !empty($path);
if($hasAuthority && (!$hasPath || $path[0] !== '/'))
$string .= '/';
elseif(!$hasAuthority && $path[1] === '/')
$path = '/' . trim($path, '/');
$string .= $path;
if(!empty($query = $this->getQuery())) {
$string .= '?';
$queryParts = explode('&', $query);
foreach($queryParts as $queryPart) {
$kvp = explode('=', $queryPart, 2);
$string .= rawurlencode($kvp[0]);
if(isset($kvp[1]))
$string .= '=' . rawurlencode($kvp[1]);
$string .= '&';
}
$string = substr($string, 0, -1);
}
if(!empty($fragment = $this->getFragment()))
$string .= '#' . rawurlencode($fragment);
return $string;
}
}