A PHP package for parsing the HTTP Link header (RFC 8288).
Requirements#
This package requires PHP 8.3+.
Installation#
You can install the package via composer:
composer require goedemiddag/link-header-parser
Usage#
Parsing a header string#
Pass the raw Link header value to LinkHeaderFactory::fromHeader(). It returns a LinkHeader object keyed by relation type.
use Goedemiddag\LinkHeaderParser\LinkHeaderFactory;
$header = '<https://api.example.com/items?page=2>; rel="next", '
. '<https://api.example.com/items?page=5>; rel="last"';
$linkHeader = LinkHeaderFactory::fromHeader($header);
$next = $linkHeader->getLink('next'); // Link object, or null
$last = $linkHeader->getLink('last');
echo $next->uri; // https://api.example.com/items?page=2
The full HTTP header line (including the Link: prefix) is accepted as well:
$linkHeader = LinkHeaderFactory::fromHeader('Link: <https://example.com/page/2>; rel="next"');
Accessing link attributes#
Each Link carries the URI, the relation type, and any extra parameters such as type, title, or hreflang.
$linkHeader = LinkHeaderFactory::fromHeader(
'<https://example.com/feed>; rel="alternate"; type="application/rss+xml"; title="RSS"'
);
$link = $linkHeader->getLink('alternate');
echo $link->uri; // https://example.com/feed
echo $link->rel; // alternate
echo $link->getAttribute('type'); // application/rss+xml
echo $link->getAttribute('title'); // RSS
echo $link->getAttribute('missing'); // null
$link->hasAttribute('type'); // true
$link->hasAttribute('missing'); // false
Dependency injection#
If you want to inject the parser rather than call the static method directly, typehint against LinkHeaderParserInterface:
use Goedemiddag\LinkHeaderParser\LinkHeaderParserInterface;
class MyApiClient
{
public function __construct(private readonly LinkHeaderParserInterface $parser) {}
public function nextPageUrl(string $linkHeaderValue): ?string
{
return $this->parser->parse($linkHeaderValue)->getLink('next')?->uri;
}
}
// Wire it up:
$client = new MyApiClient(new LinkHeaderFactory());
Real-world example — GitHub pagination#
// $response is a PSR-7 ResponseInterface
$raw = $response->getHeaderLine('Link');
$linkHeader = LinkHeaderFactory::fromHeader($raw);
if ($next = $linkHeader->getLink('next')) {
// fetch $next->uri for the next page
}
Behaviour notes#
- Relation types are case-insensitive.
rel="Next"andrel="next"both resolve viagetLink('next'). - Duplicate relation types. When the same
relappears more than once, the last entry wins. - Bare token parameters (e.g.
; nocache) have no value and are silently ignored; onlyname=valuepairs are stored as attributes. - Attribute names are normalised to lowercase.
Type="text/html"is accessible asgetAttribute('type').
Testing#
To run the tests, you can use the following command:
composer test
Security#
If you discover any security related issues in this or other packages of Goedemiddag, please email dev@goedemiddag.nl instead of using the issue tracker.