Skip to content

Commit efd67d1

Browse files
gabidjweierophinney
authored andcommitted
Added PSR-7 Interfaces brief explanations and Basic Usage Guide (#79)
* Added PSR-7 Interfaces Usage guide using Zend Diactoros * Corrected errors in documentation corrected PSR-7 methods explanations corrected typos removed concrete usage of diactoros removed unnecessary text removed zend-diactoros autoload added assumption of $request and $response * Update PSR7-Usage.md * Corrected interfaces list
1 parent f6561bf commit efd67d1

File tree

3 files changed

+293
-1
lines changed

3 files changed

+293
-1
lines changed

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ interface that describes a HTTP message. See the specification for more details.
1010
Usage
1111
-----
1212

13-
We'll certainly need some stuff in here.
13+
Before reading the usage guide we recommend reading the PSR-7 interfaces method list:
14+
15+
* [`PSR-7 Interfaces Method List`](docs/PSR7-Interfaces.md)
16+
* [`PSR-7 Usage Guide`](docs/PSR7-Usage.md)

docs/PSR7-Interfaces.md

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# Interfaces
2+
3+
The purpose of this list is to help in finding the methods when working with PSR-7. This can be considered as a cheatsheet for PSR-7 interfaces.
4+
5+
The interfaces defined in PSR-7 are the following:
6+
7+
| Class Name | Description |
8+
|---|---|
9+
| [Psr\Http\Message\MessageInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessagemessageinterface) | Representation of a HTTP message |
10+
| [Psr\Http\Message\RequestInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessagerequestinterface) | Representation of an outgoing, client-side request. |
11+
| [Psr\Http\Message\ServerRequestInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageserverrequestinterface) | Representation of an incoming, server-side HTTP request. |
12+
| [Psr\Http\Message\ResponseInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageresponseinterface) | Representation of an outgoing, server-side response. |
13+
| [Psr\Http\Message\StreamInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessagestreaminterface) | Describes a data stream |
14+
| [Psr\Http\Message\UriInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageuriinterface) | Value object representing a URI. |
15+
| [Psr\Http\Message\UploadedFileInterface](http://www.php-fig.org/psr/psr-7/#psrhttpmessageuploadedfileinterface) | Value object representing a file uploaded through an HTTP request. |
16+
17+
## `Psr\Http\Message\MessageInterface` Methods
18+
19+
| Method Name | Description | Notes |
20+
|------------------------------------| ----------- | ----- |
21+
| `getProtocolVersion()` | Retrieve HTTP protocol version | 1.0 or 1.1 |
22+
| `withProtocolVersion($version)` | Returns new message instance with given HTTP protocol version | |
23+
| `getHeaders()` | Retrieve all HTTP Headers | [Request Header List](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Request_fields), [Response Header List](https://en.wikipedia.org/wiki/List_of_HTTP_header_fields#Response_fields) |
24+
| `hasHeader($name)` | Checks if HTTP Header with given name exists | |
25+
| `getHeader($name)` | Retrieves a array with the values for a single header | |
26+
| `getHeaderLine($name)` | Retrieves a comma-separated string of the values for a single header | |
27+
| `withHeader($name, $value)` | Returns new message instance with given HTTP Header | if the header existed in the original instance, replaces the header value from the original message with the value provided when creating the new instance. |
28+
| `withAddedHeader($name, $value)` | Returns new message instance with appended value to given header | If header already exists value will be appended, if not a new header will be created |
29+
| `withoutHeader($name)` | Removes HTTP Header with given name| |
30+
| `getBody()` | Retrieves the HTTP Message Body | Returns object implementing `StreamInterface`|
31+
| `withBody(StreamInterface $body)` | Returns new message instance with given HTTP Message Body | |
32+
33+
34+
## `Psr\Http\Message\RequestInterface` Methods
35+
36+
Same methods as `Psr\Http\Message\MessageInterface` + the following methods:
37+
38+
| Method Name | Description | Notes |
39+
|------------------------------------| ----------- | ----- |
40+
| `getRequestTarget()` | Retrieves the message's request target | origin-form, absolute-form, authority-form, asterisk-form ([RFC7230](https://www.rfc-editor.org/rfc/rfc7230.txt)) |
41+
| `withRequestTarget($requestTarget)` | Return a new message instance with the specific request-target | |
42+
| `getMethod()` | Retrieves the HTTP method of the request. | GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE (defined in [RFC7231](https://tools.ietf.org/html/rfc7231)), PATCH (defined in [RFC5789](https://tools.ietf.org/html/rfc5789)) |
43+
| `withMethod($method)` | Returns a new message instance with the provided HTTP method | |
44+
| `getUri()` | Retrieves the URI instance | |
45+
| `withUri(UriInterface $uri, $preserveHost = false)` | Returns a new message instance with the provided URI | |
46+
47+
48+
## `Psr\Http\Message\ServerRequestInterface` Methods
49+
50+
Same methods as `Psr\Http\Message\RequestInterface` + the following methods:
51+
52+
| Method Name | Description | Notes |
53+
|------------------------------------| ----------- | ----- |
54+
| `getServerParams() ` | Retrieve server parameters | Typically derived from `$_SERVER` |
55+
| `getCookieParams()` | Retrieves cookies sent by the client to the server. | Typically derived from `$_COOKIES` |
56+
| `withCookieParams(array $cookies)` | Returns a new request instance with the specified cookies | |
57+
| `withQueryParams(array $query)` | Returns a new request instance with the specified query string arguments | |
58+
| `getUploadedFiles()` | Retrieve normalized file upload data | |
59+
| `withUploadedFiles(array $uploadedFiles)` | Returns a new request instance with the specified uploaded files | |
60+
| `getParsedBody()` | Retrieve any parameters provided in the request body | |
61+
| `withParsedBody($data)` | Returns a new request instance with the specified body parameters | |
62+
| `getAttributes()` | Retrieve attributes derived from the request | |
63+
| `getAttribute($name, $default = null)` | Retrieve a single derived request attribute | |
64+
| `withAttribute($name, $value)` | Returns a new request instance with the specified derived request attribute | |
65+
| `withoutAttribute($name)` | Returns a new request instance that without the specified derived request attribute | |
66+
67+
## `Psr\Http\Message\ResponseInterface` Methods:
68+
69+
Same methods as `Psr\Http\Message\MessageInterface` + the following methods:
70+
71+
| Method Name | Description | Notes |
72+
|------------------------------------| ----------- | ----- |
73+
| `getStatusCode()` | Gets the response status code. | |
74+
| `withStatus($code, $reasonPhrase = '')` | Returns a new response instance with the specified status code and, optionally, reason phrase. | |
75+
| `getReasonPhrase()` | Gets the response reason phrase associated with the status code. | |
76+
77+
## `Psr\Http\Message\StreamInterface` Methods
78+
79+
| Method Name | Description | Notes |
80+
|------------------------------------| ----------- | ----- |
81+
| `__toString()` | Reads all data from the stream into a string, from the beginning to end. | |
82+
| `close()` | Closes the stream and any underlying resources. | |
83+
| `detach()` | Separates any underlying resources from the stream. | |
84+
| `getSize()` | Get the size of the stream if known. | |
85+
| `eof()` | Returns true if the stream is at the end of the stream.| |
86+
| `isSeekable()` | Returns whether or not the stream is seekable. | |
87+
| `seek($offset, $whence = SEEK_SET)` | Seek to a position in the stream. | |
88+
| `rewind()` | Seek to the beginning of the stream. | |
89+
| `isWritable()` | Returns whether or not the stream is writable. | |
90+
| `write($string)` | Write data to the stream. | |
91+
| `isReadable()` | Returns whether or not the stream is readable. | |
92+
| `read($length)` | Read data from the stream. | |
93+
| `getContents()` | Returns the remaining contents in a string | |
94+
| `getMetadata($key = null)()` | Get stream metadata as an associative array or retrieve a specific key. | |
95+
96+
## `Psr\Http\Message\UriInterface` Methods
97+
98+
| Method Name | Description | Notes |
99+
|------------------------------------| ----------- | ----- |
100+
| `getScheme()` | Retrieve the scheme component of the URI. | |
101+
| `getAuthority()` | Retrieve the authority component of the URI. | |
102+
| `getUserInfo()` | Retrieve the user information component of the URI. | |
103+
| `getHost()` | Retrieve the host component of the URI. | |
104+
| `getPort()` | Retrieve the port component of the URI. | |
105+
| `getPath()` | Retrieve the path component of the URI. | |
106+
| `getQuery()` | Retrieve the query string of the URI. | |
107+
| `getFragment()` | Retrieve the fragment component of the URI. | |
108+
| `withScheme($scheme)` | Return an instance with the specified scheme. | |
109+
| `withUserInfo($user, $password = null)` | Return an instance with the specified user information. | |
110+
| `withHost($host)` | Return an instance with the specified host. | |
111+
| `withPort($port)` | Return an instance with the specified port. | |
112+
| `withPath($path)` | Return an instance with the specified path. | |
113+
| `withQuery($query)` | Return an instance with the specified query string. | |
114+
| `withFragment($fragment)` | Return an instance with the specified URI fragment. | |
115+
| `__toString()` | Return the string representation as a URI reference. | |
116+
117+
## `Psr\Http\Message\UploadedFileInterface` Methods
118+
119+
| Method Name | Description | Notes |
120+
|------------------------------------| ----------- | ----- |
121+
| `getStream()` | Retrieve a stream representing the uploaded file. | |
122+
| `moveTo($targetPath)` | Move the uploaded file to a new location. | |
123+
| `getSize()` | Retrieve the file size. | |
124+
| `getError()` | Retrieve the error associated with the uploaded file. | |
125+
| `getClientFilename()` | Retrieve the filename sent by the client. | |
126+
| `getClientMediaType()` | Retrieve the media type sent by the client. | |
127+
128+
> `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`.
129+
> When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered.
130+

docs/PSR7-Usage.md

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
### PSR-7 Usage
2+
3+
All PSR-7 applications comply with these interfaces
4+
They were created to establish a standard between middleware implementations.
5+
6+
> `RequestInterface`, `ServerRequestInterface`, `ResponseInterface` extend `MessageInterface` because the `Request` and the `Response` are `HTTP Messages`.
7+
> When using `ServerRequestInterface`, both `RequestInterface` and `Psr\Http\Message\MessageInterface` methods are considered.
8+
9+
10+
The following examples will illustrate how basic operations are done in PSR-7.
11+
12+
##### Examples
13+
14+
15+
For this examples to work (at least) a PSR-7 implementation package is required. (eg: zendframework/zend-diactoros, guzzlehttp/psr7, slim/slim, etc)
16+
All PSR-7 implementations should have the same behaviour.
17+
18+
The following will be assumed:
19+
`$request` is an object of `Psr\Http\Message\RequestInterface` and
20+
21+
`$response` is an object implementing `Psr\Http\Message\RequestInterface`
22+
23+
24+
### Working with HTTP Headers
25+
26+
#### Adding headers to response:
27+
28+
```php
29+
$response->withHeader('My-Custom-Header', 'My Custom Message');
30+
```
31+
32+
#### Appending values to headers
33+
34+
```php
35+
$response->withAddedHeader('My-Custom-Header', 'The second message');
36+
```
37+
38+
#### Checking if header exists:
39+
40+
```php
41+
$request->hasHeader('My-Custom-Header'); // will return false
42+
$response->hasHeader('My-Custom-Header'); // will return true
43+
```
44+
45+
> Note: My-Custom-Header was only added in the Response
46+
47+
#### Getting comma-separated values from a header (also applies to request)
48+
49+
```php
50+
// getting value from request headers
51+
$request->getHeaderLine('Content-Type'); // will return: "text/html; charset=UTF-8"
52+
// getting value from response headers
53+
$response->getHeaderLine('My-Custom-Header'); // will return: "My Custom Message; The second message"
54+
```
55+
56+
#### Getting array of value from a header (also applies to request)
57+
```php
58+
// getting value from request headers
59+
$request->getHeader('Content-Type'); // will return: ["text/html", "charset=UTF-8"]
60+
// getting value from response headers
61+
$response->getHeader('My-Custom-Header'); // will return: ["My Custom Message", "The second message"]
62+
```
63+
64+
#### Removing headers from HTTP Messages
65+
```php
66+
// removing a header from Request, removing deprecated "Content-MD5" header
67+
$request->withoutHeader('Content-MD5');
68+
69+
// removing a header from Response
70+
// effect: the browser won't know the size of the stream
71+
// the browser will download the stream till it ends
72+
$response->withoutHeader('Content-Length');
73+
```
74+
75+
### Working with HTTP Message Body
76+
77+
When working with the PSR-7 there are two methods of implementation:
78+
#### 1. Getting the body separately
79+
80+
> This method makes the body handling easier to understand and is useful when repeatedly calling body methods. (You only call `getBody()` once). Using this method mistakes like `$response->write()` are also prevented.
81+
82+
```php
83+
$body = $response->getBody();
84+
// operations on body, eg. read, write, seek
85+
// ...
86+
// replacing the old body
87+
$response->withBody($body);
88+
// this last statement is optional as we working with objects
89+
// in this case the "new" body is same with the "old" one
90+
// the $body variable has the same value as the one in $request, only the reference is passed
91+
```
92+
93+
#### 2. Working directly on response
94+
95+
> This method is useful when only performing few operations as the `$request->getBody()` statement fragment is required
96+
97+
```php
98+
$response->getBody()->write('hello');
99+
```
100+
101+
### Getting the body contents
102+
103+
The following snippet gets the contents of a stream contents.
104+
> Note: Streams must be rewinded, if content was written into streams, it will be ignored when calling `getContents()` because the stream pointer is set to the last character, which is `\0` - meaning end of stream.
105+
```php
106+
$body = $response->getBody();
107+
$body->rewind(); // or $body->seek(0);
108+
$bodyText = $body->getContents();
109+
```
110+
> Note: If `$body->seek(1)` is called before `$body->getContents()`, the first character will be ommited as the starting pointer is set to `1`, not `0`. This is why using `$body->rewind()` is recommended.
111+
112+
### Append to body
113+
114+
```php
115+
$response->getBody()->write('Hello'); // writing directly
116+
$body = $request->getBody(); // which is a `StreamInterface`
117+
$body->write('xxxxx');
118+
```
119+
120+
### Prepend to body
121+
Prepending is different when it comes to streams. The content must be copied before writing the content to be prepended.
122+
The following example will explain the behaviour of streams.
123+
124+
```php
125+
// assuming our response is initially empty
126+
$body = $repsonse->getBody();
127+
// writing the string "abcd"
128+
$body->write('abcd');
129+
130+
// seeking to start of stream
131+
$body->seek(0);
132+
// writing 'ef'
133+
$body->write('ef'); // at this point the stream contains "efcd"
134+
```
135+
136+
#### Prepending by rewriting separately
137+
138+
```php
139+
// assuming our response body stream only contains: "abcd"
140+
$body = $response->getBody();
141+
$body->rewind();
142+
$contents = $body->getContents(); // abcd
143+
// seeking the stream to beginning
144+
$body->rewind();
145+
$body->write('ef'); // stream contains "efcd"
146+
$body->write($contents); // stream contains "efabcd"
147+
```
148+
149+
> Note: `getContents()` seeks the stream while reading it, therefore if the second `rewind()` method call was not present the stream would have resulted in `abcdefabcd` because the `write()` method appends to stream if not preceeded by `rewind()` or `seek(0)`.
150+
151+
#### Prepending by using contents as a string
152+
```php
153+
$body = $response->getBody();
154+
$body->rewind();
155+
$contents = $body->getContents(); // efabcd
156+
$contents = 'ef'.$contents;
157+
$body->rewind();
158+
$body->write($contents);
159+
```

0 commit comments

Comments
 (0)