A PHP library for parsing and building HTTP headers.
Via Composer
$ composer require stadly/http
Header values can be parsed using fromValue
on each header class:
use Stadly\Http\Header\Common\ContentType;
use Stadly\Http\Header\Request\IfNoneMatch;
use Stadly\Http\Header\Response\ContentDisposition;
$contentType = ContentType::fromValue($_SERVER['HTTP_CONTENT_TYPE']);
$ifNoneMatch = IfNoneMatch::fromValue($_SERVER['HTTP_IF_NONE_MATCH']);
$contentDisposition = ContentDisposition::fromValue($_SERVER['HTTP_CONTENT_DISPOSITION']);
Header strings can be parsed using HeaderFactory::fromString
:
use Stadly\Http\Header\Request\HeaderFactory as RequestHeaderFactory;
use Stadly\Http\Header\Response\HeaderFactory as ResponseHeaderFactory;
$requestHeaders = [
'Content-Type: text/html; charset=UTF-8',
'If-Match: "67ab43", "54ed21", W/"7892dd"',
'Range: bytes=10-100, 200-300',
];
foreach ($requestHeaders as $headerString) {
$header = RequestHeaderFactory::fromString($headerString);
}
$responseHeaders = [
'Content-Type: multipart/form-data; boundary="abc def"',
'Cache-Control: no-cache="foo, bar", max-age=120, must-revalidate',
"Content-Disposition: attachment; filename=unicorn.jpg; filename*=UTF-8''%F0%9F%A6%84.jpg",
];
foreach ($responseHeaders as $headerString) {
$header = ResponseHeaderFactory::fromString($headerString);
}
Note that header strings include the header name, while header values do not. The following results in identical headers:
use Stadly\Http\Header\Response\ContentDisposition;
use Stadly\Http\Header\Response\HeaderFactory;
$header1 = ContentDisposition::fromValue('inline; filename=image.jpg');
$header2 = HeaderFactory::fromString('Content-Disposition: inline; filename=image.jpg');
Example parsing the If-None-Match
request header and using it to determine whether to serve a file. The response headers Content-Disposition
and ETag
are built for serving the file.
use Stadly\Http\Header\Request\IfNoneMatch;
use Stadly\Http\Header\Response\ContentDisposition;
use Stadly\Http\Header\Response\ETag;
use Stadly\Http\Header\Value\EntityTag\EntityTag;
$entityTag = new EntityTag(md5($filename));
$ifNoneMatch = IfNoneMatch::fromValue($_SERVER['HTTP_IF_NONE_MATCH']);
if ($ifNoneMatch->evaluate($entityTag)) {
// Serve file.
$contentDisposition = new ContentDisposition('attachment');
$contentDisposition->setFilename(basename($filename));
header((string)$contentDisposition);
$eTag = new ETag($entityTag);
header((string)$eTag);
readfile($filename);
} else {
// 304 Not modified.
http_response_code(304);
}
The checked header fields have been implemented.
- Content-Type https://tools.ietf.org/html/rfc7231#section-3.1.1.5
- Content-Encoding https://tools.ietf.org/html/rfc7231#section-3.1.2.2
- Content-Language https://tools.ietf.org/html/rfc7231#section-3.1.3.2
- Content-Location https://tools.ietf.org/html/rfc7231#section-3.1.4.2
- Content-Length https://tools.ietf.org/html/rfc7230#section-3.3.2
- Content-Range https://tools.ietf.org/html/rfc7233#section-4.2
- Trailer https://tools.ietf.org/html/rfc7230#section-4.4
- Transfer-Encoding https://tools.ietf.org/html/rfc7230#section-3.3.1
- Cache-Control https://tools.ietf.org/html/rfc7234#section-5.2
- Expect https://tools.ietf.org/html/rfc7231#section-5.1.1
- Host https://tools.ietf.org/html/rfc7230#section-5.4
- Max-Forwards https://tools.ietf.org/html/rfc7231#section-5.1.2
- Pragma https://tools.ietf.org/html/rfc7234#section-5.4
- Range https://tools.ietf.org/html/rfc7233#section-3.1
- TE https://tools.ietf.org/html/rfc7230#section-4.3
- If-Match https://tools.ietf.org/html/rfc7232#section-3.1
- If-None-Match https://tools.ietf.org/html/rfc7232#section-3.2
- If-Modified-Since https://tools.ietf.org/html/rfc7232#section-3.3
- If-Unmodified-Since https://tools.ietf.org/html/rfc7232#section-3.4
- If-Range https://tools.ietf.org/html/rfc7233#section-3.2
- Accept https://tools.ietf.org/html/rfc7231#section-5.3.2
- Accept-Charset https://tools.ietf.org/html/rfc7231#section-5.3.3
- Accept-Encoding https://tools.ietf.org/html/rfc7231#section-5.3.4
- Accept-Language https://tools.ietf.org/html/rfc7231#section-5.3.5
- Authorization https://tools.ietf.org/html/rfc7235#section-4.2
- Proxy-Authorization https://tools.ietf.org/html/rfc7235#section-4.4
- From https://tools.ietf.org/html/rfc7231#section-5.5.1
- Referer https://tools.ietf.org/html/rfc7231#section-5.5.2
- User-Agent https://tools.ietf.org/html/rfc7231#section-5.5.3
- Age https://tools.ietf.org/html/rfc7234#section-5.1
- Cache-Control https://tools.ietf.org/html/rfc7234#section-5.2
- Expires https://tools.ietf.org/html/rfc7234#section-5.3
- Date https://tools.ietf.org/html/rfc7231#section-7.1.1.2
- Location https://tools.ietf.org/html/rfc7231#section-7.1.2
- Retry-After https://tools.ietf.org/html/rfc7231#section-7.1.3
- Vary https://tools.ietf.org/html/rfc7231#section-7.1.4
- Warning https://tools.ietf.org/html/rfc7234#section-5.5
- ETag https://tools.ietf.org/html/rfc7232#section-2.3
- Last-Modified https://tools.ietf.org/html/rfc7232#section-2.2
- WWW-Authenticate https://tools.ietf.org/html/rfc7235#section-4.1
- Proxy-Authenticate https://tools.ietf.org/html/rfc7235#section-4.3
- Accept-Ranges https://tools.ietf.org/html/rfc7233#section-2.3
- Allow https://tools.ietf.org/html/rfc7231#section-7.4.1
- Server https://tools.ietf.org/html/rfc7231#section-7.4.2
- Content-Disposition https://tools.ietf.org/html/rfc6266#section-4
Please see CHANGELOG for more information on what has changed recently.
$ composer test
Please see CONTRIBUTING and CODE_OF_CONDUCT for details.
If you discover any security related issues, please email magnar@myrtveit.com instead of using the issue tracker.
The MIT License (MIT). Please see License File for more information.