Upgrading from version 1.x to 2.0
bakame/http-structured-fields 2.0 is a new major version that comes with backward compatibility breaks.
This guide will help you migrate from a 2.x version to 2.0. It will only explain backward compatibility breaks,
it will not present the new features,
Installation
If you are using composer then you should update the require section of your composer.json file.
composer require bakame/http-structured-fields:^2.0
This will edit (or create) your composer.json file.
PHP version requirement
bakame/http-structured-fields 2.0 requires a PHP version greater or equal to 8.1 as does the previous version.
Interfaces
Structured Field Interfaces
All the Interfaces around the structured field data types are removed. So if you type-hinted your code using the interfaces, you will need to replace them by their actual implementation.
- The
MemberOrderedMapinterface will need to be replaced either byDictionaryorParametersclasses - The
MemberListinterface will need to be replaced either byOuterListorInnerListclasses - The
ParameterAccessinterface will need to be replaced either byItemorInnerListclasses - The
ValueAccessinterface will need to be replaced either by theItemclass
Parser Interfaces
The Parser related interfaces are completely removed, the parser is now an internal implementation detail which has no facing public API.
- public static function fromHttpValue(Stringable|string $httpValue, DictionaryParser $parser = new Parser()): self
+ public static function fromHttpValue(Stringable|string $httpValue, ?Ietf $rfc = null): self
In v2, the parser instance is replaced by an Enum that indicates which RFC should be used for parsing.
If your code did not provide any second parameter to the method then the parsing will be done using RFC9651
if you want to only consider the previous active RFC, then you will have to explicitly name it via the Ietf Enum.
Method renaming
Dictionary and Parameters container members can be accessed vi their name or via their index.
To normalize the accessor methods the following changes were introduced
1.x method name |
2.x method name |
|---|---|
Item::parameter |
Item::parameterByKey |
InnerList::parameter |
InnerList::parameterByKey |
InnerList::has |
InnerList::hasIndices |
InnerList::get |
InnerList::getIndex |
OuterList::get |
OuterList::getIndex |
OuterList::has |
OuterList::hasIndices |
Dictionary::has |
Dictionary::hasKeys |
Dictionary::get |
Dictionary::getByKey |
Dictionary::pair |
Dictionary::getByIndex |
Parameters::has |
Parameters::hasKeys |
Parameters::get |
Parameters::getByKey |
Parameters::pair |
Parameters::getByIndex |
Container::remove |
Container::removeByIndices |
Container::hasNoMember |
Container::isEmpty |
Container::hasMembers |
Container::isNotEmpty |
The Parameters::remove and Dictionary::remove methods are removed from the public API, they
were accepting indices and keys indiscriminately which may lead to subtle bugs in code.
Behaviour changes
To normalize container usage, performing foreach on a Container will always make the iteration return the an
Iterator whose offset is the member indices and the value is:
- the member value itself if the container is a list (
OuterList,InnerList) - an array with 2 entries, the first entry is the member name and the second entry, the member value. (
Dictionary,Parameters)
$headerLine = 'picture-in-picture=(), geolocation=(self "https://example.com/"), camera=*';
//the raw header line is a structured field dictionary
$permissions = DataType::Dictionary->parse($headerLine); // parse the field
In version 1:
foreach ($permissions as $offset => $member) {
//first iteration
//$offset 'picture-in-picture
//$member InnerList::new()
}
In version 2:
foreach ($permissions as $offset => $member) {
//first iteration
//$offset 0
//$member ['picture-in-picture', InnerList::new()]
}
You can access the v1 behaviour using the toAssociative method. The method
exists on the Dictionary and Parameters containers.
In version 2:
foreach ($permissions->toAssociative() as $offset => $member) {
//first iteration
//$offset 'picture-in-picture
//$member InnerList::new()
}
Auto-conversion
If the Item or the InnerList have no parameters attached to them you can now ignore the parameters value all together,
this is not possible in v1.
In version 1:
OuterList::fromPairs([
[
[['foo', []], ['bar', []]],
]
])->toHttpValue());
In version 2:
OuterList::fromPairs([
[
['foo', 'bar'],
]
])->toHttpValue());
[!NOTE] The v1 syntax is still supported.