|
6 | 6 | * Leaf Http Caching |
7 | 7 | * ------------------------------------ |
8 | 8 | * HTTP Caching made simple with Leaf |
9 | | - * |
| 9 | + * |
10 | 10 | * @author Michael Darko |
11 | 11 | * @since 3.0.0 |
12 | 12 | */ |
13 | 13 | class Cache |
14 | 14 | { |
15 | | - /** |
16 | | - * Set Last-Modified HTTP Response Header |
17 | | - * |
18 | | - * Set the HTTP 'Last-Modified' header and stop if a conditional |
19 | | - * GET request's `If-Modified-Since` header matches the last modified time |
20 | | - * of the resource. The `time` argument is a UNIX timestamp integer value. |
21 | | - * When the current request includes an 'If-Modified-Since' header that |
22 | | - * matches the specified last modified time, the application will stop |
23 | | - * and send a '304 Not Modified' response to the client. |
24 | | - * |
25 | | - * @param int $time The last modified UNIX timestamp |
26 | | - */ |
27 | | - public static function lastModified(int $time) |
28 | | - { |
29 | | - Headers::set('Last-Modified', gmdate('D, d M Y H:i:s T', $time)); |
| 15 | + /** |
| 16 | + * Set Last-Modified HTTP Response Header |
| 17 | + * |
| 18 | + * Set the HTTP 'Last-Modified' header and stop if a conditional |
| 19 | + * GET request's `If-Modified-Since` header matches the last modified time |
| 20 | + * of the resource. The `time` argument is a UNIX timestamp integer value. |
| 21 | + * When the current request includes an 'If-Modified-Since' header that |
| 22 | + * matches the specified last modified time, the application will stop |
| 23 | + * and send a '304 Not Modified' response to the client. |
| 24 | + * |
| 25 | + * @param int $time The last modified UNIX timestamp |
| 26 | + */ |
| 27 | + public static function lastModified(int $time) |
| 28 | + { |
| 29 | + Headers::set('Last-Modified', gmdate('D, d M Y H:i:s T', $time)); |
30 | 30 |
|
31 | | - if ($time === strtotime(Headers::get('If-Modified-Since'))) { |
32 | | - \Leaf\App::halt(304); |
33 | | - } |
34 | | - } |
| 31 | + $ifModifiedSince = Headers::get('If-Modified-Since'); |
35 | 32 |
|
36 | | - /** |
37 | | - * Set ETag HTTP Response Header |
38 | | - * |
39 | | - * Set the etag header and stop if the conditional GET request matches. |
40 | | - * The `value` argument is a unique identifier for the current resource. |
41 | | - * The `type` argument indicates whether the etag should be used as a strong or |
42 | | - * weak cache validator. |
43 | | - * |
44 | | - * When the current request includes an 'If-None-Match' header with |
45 | | - * a matching etag, execution is immediately stopped. If the request |
46 | | - * method is GET or HEAD, a '304 Not Modified' response is sent. |
47 | | - * |
48 | | - * @param string $value The etag value |
49 | | - * @param string $type The type of etag to create; either "strong" or "weak" |
50 | | - */ |
51 | | - public static function etag(string $value, string $type = "strong") |
52 | | - { |
53 | | - if (!in_array($type, ["strong", "weak"])) { |
54 | | - trigger_error("Invalid Leaf::etag type. Expected either \"strong\" or \"weak\"."); |
55 | | - } |
| 33 | + if ($ifModifiedSince && $time === strtotime($ifModifiedSince)) { |
| 34 | + \Leaf\App::halt(304); |
| 35 | + } |
| 36 | + } |
56 | 37 |
|
57 | | - $value = "\"$value\""; |
| 38 | + /** |
| 39 | + * Set ETag HTTP Response Header |
| 40 | + * |
| 41 | + * Set the etag header and stop if the conditional GET request matches. |
| 42 | + * The `value` argument is a unique identifier for the current resource. |
| 43 | + * The `type` argument indicates whether the etag should be used as a strong or |
| 44 | + * weak cache validator. |
| 45 | + * |
| 46 | + * When the current request includes an 'If-None-Match' header with |
| 47 | + * a matching etag, execution is immediately stopped. If the request |
| 48 | + * method is GET or HEAD, a '304 Not Modified' response is sent. |
| 49 | + * |
| 50 | + * @param string $value The etag value |
| 51 | + * @param string $type The type of etag to create; either "strong" or "weak" |
| 52 | + */ |
| 53 | + public static function etag(string $value, string $type = 'strong') |
| 54 | + { |
| 55 | + if (!in_array($type, ['strong', 'weak'])) { |
| 56 | + trigger_error('Invalid Leaf::etag type. Expected either "strong" or "weak".'); |
| 57 | + } |
58 | 58 |
|
59 | | - if ($type === "weak") { |
60 | | - $value = "W/" . $value; |
61 | | - } |
| 59 | + $value = "\"$value\""; |
62 | 60 |
|
63 | | - Headers::set("ETag", $value); |
| 61 | + if ($type === 'weak') { |
| 62 | + $value = 'W/' . $value; |
| 63 | + } |
64 | 64 |
|
65 | | - if ($etagsHeader = Headers::get("If-None-Match")) { |
66 | | - $etags = preg_split("@\s*,\s*@", $etagsHeader); |
| 65 | + Headers::set('ETag', $value); |
67 | 66 |
|
68 | | - if (in_array($value, $etags) || in_array("*", $etags)) { |
69 | | - $_304Methods = [Request::METHOD_GET, Request::METHOD_HEAD]; |
| 67 | + if ($etagsHeader = Headers::get('If-None-Match')) { |
| 68 | + $etags = preg_split("@\s*,\s*@", $etagsHeader); |
70 | 69 |
|
71 | | - if (in_array(Request::getMethod(), $_304Methods)) { |
72 | | - \Leaf\App::halt(304); |
73 | | - } else { |
74 | | - // according to https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26 |
75 | | - // all methods besides GET and HEAD should return a 421 (Precondition Failed) |
76 | | - \Leaf\App::halt(412); |
77 | | - } |
78 | | - } |
79 | | - } |
80 | | - } |
| 70 | + if (in_array($value, $etags) || in_array('*', $etags)) { |
| 71 | + $_304Methods = [Request::METHOD_GET, Request::METHOD_HEAD]; |
81 | 72 |
|
82 | | - /** |
83 | | - * Set Expires HTTP response header |
84 | | - * |
85 | | - * The `Expires` header tells the HTTP client the time at which |
86 | | - * the current resource should be considered stale. At that time the HTTP |
87 | | - * client will send a conditional GET request to the server; the server |
88 | | - * may return a 200 OK if the resource has changed, else a 304 Not Modified |
89 | | - * if the resource has not changed. The `Expires` header should be used in |
90 | | - * conjunction with the `etag()` or `lastModified()` methods above. |
91 | | - * |
92 | | - * @param string|int $time If string, a time to be parsed by `strtotime()`; If int, a UNIX timestamp; |
93 | | - */ |
94 | | - public static function expires($time) |
95 | | - { |
96 | | - if (is_string($time)) { |
97 | | - $time = strtotime($time); |
98 | | - } |
| 73 | + if (in_array(Request::getMethod(), $_304Methods)) { |
| 74 | + \Leaf\App::halt(304); |
| 75 | + } else { |
| 76 | + // according to https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26 |
| 77 | + // all methods besides GET and HEAD should return a 421 (Precondition Failed) |
| 78 | + \Leaf\App::halt(412); |
| 79 | + } |
| 80 | + } |
| 81 | + } |
| 82 | + } |
99 | 83 |
|
100 | | - Headers::set('Expires', gmdate('D, d M Y H:i:s T', $time)); |
101 | | - } |
| 84 | + /** |
| 85 | + * Set Expires HTTP response header |
| 86 | + * |
| 87 | + * The `Expires` header tells the HTTP client the time at which |
| 88 | + * the current resource should be considered stale. At that time the HTTP |
| 89 | + * client will send a conditional GET request to the server; the server |
| 90 | + * may return a 200 OK if the resource has changed, else a 304 Not Modified |
| 91 | + * if the resource has not changed. The `Expires` header should be used in |
| 92 | + * conjunction with the `etag()` or `lastModified()` methods above. |
| 93 | + * |
| 94 | + * @param string|int $time If string, a time to be parsed by `strtotime()`; If int, a UNIX timestamp; |
| 95 | + */ |
| 96 | + public static function expires($time) |
| 97 | + { |
| 98 | + if (is_string($time)) { |
| 99 | + $time = strtotime($time); |
| 100 | + } |
| 101 | + |
| 102 | + Headers::set('Expires', gmdate('D, d M Y H:i:s T', $time)); |
| 103 | + } |
102 | 104 | } |
0 commit comments