scheme = strtolower($parts['scheme']); if(isset($parts['host'])) $this->host = $parts['host']; if(isset($parts['port'])) $this->port = $parts['port']; if(isset($parts['user'])) $this->user = $parts['user']; if(isset($parts['pass'])) $this->pass = $parts['pass']; if(isset($parts['path'])) $this->path = $parts['path']; if(isset($parts['query'])) $this->query = $parts['query']; if(isset($parts['fragment'])) $this->fragment = $parts['fragment']; } public static function parse(string $urlString): Url { $parts = parse_url($urlString); if($parts === false) throw new InvalidArgumentException('Invalid URL provided.'); return new Url($parts); } public function resetString(): void { $this->formatted = null; } public function setScheme(string $scheme): void { $this->scheme = $scheme; $this->resetString(); } public function discardFragment(): void { $this->fragment = ''; $this->resetString(); } public function hasScheme(): bool { return $this->scheme !== ''; } public function hasHost(): bool { return $this->host !== ''; } public function hasPort(): bool { return $this->port !== 0; } public function hasUser(): bool { return $this->user !== ''; } public function hasPassword(): bool { return $this->pass !== ''; } public function hasPath(): bool { return $this->path !== ''; } public function hasQuery(): bool { return $this->query !== ''; } public function hasFragment(): bool { return $this->fragment !== ''; } public function getScheme(): string { return $this->scheme; } public function getHost(): string { return $this->host; } public function getPort(): int { return $this->port; } public function getUser(): string { return $this->user; } public function getPassword(): string { return $this->pass; } public function getPath(): string { return $this->path; } public function getQuery(): string { return $this->query; } public function getFragment(): string { return $this->fragment; } public function hasUserInfo(): bool { return $this->hasUser() || $this->hasPassword(); } public function hasAuthority(): bool { return $this->hasUserInfo() || $this->hasHost(); } public function getUserInfo(): string { $userInfo = $this->user; if($this->pass !== '') $userInfo .= ':' . $this->pass; return $userInfo; } public function getAuthority(): string { $authority = '//'; if($this->hasUserInfo()) $authority .= $this->getUserInfo() . '@'; $authority .= $this->host; if($this->port !== 0) $authority .= ':' . $this->port; return $authority; } public function calculateHash(bool $raw = true): string { return hash('sha256', (string)$this, $raw); } public function isHTTP(): bool { return $this->scheme === 'http'; } public function isHTTPS(): bool { return $this->scheme === 'https'; } public function isWeb(): bool { return $this->scheme === 'https' || $this->scheme === 'http'; } public function __toString(): string { if($this->formatted === null) { $string = ''; if($this->hasScheme()) $string .= $this->getScheme() . ':'; $hasAuthority = $this->hasAuthority(); if($hasAuthority) $string .= $this->getAuthority(); $hasPath = $this->hasPath(); $path = $this->getPath(); if($hasAuthority && (!$hasPath || $path[0] !== '/')) $string .= '/'; elseif(!$hasAuthority && $path[1] === '/') $path = '/' . trim($path, '/'); $string .= $path; // is all this necessary...? if($this->hasQuery()) { $string .= '?'; $parts = explode('&', $this->getQuery()); foreach($parts as $part) { $param = explode('=', $part, 2); $string .= rawurlencode($param[0]); if(isset($param[1])) $string .= '=' . rawurlencode($param[1]); $string .= '&'; } $string = substr($string, 0, -1); } if($this->hasFragment()) $string .= '#' . rawurlencode($this->getFragment()); $this->formatted = $string; } return $this->formatted; } public function toV1(): array { $parts = ['uri' => (string)$this]; if($this->hasScheme()) $parts['scheme'] = $this->getScheme(); if($this->hasHost()) $parts['host'] = $this->getHost(); if($this->hasPort()) $parts['port'] = $this->getPort(); if($this->hasUser()) $parts['user'] = $this->getUser(); if($this->hasPassword()) $parts['pass'] = $parts['password'] = $this->getPassword(); if($this->hasPath()) $parts['path'] = $this->getPath(); if($this->hasQuery()) $parts['query'] = $this->getQuery(); if($this->hasFragment()) $parts['fragment'] = $this->getFragment(); return $parts; } }