Skip to content

Commit de77d4d

Browse files
committed
adding upgrading guide
1 parent e924132 commit de77d4d

File tree

4 files changed

+162
-2
lines changed

4 files changed

+162
-2
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "bakame/http-structured-fields",
3-
"description": "A PHP library that parses, validates and serializes HTTP structured fields according to the IETF RFCs",
3+
"description": "A PHP library that parses, validates and serializes HTTP structured fields according to RFC9561 and RFC8941",
44
"type": "library",
55
"keywords": [
66
"http",

docs/00-intro.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ composer require bakame/http-structured-fields
6060
- [Working with The Containers](04-containers.md)
6161
- [Structured Field Validation](05-validation.md)
6262
- [Interacting with the PHP Ecosystem](07-extensions.md)
63+
- [Upgrading from 1.x to 2.0](08-migration.md)

docs/07-extensions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,4 @@ To show how this can be achieved you can check the codebase from [HTTP Cache Sta
101101
which uses the interface. Of note by using this interface you can completely hide the presence of
102102
this package to your end users if needed.
103103

104-
← [Validation](05-validation.md)
104+
← [Validation](05-validation.md) | [Upgrading to v2.0](08-migration.md)

docs/08-migration.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
---
2+
title: Migrating from version 1.x
3+
order: 8
4+
---
5+
6+
# Upgrading from version 1.x to 2.0
7+
8+
`bakame/http-structured-fields 2.0` is a new major version that comes with backward compatibility breaks.
9+
This guide will help you migrate from a 2.x version to 2.0. It will only explain backward compatibility breaks,
10+
it will not present the new features,
11+
12+
## Installation
13+
14+
If you are using composer then you should update the `require` section of your `composer.json` file.
15+
16+
```php
17+
composer require bakame/http-structured-fields:^2.0
18+
```
19+
20+
This will edit (or create) your `composer.json` file.
21+
22+
## PHP version requirement
23+
24+
`bakame/http-structured-fields 2.0` requires a PHP version greater or equal to `8.1` like the previous version.
25+
26+
## Interfaces
27+
28+
### Structured Field Interfaces
29+
30+
All the Interfaces around the structured field data types are remove. So if you typehinted your code using
31+
the interfaces, you will need to replace them by their actual implementation.
32+
33+
- The `MemberOrderedMap` interface will need to be replaced either by `Dictionary` or `Parameters` classes
34+
- The `MemberList` interface will need to be replaced either by `OuterList` or `InnerList` classes
35+
- The `ParameterAccess` interface will need to be replaced either by `Item` or `InnerList` classes
36+
- The `ValueAccess` interface will need to be replaced either by the `Item` class
37+
38+
### Parser Interfaces
39+
40+
The Parser related interfaces are completely removed, the parser is now an internal implementation detail which has no
41+
facing public API.
42+
43+
```diff
44+
- public static function fromHttpValue(Stringable|string $httpValue, DictionaryParser $parser = new Parser()): self
45+
+ public static function fromHttpValue(Stringable|string $httpValue, ?Ietf $rfc = null): self
46+
```
47+
48+
In v2, the parser instance is replaced by a enum that indicates which RFC should be used for parsing.
49+
If your code did not provide any second parameter to the method then the parsing will be done using `RFC9651`
50+
if you want to only consider the previous active RFC, then you will have to explicitly name it via the `Ietf` Enum.
51+
52+
## Method renaming
53+
54+
`Dictionary` and `Parameters` container members can be accessed vi their name or via their index.
55+
To normalize the accessor methods the following changes were introduced
56+
57+
| `1.x` method name | `2.x` method name |
58+
|-------------------------------------|--------------------------------------|
59+
| `Item::parameter` | `Item::parameterByName` |
60+
| `Item::withoutParamtersByKeys` | `Item::withoutParamtersByNames` |
61+
| `InnerList::parameter` | `InnerList::parameterByName` |
62+
| `InnerList::withoutParamtersByKeys` | `InnerList::withoutParamtersByNames` |
63+
| `InnerList::has` | `InnerList::hasIndices` |
64+
| `InnerList::get` | `InnerList::getIndex` |
65+
| `OuterList::get` | `OuterList::getIndex` |
66+
| `OuterList::has` | `OuterList::hasIndices` |
67+
| `Dictionary::has` | `Dictionary::hasNames` |
68+
| `Dictionary::keys` | `Dictionary::names` |
69+
| `Dictionary::get` | `Dictionary::getByName` |
70+
| `Dictionary::removeByKeys` | `Dictionary::removeByNames` |
71+
| `Dictionary::pair` | `Dictionary::getByIndex` |
72+
| `Parameters::has` | `Parameters::hasNames` |
73+
| `Parameters::keys` | `Parameters::names` |
74+
| `Parameters::get` | `Parameters::getByName` |
75+
| `Parameters::pair` | `Parameters::getByIndex` |
76+
| `Parameters::removeByKeys` | `Parameters::removeByNames` |
77+
| `Container::remove` | `Container::removeByIndices` |
78+
| `Container::hasNoMember` | `Container::isEmpty` |
79+
| `Container::hasMembers` | `Container::isNotEmpty` |
80+
81+
The `Parameters::remove` and `Dictionary::remove` methods are removed from the public API, they
82+
were accepting `indices` and `names` indiscriminately which may lead to subtle bugs in code.
83+
84+
## Behaviour changes
85+
86+
To normalize container usage, performing `foreach` on a Container will always make the iteration return the an
87+
`Iterator` whose offset is the member indices and the value is:
88+
89+
- the member value itself if the container is a list (`OuterList`, `InnerList`)
90+
- an array with 2 entries, the first entry is the member name and the second entry, the member value. (`Dictionary`, `Parameters`)
91+
92+
```pho
93+
$headerLine = 'picture-in-picture=(), geolocation=(self "https://example.com/"), camera=*';
94+
//the raw header line is a structured field dictionary
95+
$permissions = DataType::Dictionary->parse($headerLine); // parse the field
96+
```
97+
98+
In version 1:
99+
100+
```php
101+
foreach ($permissions as $offset => $member) {
102+
//first iteration
103+
//$offset 'picture-in-picture
104+
//$member InnerList::new()
105+
}
106+
```
107+
108+
In version 2:
109+
110+
```php
111+
foreach ($permissions as $offset => $member) {
112+
//first iteration
113+
//$offset 0
114+
//$member ['picture-in-picture', InnerList::new()]
115+
}
116+
````
117+
118+
You can access the v1 behaviour using the `toAssociative` method. The method
119+
exists on the `Dictionary` and `Parameters` containers.
120+
121+
In version 2:
122+
123+
```php
124+
foreach ($permissions->toAssociative() as $offset => $member) {
125+
//first iteration
126+
//$offset 'picture-in-picture
127+
//$member InnerList::new()
128+
}
129+
````
130+
131+
## Auto-conversion
132+
133+
If the `Item` or the `InnerList` have no parameters attached to them you can now ignore the parameters value all together,
134+
this is not possible in v1.
135+
136+
In version 1:
137+
138+
```php
139+
OuterList::fromPairs([
140+
[
141+
[['foo', []], ['bar', []]],
142+
]
143+
])->toHttpValue());
144+
```
145+
146+
In version 2:
147+
148+
```php
149+
OuterList::fromPairs([
150+
[
151+
['foo', 'bar'],
152+
]
153+
])->toHttpValue());
154+
```
155+
156+
> [!NOTE]
157+
> The v1 syntax is still supported.
158+
159+
← [Extending the package functionalities](07-extensions.md) | [Intro](00-intro.md) →

0 commit comments

Comments
 (0)