bakame / http-structured-fields
PHP 中用于操作 HTTP 结构化字段的值
Requires
- php: ^8.1
- ext-json: *
Requires (Dev)
- bakame/aide-base32: dev-main
- friendsofphp/php-cs-fixer: ^v3.45.0
- httpwg/structured-field-tests: *@dev
- phpbench/phpbench: ^1.2.15
- phpstan/phpstan: ^1.10.50
- phpstan/phpstan-deprecation-rules: ^1.1.4
- phpstan/phpstan-phpunit: ^1.3.15
- phpstan/phpstan-strict-rules: ^1.5.2
- phpunit/phpunit: ^10.5.5
- symfony/var-dumper: ^6.4.0
README
bakame/http-structured-fields
是一个框架无关的 PHP 库,允许您根据 RFC8941 在 PHP 中解析、序列化、创建和更新 HTTP 结构化字段。
安装后,您将能够执行以下操作
use Bakame\Http\StructuredFields\DataType; use Bakame\Http\StructuredFields\Token; //1 - parsing an Accept Header $fieldValue = 'text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8'; $field = DataType::List->parse($fieldValue); $field[2]->value()->toString(); // returns 'application/xml' $field[2]->parameter('q'); // returns (float) 0.9 $field[0]->value()->toString(); // returns 'text/html' $field[0]->parameter('q'); // returns null //2 - building a retrofit Cookie Header echo DataType::List->serialize([ [ ['foo', 'bar'], [ ['expire', new DateTimeImmutable('2023-04-14 20:32:08')], ['path', '/'], [ 'max-age', 2500], ['secure', true], ['httponly', true], ['samesite', Token::fromString('lax')], ] ], ]); // returns ("foo" "bar");expire=@1681504328;path="/";max-age=2500;secure;httponly=?0;samesite=lax
系统要求
PHP >= 8.1 是必需的,但推荐使用最新稳定版本的 PHP。
安装
使用 composer
composer require bakame/http-structured-fields
文档
前言
注意
虽然此包可以解析和序列化 HTTP 值,但它不会根据任何符合性规则验证其内容。您仍然需要根据相应字段的约束执行符合性检查。内容验证不在本库的范围内,尽管您可以利用其一些功能来简化所需的验证。
解析和序列化结构化字段
基本用法
注意
新增于版本 1.2.0
要快速解析或序列化 RFC 中定义的五种(5)数据类型之一,您可以使用 DataType
枚举。除了列出可以提供给其 parse
方法的数据类型(List
、InnerList
、Parameters
、Dictionary
和 Item
)之外,您还可以提供一个表示字段文本表示的字符串或可转换为字符串的对象。如果成功,它将返回一个表示结构化字段的对象,否则将抛出异常。
$headerLine = 'bar;baz=42'; //the raw header line is a structured field item $field = DataType::Item->parse($headerLine); $field->value(); // returns Token::fromString('bar); the found token value $field->parameter('baz'); // returns 42; the value of the parameter or null if the parameter is not defined.
要补充行为,您可以使用其 serialize
方法将一个由成对值组成的可迭代结构转换为文本表示形式。
use Bakame\Http\StructuredFields\Item; use Bakame\Http\StructuredFields\DataType; echo DataType::List->serialize([ [ 'dumela lefatshe', [['a', false]] ], [ ['a', 'b', Item::fromDateString('+30 minutes')], [['a', true]] ], ]); // display "dumela lefatshe";a=?0, ("a" "b" @1703319068);a
serialize
方法是使用 create
方法将可迭代结构转换为 StructuredField
并在新生成的对象上调用其 toHttpValue
方法的快捷方式。考虑到这一点,可以重写最后一个示例。
use Bakame\Http\StructuredFields\Item; use Bakame\Http\StructuredFields\DataType; $list = DataType::List->create([ [ 'dumela lefatshe', [['a', false]] ], [ ['a', 'b', Item::fromDateString('+30 minutes')], [['a', true]] ], ]); echo $list->toHttpValue(); // display "dumela lefatshe";a=?0, ("a" "b" @1703319068);a
提示
虽然格式一开始可能会令人难以理解,但在阅读完其余文档后,您将理解它。在底层,DataType
枚举使用以下讨论的机制。
使用特定数据类型类
该包为每种数据类型提供了特定的类。解析是通过各自的 fromHttpValue
命名构造函数进行的。以下是一个使用 Item
类的方法示例
declare(strict_types=1); use Bakame\Http\StructuredFields\DataType; require 'vendor/autoload.php'; // the raw HTTP field value is given by your application // via any given framework, package or super global. $headerLine = 'bar;baz=42'; //the raw header line is a structured field item $field = Item::fromHttpValue($headerLine); $field->value(); // returns Token::fromString('bar); the found token value $field->parameter('baz'); // returns 42; the value of the parameter or null if the parameter is not defined.
提示
DataType::parse
方法使用每个特定类的 fromHttpValue
命名构造函数来生成结构化字段的 PHP 表示形式。
fromHttpValue
方法返回一个实现了 StructuredField
接口的实例。该接口提供了一个 toHttpValue
方法,该方法将其序列化为符合 RFC 的标准 HTTP 字段字符串值。为了便于集成,已实现 __toString
方法作为 toHttpValue
方法的别名。
$field = Item::fromHttpValue('bar; baz=42; secure=?1'); echo $field->toHttpValue(); // return 'bar;baz=42;secure' // on serialization the field has been normalized // the HTTP response is build by your application // via any given framework, package or PHP native function. header('foo: '. $field->toHttpValue()); //or header('foo: '. $field);
提示
这是由 DataType::serialize
方法使用的机制。一旦创建了结构化字段,该方法就会调用其 toHttpValue
方法。
RFC 中定义的所有五种(5)结构化数据类型都在 Bakame\Http\StructuredFields
命名空间中提供。它们都实现了 StructuredField
接口并公开了 fromHttpValue
命名构造函数。
项目
参数
字典
OuterList
(在 RFC 中命名为List
,但在包中重命名为list
,因为在 PHP 中list
是保留字。)内部列表
访问结构化字段值
RFC 值类型
根据RFC,项目值可以有不同的类型,可以通过以下方式在PHP中转换:
- 尽可能使用原生类型或类;
- 在包命名空间中定义的特定类来表示非原生类型;
下表总结了项目值类型。
注意
《日期》和《显示字符串》类型目前还不是任何接受的RFC的一部分。但它们已经被添加到超补丁RFC提案中的新类型中。
更多信息请参见https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-sfbis。
枚举《类型》列出所有可用类型,并可以使用《Type::fromVariable》静态方法确定与PHP结构对应的RFC类型。如果结构不被识别,则该方法将抛出异常。作为替代,可以使用《Type::tryFromVariable》,它将在未识别的类型上返回《null》。成功时,这两种方法都返回相应的枚举《Type》。
use Bakame\Http\StructuredFields\Type; echo Type::fromVariable(42)->value; // returns 'integer' echo Type::fromVariable(42.0)->name; // returns 'Decimal' echo Type::fromVariable(new SplTempFileObject()); // throws InvalidArgument echo Type::tryFromVariable(new SplTempFileObject()); // returns null
为了简化验证,公开了《Type::equals》方法来检查《Item》是否具有预期的类型。它也可以用于比较类型。
use Bakame\Http\StructuredFields\DataType; use Bakame\Http\StructuredFields\Type; $field = DataType::Item->parse('"foo"'); Type::Date->equals($field); // returns false Type::String->equals($field); // returns true; Type::Boolean->equals(Type::String); // returns false
RFC定义了三种(3)不能由PHP默认类型系统表示的特定数据类型,对于这些类型,我们定义了三个类《Token》、《ByteSequence》和《DisplayString》来帮助它们的表示。
use Bakame\Http\StructuredFields\ByteSequence; use Bakame\Http\StructuredFields\DisplayString; use Bakame\Http\StructuredFields\Token; Token::fromString(string|Stringable $value): Token ByteSequence::fromDecoded(string|Stringable $value): ByteSequence; ByteSequence::fromEncoded(string|Stringable $value): ByteSequence; DisplayString::fromDecoded(string|Stringable $value): DisplayString; DisplayString::fromEncoded(string|Stringable $value): DisplayString;
所有类都是最终的和不可变的;它们的值一旦实例化后就不能修改。要访问它们的值,它们公开以下API:
use Bakame\Http\StructuredFields\Token; use Bakame\Http\StructuredFields\ByteSequence; use Bakame\Http\StructuredFields\DisplayString; $token = Token::fromString('application/text+xml'); echo $token->toString(); // returns 'application/text+xml' $displayString = DisplayString::fromDecoded('füü'); $displayString->decoded(); // returns 'füü' $displayString->encoded(); // returns 'f%c3%bc%c3%bc' $byte = ByteSequence::fromDecoded('Hello world!'); $byte->decoded(); // returns 'Hello world!' $byte->encoded(); // returns 'SGVsbG8gd29ybGQh' $token->equals($byte); // will return false; $displayString->equals($byte); // will return false; $byte->equals(ByteSequence::fromEncoded('SGVsbG8gd29ybGQh')); // will return true $token->type(); // returns Type::Token enum $byte->type(); // returns Type::ByteSequence $displayString->type(); // returns Type::DisplayString
警告
这些类不公开《Stringable》接口,以帮助将它们与字符串或可字符串化对象区分开来。
项目
定义的类型都附加到《Item》对象上,可以使用以下方法访问它们的值和类型:
use Bakame\Http\StructuredFields\Item; use Bakame\Http\StructuredFields\Type; $item = Item::fromHttpValue('@1234567890'); $item->type(); // return Type::Date; $item->value() // return the equivalent to DateTimeImmutable('@1234567890');
容器
所有容器对象都实现了PHP的《IteratorAggregate》、《Countable》和《ArrayAccess》接口。它们的成员可以使用以下共享方法访问:
$container->keys(): array<string|int>; $container->has(string|int ...$offsets): bool; $container->get(string|int $offset): StrucuredField; $container->hasMembers(): bool; $container->hasNoMembers(): bool;
重要
如果不存在给定《$offset》的成员,则《get》方法将抛出《InvalidOffset》异常。
为了避免无效状态,如果尝试在任何容器对象上使用,则《ArrayAccess》修改方法将抛出《ForbiddenOperation》异常。
use Bakame\Http\StructuredFields\Parameters; $value = Parameters::fromHttpValue(';a=foobar'); $value->has('b'); // return false $value['a']->value(); // return 'foobar' $value['b']; // triggers a InvalidOffset exception, the index does not exist $value['a'] = 23 // triggers a ForbiddenOperation exception unset($value['a']); // triggers a ForbiddenOperation exception
《Dictionary》和《Parameters》类还允许将其成员作为对来访问。
$container->hasPair(int ...$offsets): bool; $container->pair(int $offset): array{0:string, 1:StructuredField}; $container->toPairs(): iterable<array{0:string, 1:StructuredField}>;
重要
如果不存在给定《$offset》的成员,则《pair》方法将抛出《InvalidOffset》异常。
访问参数值
使用以下方法访问附加到《InnerList》或《Item》实例的关联《Parameters》实例:
use Bakame\Http\StructuredFields\InnerList; use Bakame\Http\StructuredFields\Item; use Bakame\Http\StructuredFields\Parameters; $field->parameter(string $key): ByteSequence|Token|DisplayString|DateTimeImmutable|Stringable|string|int|float|bool|null; $field->parameters(): Parameters; $field->parameterByIndex(int $index): array{0:string, 1:ByteSequence|Token|DisplayString|DateTimeImmutable|Stringable|string|int|float|boo} InnerList::toPair(): array{0:list<Item>, 1:Parameters}>}; Item::toPair(): array{0:ByteSequence|Token|DisplayString|DateTimeImmutable|Stringable|string|int|float|bool, 1:Parameters}>};
注意
- 如果找不到给定键的值,则《parameter》方法将返回《null》。
- 《parameterByIndex》方法在《版本1.1.0》中添加,如果未找到给定索引的参数,则返回空数组。
构建和更新结构化字段值
每个值对象都可以用作构建器来创建HTTP字段值。因为我们使用不可变值对象,所以对值对象的任何更改都将返回一个新的实例,其中包含应用了更改的实例,而原始实例保持不变。
项目值
《Item》值对象公开以下命名构造函数来实例化裸项(即:没有附加参数的项)。
use Bakame\Http\StructuredFields\ByteSequence; use Bakame\Http\StructuredFields\Item; use Bakame\Http\StructuredFields\Token; Item:new(DateTimeInterface|ByteSequence|Token|DisplayString|string|int|array|float|bool $value): self Item::fromDecodedByteSequence(Stringable|string $value): self; Item::fromEncodedDisplayString(Stringable|string $value): self; Item::fromDecodedDisplayString(Stringable|string $value): self; Item::fromEncodedByteSequence(Stringable|string $value): self; Item::fromToken(Stringable|string $value): self; Item::fromString(Stringable|string $value): self; Item::fromDate(DateTimeInterface $datetime): self; Item::fromDateFormat(string $format, string $datetime): self; Item::fromDateString(string $datetime, DateTimeZone|string|null $timezone = null): self; Item::fromTimestamp(int $value): self; Item::fromDecimal(int|float $value): self; Item::fromInteger(int|float $value): self; Item::true(): self; Item::false(): self;
要更新《Item》实例值,请使用《withValue》方法。
use Bakame\Http\StructuredFields\Item; Item::withValue(DateTimeInterface|ByteSequence|Token|DisplayString|string|int|float|bool $value): static
有序映射
《Dictionary》和《Parameters》是有序映射实例。它们可以使用以下关联可迭代结构使用其键构建:
use Bakame\Http\StructuredFields\Dictionary; $value = Dictionary::fromAssociative([ 'b' => Item::false(), 'a' => Item::fromToken('bar'), 'c' => new DateTimeImmutable('2022-12-23 13:00:23'), ]); echo $value->toHttpValue(); //"b=?0, a=bar, c=@1671800423" echo $value; //"b=?0, a=bar, c=@1671800423"
或使用其索引使用RFC中定义的对(元组)的可迭代结构。
use Bakame\Http\StructuredFields\Parameters; use Bakame\Http\StructuredFields\Item; $value = Parameters::fromPairs(new ArrayIterator([ ['b', Item::false()], ['a', Item::fromToken('bar')], ['c', new DateTime('2022-12-23 13:00:23')] ])); echo $value->toHttpValue(); //;b=?0;a=bar;c=@1671800423 echo $value; //;b=?0;a=bar;c=@1671800423
如果偏好使用构建器模式,可以通过以下步骤达到相同的结果:
- 首先,使用名为构造函数的
new
创建一个Parameters
或Dictionary
实例,该构造函数返回一个没有任何成员的新实例。 - 然后,使用以下任何一种修改方法来填充它。
$map->add(string $key, $value): static; $map->append(string $key, $value): static; $map->prepend(string $key, $value): static; $map->mergeAssociative(...$others): static; $map->mergePairs(...$others): static; $map->remove(string|int ...$key): static;
如下所示:
use Bakame\Http\StructuredFields\Dictionary; use Bakame\Http\StructuredFields\Item; use Bakame\Http\StructuredFields\Token; $value = Dictionary::new() ->add('a', InnerList::new( Item::fromToken('bar'), Item::fromString('42'), Item::fromInteger(42), Item::fromDecimal(42) )) ->prepend('b', Item::false()) ->append('c', Item::fromDateString('2022-12-23 13:00:23')) ; echo $value->toHttpValue(); //b=?0, a=(bar "42" 42 42.0), c=@1671800423 echo $value; //b=?0, a=(bar "42" 42 42.0), c=@1671800423
从版本 1.1.0
开始,也可以使用 RFC 中描述的索引和配对来构建 Dictionary
和 Parameters
实例。
$pair
参数是一个元组(即:具有两个成员的列表),其中
- 第一个数组成员是参数
$key
- 第二个数组成员是参数
$value
// since version 1.1 $map->unshift(array ...$pairs): static; $map->push(array ...$pairs): static; $map->insert(int $key, array ...$pairs): static; $map->replace(int $key, array $pair): static; $map->removeByKeys(string ...$keys): static; $map->removeByIndices(int ...$indices): static;
我们可以重写前面的示例
use Bakame\Http\StructuredFields\Dictionary; use Bakame\Http\StructuredFields\Item; use Bakame\Http\StructuredFields\Token; $value = Dictionary::new() ->push( ['a', InnerList::new( Item::fromToken('bar'), Item::fromString('42'), Item::fromInteger(42), Item::fromDecimal(42) )], ['c', Item::true()] ) ->unshift(['b', Item::false()]) ->replace(2, ['c', Item::fromDateString('2022-12-23 13:00:23')]) ; echo $value->toHttpValue(); //b=?0, a=(bar "42" 42 42.0), c=@1671800423 echo $value; //b=?0, a=(bar "42" 42 42.0), c=@1671800423
注意
在重复的 keys
上,根据 RFC 逻辑合并配对值。
remove
始终接受字符串或整数作为输入。从版本 1.1
开始,如果方法提供了索引,则该方法将固定删除相应的配对。
<?php use Bakame\Http\StructuredFields\Dictionary; $field = Dictionary::fromHttpValue('b=?0, a=(bar "42" 42 42.0), c=@1671800423'); - echo $field->remove('b', 2)->toHttpValue(); // returns a=(bar "42" 42 42.0), c=@1671800423 + echo $field->remove('b', 2)->toHttpValue(); // returns a=(bar "42" 42 42.0)
如果需要更严格的方法,请使用以下新方法 removeByIndices
和/或 removeByKeys
use Bakame\Http\StructuredFields\Parameters; $field = Parameters::fromHttpValue(';expire=@1681504328;path="/";max-age=2500;secure;httponly=?0;samesite=lax'); echo $field->removeByIndices(4, 2, 0)->toHttpValue(); // returns ;path="/";secure;samesite=lax echo $field->removeByKeys('expire', 'httponly', 'max-age')->toHttpValue(); // returns ;path="/";secure;samesite=lax
自动转换
对于所有容器,为了简化实例化,以下自动转换应用于每个修改方法的成员参数。
如果提交的类型是
- 实现对象的结构化字段,则将按原样传递
- 可迭代结构,它将被转换为使用
InnerList::new
创建的InnerList
实例 - 否则,它将被转换为使用
Item::new
命名构造函数的Item
如果无法进行转换,将抛出 InvalidArgument
异常。
这意味着以下两种结构都构建了相同的对象
use Bakame\Http\StructuredFields\Dictionary; use Bakame\Http\StructuredFields\Item; use Bakame\Http\StructuredFields\Token; echo Dictionary::new() ->add('a', InnerList::new( Item::fromToken('bar'), Item::fromString('42'), Item::fromInteger(42), Item::fromDecimal(42) )) ->prepend('b', Item::false()) ->append('c', Item::fromDateString('2022-12-23 13:00:23')) ->toHttpValue() ; echo Dictionary::new() ->add('a', [Token::fromString('bar'), '42', 42, 42.0]) ->prepend('b', false) ->append('c', new DateTimeImmutable('2022-12-23 13:00:23')) ->toHttpValue() ; // both will return 'b=?0, a=(bar "42" 42 42.0), c=@1671800423
当然,也可以混合使用这两种表示法。
列表
要创建 OuterList
和 InnerList
实例,可以使用接受单个可变参数 $members
的 new
命名构造函数。
use Bakame\Http\StructuredFields\InnerList; use Bakame\Http\StructuredFields\ByteSequence; $list = InnerList::new( ByteSequence::fromDecoded('Hello World'), 42.0, 42 ); echo $list->toHttpValue(); //'(:SGVsbG8gV29ybGQ=: 42.0 42)' echo $list; //'(:SGVsbG8gV29ybGQ=: 42.0 42)'
再次强调,可以通过组合 new
命名构造函数和以下修改方法之一来使用构建器模式。
$list->unshift(...$members): static; $list->push(...$members): static; $list->insert(int $key, ...$members): static; $list->replace(int $key, $member): static; $list->remove(int ...$key): static;
如下所示
use Bakame\Http\StructuredFields\ByteSequence; use Bakame\Http\StructuredFields\InnerList; $list = InnerList::new() ->unshift('42') ->push(42) ->insert(1, 42.0) ->replace(0, ByteSequence::fromDecoded('Hello World')); echo $list->toHttpValue(); //'(:SGVsbG8gV29ybGQ=: 42.0 42)' echo $list; //'(:SGVsbG8gV29ybGQ=: 42.0 42)'
注意
新增于版本 1.2.0
也可以根据配对的可迭代结构创建一个 OuterList
。
use Bakame\Http\StructuredFields\OuterList; $list = OuterList::fromPairs([ [ ['foo', 'bar'], [ ['expire', new DateTime('2024-01-01 12:33:45')], ['path', '/'], [ 'max-age', 2500], ['secure', true], ['httponly', true], ['samesite', Token::fromString('lax')], ] ], [ 'coucoulesamis', [['a', false]], ] ]);
配对定义与使用各自的 fromPair
方法创建 InnerList
或 Item
相同。
添加和更新参数
为了简化处理附加有 Parameters
对象的实例的工作,添加了以下方法
use Bakame\Http\StructuredFields\ByteSequence; use Bakame\Http\StructuredFields\InnerList; use Bakame\Http\StructuredFields\Item; use Bakame\Http\StructuredFields\Token; //@type SfItemInput ByteSequence|Token|DateTimeInterface|string|int|float|bool Item::fromAssociative(SfItemInput $value, Parameters|iterable<string, SfItemInput> $parameters): self; Item::fromPair(array{0:SfItemInput, 1:Parameters|iterable<array{0:string, 1:SfItemInput}>} $pair): self; InnerList::fromAssociative(iterable<SfItemInput> $value, Parameters|iterable<string, SfItemInput> $parameters): self; InnerList::fromPair(array{0:iterable<SfItemInput>, Parameters|iterable<array{0:string, 1:SfItemInput}>} $pair): self;
以下示例说明了如何使用这些方法
use Bakame\Http\StructuredFields\Dictionary; use Bakame\Http\StructuredFields\Item; echo Item::fromAssociative( Token::fromString('bar'), ['baz' => 42] )->toHttpValue(), PHP_EOL; echo Item::fromPair([ Token::fromString('bar'), [['baz', 42]], ])->toHttpValue(), PHP_EOL; //both methods return `bar;baz=42`
这两个对象都提供了额外的修改方法来帮助处理参数。可以使用以下方法附加和更新关联的 Parameters
实例。
$field->addParameter(string $key, mixed $value): static; $field->appendParameter(string $key, mixed $value): static; $field->prependParameter(string $key, mixed $value): static; $field->withoutParameters(string ...$keys): static; // this method is deprecated as of version 1.1 use withoutParametersByKeys instead $field->withoutAnyParameter(): static; $field->withParameters(Parameters $parameters): static;
从版本 1.1
开始,也可以使用每个成员的索引来执行附加修改。
$field->pushParameters(array ...$pairs): static $field->unshiftParameters(array ...$pairs): static $field->insertParameters(int $index, array ...$pairs): static $field->replaceParameter(int $index, array $pair): static $field->withoutParametersByKeys(string ...$keys): static $field->withoutParametersByIndices(int ...$indices): static
$pair
参数是一个元组(即:具有两个成员的列表),其中
- 第一个数组成员是参数
$key
- 第二个数组成员是参数
$value
警告
返回值将是父类而不是 Parameters
实例
use Bakame\Http\StructuredFields\InnerList; use Bakame\Http\StructuredFields\Item; echo InnerList::new('foo', 'bar') ->addParameter('expire', Item::fromDateString('+30 minutes')) ->addParameter('path', '/') ->addParameter('max-age', 2500) ->toHttpValue(); echo InnerList::new('foo', 'bar') ->pushParameter( ['expire', Item::fromDateString('+30 minutes')], ['path', '/'], ['max-age', 2500], ) ->toHttpValue(); // both flow return the InnerList HTTP value // ("foo" "bar");expire=@1681538756;path="/";max-age=2500
高级解析用法
从版本 1.1
开始,内部解析器已公开,以便
- 解析和对象构建之间的更清晰的解耦
- 不同的解析器实现
- 改进测试中的包使用。
每个 fromHttpValue
方法签名都已更新,以接受第二个可选参数,该参数表示用于解析 HTTP 字符串表示值所需的解析器接口。
默认情况下,如果没有提供解析器,则包将默认使用包的 Parser
类,
Item::fromHttpValue(Stringable|string $httpValue, ItemParser $parser = new Parser()): Item; InnerList::fromHttpValue(Stringable|string $httpValue, InnerListParser $parser = new Parser()): InnerList; Dictionary::fromHttpValue(Stringable|string $httpValue, DictionaryParser $parser = new Parser()): Dictionary; OuterList::fromHttpValue(Stringable|string $httpValue, ListParser $parser = new Parser()): OuterList; Parameters::fromHttpValue(Stringable|string $httpValue, ParametersParser $parser = new Parser()): Parameters;
Parser
类公开以下方法,每个方法都属于不同的契约或接口。
Parser::parseValue(Stringable|string $httpValue): ByteSequence|Token|DateTimeImmutable|string|int|float|bool; Parser::parseItem(Stringable|string $httpValue): array; Parser::parseParameters(Stringable|string $httpValue): array; Parser::parseInnerList(Stringable|string $httpValue): array; Parser::parseList(Stringable|string $httpValue): array; Parser::parseDictionary(Stringable|string $httpValue): array;
一旦实例化,调用上述列出的方法就很简单了
use Bakame\Http\StructuredFields\Parser; $parser = new Parser(); $parser->parseValue('text/csv'); //returns Token::fromString('text/csv') $parser->parseItem('@1234567890;file=24'); //returns an array // [ // new DateTimeImmutable('@1234567890'), // ['file' => 24], // ]
注意
虽然提供的默认Parser
类实现了所有这些方法,但您可以根据需要只实现您需要的那些方法。
贡献
欢迎贡献,贡献将得到充分认可。请参阅CONTRIBUTING和行为准则以获取详细信息。
测试
库
- 包含一个PHPUnit测试套件
- 使用PHP CS Fixer的编码风格合规性测试套件。
- 使用PHPStan的代码分析合规性测试套件。
- 符合语言无关的HTTP结构化字段测试套件。
要运行测试,请在项目文件夹中运行以下命令。
composer test
安全性
如果您发现任何安全相关的问题,请通过电子邮件nyamsprod@gmail.com联系,而不是使用问题跟踪器。
鸣谢
归属
该包的内部解析器深受Gapple在PHP的结构化字段值上的先前工作的启发。
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。