1<?php 2 3namespace iplx\Http; 4 5use InvalidArgumentException; 6use Psr\Http\Message\UriInterface; 7 8class Uri implements UriInterface 9{ 10 protected $scheme; 11 12 protected $host; 13 14 protected $port; 15 16 protected $user; 17 18 protected $pass; 19 20 protected $path; 21 22 protected $query; 23 24 protected $fragment; 25 26 public function __construct($uri = null) 27 { 28 $parts = parse_url($uri); 29 30 if ($parts === false) { 31 throw new InvalidArgumentException(); 32 } 33 34 foreach ($parts as $component => $value) { 35 $this->$component = $value; 36 } 37 } 38 39 public function getScheme() 40 { 41 return $this->scheme; 42 } 43 44 public function getAuthority() 45 { 46 // Weak type check to also check null 47 if ($this->host == '') { 48 return ''; 49 } 50 51 $authority = $this->host; 52 53 $userInfo = $this->getUserInfo(); 54 $port = $this->getPort(); 55 56 if ($userInfo) { 57 $authority = "$userInfo@$authority"; 58 } 59 60 if ($port !== null) { 61 $authority .= ":$port"; 62 } 63 64 return $authority; 65 } 66 67 public function getUserInfo() 68 { 69 $userInfo = $this->user; 70 71 if ($this->pass !== null) { 72 $userInfo .= ":{$this->pass}"; 73 } 74 75 return $userInfo; 76 } 77 78 public function getHost() 79 { 80 return $this->host; 81 } 82 83 public function getPort() 84 { 85 return $this->port; 86 } 87 88 public function getPath() 89 { 90 return $this->path; 91 } 92 93 public function getQuery() 94 { 95 return $this->query; 96 } 97 98 public function getFragment() 99 { 100 return $this->fragment; 101 } 102 103 public function withScheme($scheme) 104 { 105 $uri = clone $this; 106 $uri->scheme = $scheme; 107 108 return $uri; 109 } 110 111 public function withUserInfo($user, $password = null) 112 { 113 $uri = clone $this; 114 $uri->user = $user; 115 $uri->pass = $password; 116 117 return $uri; 118 } 119 120 public function withHost($host) 121 { 122 $uri = clone $this; 123 $uri->host = $host; 124 125 return $uri; 126 } 127 128 public function withPort($port) 129 { 130 $uri = clone $this; 131 $uri->port = $port; 132 133 return $uri; 134 } 135 136 public function withPath($path) 137 { 138 $uri = clone $this; 139 $uri->path = $path; 140 141 return $uri; 142 } 143 144 public function withQuery($query) 145 { 146 $uri = clone $this; 147 $uri->query = $query; 148 149 return $uri; 150 } 151 152 public function withFragment($fragment) 153 { 154 $uri = clone $this; 155 $uri->fragment = $fragment; 156 157 return $uri; 158 } 159 160 public function __toString() 161 { 162 $scheme = $this->getScheme(); 163 $authority = $this->getAuthority(); 164 $path = $this->getPath(); 165 $query = $this->getQuery(); 166 $fragment = $this->getFragment(); 167 168 $uri = ''; 169 170 // Weak type checks to also check null 171 172 if ($scheme != '') { 173 $uri = "$scheme:"; 174 } 175 176 if ($authority != '') { 177 $uri .= "//$authority"; 178 } 179 180 if ($path != '') { 181 if ($path[0] === '/') { 182 if ($authority == '') { 183 $path = ltrim($path, '/'); 184 } 185 } else { 186 $path = "/$path"; 187 } 188 189 $uri .= $path; 190 } 191 192 if ($query != '') { 193 $uri .= "?$query"; 194 } 195 196 if ($fragment != '') { 197 $uri .= "#$fragment"; 198 } 199 200 return $uri; 201 } 202} 203