1<?php
2
3namespace Psr\Http\Message;
4
5/**
6 * Value object representing a URI.
7 *
8 * This interface is meant to represent URIs according to RFC 3986 and to
9 * provide methods for most common operations. Additional functionality for
10 * working with URIs can be provided on top of the interface or externally.
11 * Its primary use is for HTTP requests, but may also be used in other
12 * contexts.
13 *
14 * Instances of this interface are considered immutable; all methods that
15 * might change state MUST be implemented such that they retain the internal
16 * state of the current instance and return an instance that contains the
17 * changed state.
18 *
19 * Typically the Host header will be also be present in the request message.
20 * For server-side requests, the scheme will typically be discoverable in the
21 * server parameters.
22 *
23 * @link http://tools.ietf.org/html/rfc3986 (the URI specification)
24 */
25interface UriInterface
26{
27    /**
28     * Retrieve the scheme component of the URI.
29     *
30     * If no scheme is present, this method MUST return an empty string.
31     *
32     * The value returned MUST be normalized to lowercase, per RFC 3986
33     * Section 3.1.
34     *
35     * The trailing ":" character is not part of the scheme and MUST NOT be
36     * added.
37     *
38     * @see https://tools.ietf.org/html/rfc3986#section-3.1
39     * @return string The URI scheme.
40     */
41    public function getScheme(): string;
42
43    /**
44     * Retrieve the authority component of the URI.
45     *
46     * If no authority information is present, this method MUST return an empty
47     * string.
48     *
49     * The authority syntax of the URI is:
50     *
51     * <pre>
52     * [user-info@]host[:port]
53     * </pre>
54     *
55     * If the port component is not set or is the standard port for the current
56     * scheme, it SHOULD NOT be included.
57     *
58     * @see https://tools.ietf.org/html/rfc3986#section-3.2
59     * @return string The URI authority, in "[user-info@]host[:port]" format.
60     */
61    public function getAuthority(): string;
62
63    /**
64     * Retrieve the user information component of the URI.
65     *
66     * If no user information is present, this method MUST return an empty
67     * string.
68     *
69     * If a user is present in the URI, this will return that value;
70     * additionally, if the password is also present, it will be appended to the
71     * user value, with a colon (":") separating the values.
72     *
73     * The trailing "@" character is not part of the user information and MUST
74     * NOT be added.
75     *
76     * @return string The URI user information, in "username[:password]" format.
77     */
78    public function getUserInfo(): string;
79
80    /**
81     * Retrieve the host component of the URI.
82     *
83     * If no host is present, this method MUST return an empty string.
84     *
85     * The value returned MUST be normalized to lowercase, per RFC 3986
86     * Section 3.2.2.
87     *
88     * @see http://tools.ietf.org/html/rfc3986#section-3.2.2
89     * @return string The URI host.
90     */
91    public function getHost(): string;
92
93    /**
94     * Retrieve the port component of the URI.
95     *
96     * If a port is present, and it is non-standard for the current scheme,
97     * this method MUST return it as an integer. If the port is the standard port
98     * used with the current scheme, this method SHOULD return null.
99     *
100     * If no port is present, and no scheme is present, this method MUST return
101     * a null value.
102     *
103     * If no port is present, but a scheme is present, this method MAY return
104     * the standard port for that scheme, but SHOULD return null.
105     *
106     * @return null|int The URI port.
107     */
108    public function getPort(): ?int;
109
110    /**
111     * Retrieve the path component of the URI.
112     *
113     * The path can either be empty or absolute (starting with a slash) or
114     * rootless (not starting with a slash). Implementations MUST support all
115     * three syntaxes.
116     *
117     * Normally, the empty path "" and absolute path "/" are considered equal as
118     * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically
119     * do this normalization because in contexts with a trimmed base path, e.g.
120     * the front controller, this difference becomes significant. It's the task
121     * of the user to handle both "" and "/".
122     *
123     * The value returned MUST be percent-encoded, but MUST NOT double-encode
124     * any characters. To determine what characters to encode, please refer to
125     * RFC 3986, Sections 2 and 3.3.
126     *
127     * As an example, if the value should include a slash ("/") not intended as
128     * delimiter between path segments, that value MUST be passed in encoded
129     * form (e.g., "%2F") to the instance.
130     *
131     * @see https://tools.ietf.org/html/rfc3986#section-2
132     * @see https://tools.ietf.org/html/rfc3986#section-3.3
133     * @return string The URI path.
134     */
135    public function getPath(): string;
136
137    /**
138     * Retrieve the query string of the URI.
139     *
140     * If no query string is present, this method MUST return an empty string.
141     *
142     * The leading "?" character is not part of the query and MUST NOT be
143     * added.
144     *
145     * The value returned MUST be percent-encoded, but MUST NOT double-encode
146     * any characters. To determine what characters to encode, please refer to
147     * RFC 3986, Sections 2 and 3.4.
148     *
149     * As an example, if a value in a key/value pair of the query string should
150     * include an ampersand ("&") not intended as a delimiter between values,
151     * that value MUST be passed in encoded form (e.g., "%26") to the instance.
152     *
153     * @see https://tools.ietf.org/html/rfc3986#section-2
154     * @see https://tools.ietf.org/html/rfc3986#section-3.4
155     * @return string The URI query string.
156     */
157    public function getQuery(): string;
158
159    /**
160     * Retrieve the fragment component of the URI.
161     *
162     * If no fragment is present, this method MUST return an empty string.
163     *
164     * The leading "#" character is not part of the fragment and MUST NOT be
165     * added.
166     *
167     * The value returned MUST be percent-encoded, but MUST NOT double-encode
168     * any characters. To determine what characters to encode, please refer to
169     * RFC 3986, Sections 2 and 3.5.
170     *
171     * @see https://tools.ietf.org/html/rfc3986#section-2
172     * @see https://tools.ietf.org/html/rfc3986#section-3.5
173     * @return string The URI fragment.
174     */
175    public function getFragment(): string;
176
177    /**
178     * Return an instance with the specified scheme.
179     *
180     * This method MUST retain the state of the current instance, and return
181     * an instance that contains the specified scheme.
182     *
183     * Implementations MUST support the schemes "http" and "https" case
184     * insensitively, and MAY accommodate other schemes if required.
185     *
186     * An empty scheme is equivalent to removing the scheme.
187     *
188     * @param string $scheme The scheme to use with the new instance.
189     * @return static A new instance with the specified scheme.
190     * @throws \InvalidArgumentException for invalid or unsupported schemes.
191     */
192    public function withScheme(string $scheme): UriInterface;
193
194    /**
195     * Return an instance with the specified user information.
196     *
197     * This method MUST retain the state of the current instance, and return
198     * an instance that contains the specified user information.
199     *
200     * Password is optional, but the user information MUST include the
201     * user; an empty string for the user is equivalent to removing user
202     * information.
203     *
204     * @param string $user The user name to use for authority.
205     * @param null|string $password The password associated with $user.
206     * @return static A new instance with the specified user information.
207     */
208    public function withUserInfo(string $user, ?string $password = null): UriInterface;
209
210    /**
211     * Return an instance with the specified host.
212     *
213     * This method MUST retain the state of the current instance, and return
214     * an instance that contains the specified host.
215     *
216     * An empty host value is equivalent to removing the host.
217     *
218     * @param string $host The hostname to use with the new instance.
219     * @return static A new instance with the specified host.
220     * @throws \InvalidArgumentException for invalid hostnames.
221     */
222    public function withHost(string $host): UriInterface;
223
224    /**
225     * Return an instance with the specified port.
226     *
227     * This method MUST retain the state of the current instance, and return
228     * an instance that contains the specified port.
229     *
230     * Implementations MUST raise an exception for ports outside the
231     * established TCP and UDP port ranges.
232     *
233     * A null value provided for the port is equivalent to removing the port
234     * information.
235     *
236     * @param null|int $port The port to use with the new instance; a null value
237     *     removes the port information.
238     * @return static A new instance with the specified port.
239     * @throws \InvalidArgumentException for invalid ports.
240     */
241    public function withPort(?int $port): UriInterface;
242
243    /**
244     * Return an instance with the specified path.
245     *
246     * This method MUST retain the state of the current instance, and return
247     * an instance that contains the specified path.
248     *
249     * The path can either be empty or absolute (starting with a slash) or
250     * rootless (not starting with a slash). Implementations MUST support all
251     * three syntaxes.
252     *
253     * If the path is intended to be domain-relative rather than path relative then
254     * it must begin with a slash ("/"). Paths not starting with a slash ("/")
255     * are assumed to be relative to some base path known to the application or
256     * consumer.
257     *
258     * Users can provide both encoded and decoded path characters.
259     * Implementations ensure the correct encoding as outlined in getPath().
260     *
261     * @param string $path The path to use with the new instance.
262     * @return static A new instance with the specified path.
263     * @throws \InvalidArgumentException for invalid paths.
264     */
265    public function withPath(string $path): UriInterface;
266
267    /**
268     * Return an instance with the specified query string.
269     *
270     * This method MUST retain the state of the current instance, and return
271     * an instance that contains the specified query string.
272     *
273     * Users can provide both encoded and decoded query characters.
274     * Implementations ensure the correct encoding as outlined in getQuery().
275     *
276     * An empty query string value is equivalent to removing the query string.
277     *
278     * @param string $query The query string to use with the new instance.
279     * @return static A new instance with the specified query string.
280     * @throws \InvalidArgumentException for invalid query strings.
281     */
282    public function withQuery(string $query): UriInterface;
283
284    /**
285     * Return an instance with the specified URI fragment.
286     *
287     * This method MUST retain the state of the current instance, and return
288     * an instance that contains the specified URI fragment.
289     *
290     * Users can provide both encoded and decoded fragment characters.
291     * Implementations ensure the correct encoding as outlined in getFragment().
292     *
293     * An empty fragment value is equivalent to removing the fragment.
294     *
295     * @param string $fragment The fragment to use with the new instance.
296     * @return static A new instance with the specified fragment.
297     */
298    public function withFragment(string $fragment): UriInterface;
299
300    /**
301     * Return the string representation as a URI reference.
302     *
303     * Depending on which components of the URI are present, the resulting
304     * string is either a full URI or relative reference according to RFC 3986,
305     * Section 4.1. The method concatenates the various components of the URI,
306     * using the appropriate delimiters:
307     *
308     * - If a scheme is present, it MUST be suffixed by ":".
309     * - If an authority is present, it MUST be prefixed by "//".
310     * - The path can be concatenated without delimiters. But there are two
311     *   cases where the path has to be adjusted to make the URI reference
312     *   valid as PHP does not allow to throw an exception in __toString():
313     *     - If the path is rootless and an authority is present, the path MUST
314     *       be prefixed by "/".
315     *     - If the path is starting with more than one "/" and no authority is
316     *       present, the starting slashes MUST be reduced to one.
317     * - If a query is present, it MUST be prefixed by "?".
318     * - If a fragment is present, it MUST be prefixed by "#".
319     *
320     * @see http://tools.ietf.org/html/rfc3986#section-4.1
321     * @return string
322     */
323    public function __toString(): string;
324}
325