psg / sr1
PHP SG SR-1
Requires
- php: >=7.1
This package is auto-updated.
Last update: 2024-09-17 01:25:09 UTC
README
composer require psg/sr1
class Request implements Psg\Sr1\RequestInterface{}
实现
与 FIG PSR 7 的变更比较
-
所有类现在都有工厂方法和 "create" 方法
- RequestInterface
- createRequest()
- create()
- ResponseInterface
- createResponse()
- create()
- ServerRequestInterface
- createServerReques()
- create()
- StreamInterface
- createStream()
- createStreamFromFile()
- createStreamFromResource()
- create()
- createFromFile()
- createFromResource()
- UploadedFileInterface
- createUploadedFile()
- create()
- UriInterface
- createUri()
- create()
- RequestInterface
-
Request, Response 有方法
withBodyString(string $body)
使用字符串设置体getBodyString()
获取字符串形式的体
PSR 7, 15, 17 的问题
当我查看 PSR 7, 15, 和 17 时,我意识到,为了编写替换 HTTP 响应体内容中 "bill" 为 "bob" 的中间件,我需要做以下之一
- 依赖于框架注入工厂和使用 __construct 注入(如果构造函数接受其他非自动注入的配置参数,这可能会成为问题)
- 在中间件中实现 PSR 17 工厂
- 在中间件中构建自己的 PSR 17 实现
仅仅为了替换 "bill" 为 "bob",这应该只需要一行代码(preg_replace('/bill/', 'bob', $body)),我发现这三个解决方案都不好。不仅不好,而且它们都不是标准,这意味着选择哪一个,以及如何实现,都取决于程序员,可能是可变的。
让我们看看为什么这些解决方案不好
- 对于 #1,除了假设框架使用 IoC 注入外,它还意味着如果我的中间件的构造函数看起来像
public function __construct(StreamFactory $streamFactory, UriFactory $UriFactory, $config_param1, $config_param2){}
我需要想出一种方法来在我的配置传递给框架进行自动 IoC 注入之前注入我的自定义配置。
- 对于 #2,这假设框架和用户将通过 composer 导入中间件,以便解决包依赖关系。我希望人们使用我的非常简单的中间件能够即插即用,而无需运行 composer 依赖拉取。是否可以假设中间件可以拉入外部依赖?有时可以,但在这种简单的中间件情况下,这毫无意义。
- 对于 #3,这有点愚蠢。仅仅为了完成相当于一行代码的事情,我不得不花上不知道多长时间来构建自己的、不可重用的 PSR 17 实现。
因此,我认为 PSR 7 有缺陷。PSR 7 类的本质就是工厂,因为它们在修改时返回自身的新实例,这意味着将这些类做成完整工厂的分离关注点论点是无效的。
最后,withBodyString()
方法的便利性。大多数 PHP 响应都是字符串体。然而,由于存在一些体异常长的例外情况,FIG 决定牺牲便利性并强制大家以流的形式处理体;更糟糕的是,你必须导入一个工厂才能以有意义的方式进行修改的流。因此,SR 1 有便利函数,并依赖于实现来确定它们希望如何从字符串创建流。为了与 withBodyString
平行,还提供了 getBodyString
,但它是与 (string) $response->getBody()
相同的。
为什么放弃 PSR 100-102
存在与PSR 100相关的问题,以及随后的101和102。根据观察Liskov替换原则的本质,你无法在扩展接口中提供一个扩展参数。
例如,
interface x{ public function bob(); } interface y extends x{ public function bill(); } interface Bob{ public function process(x $param); } interface Sue extends Bob{ public function process(y $param); }
苏能否替代鲍勃?苏可能接收一个x
类型的参数,并且苏可能期望一个y
类型扩展x
的功能。所以,不,苏可能无法替代鲍勃。因此,PSR 10X使用了原始的PSR 7参数。这个问题在于它需要所有交互代码都预测PSR 100或PSR 7实例。如果代码从遵循PSR 7的中间件接收PSR 7响应,那么如果代码想使用PSR 100响应功能,就必须将响应升级到PSR 100,这并不是通过一小段代码就能完成的。
因此,我决定将这些PSR 100-102重建为SR 1(根据FIG的要求改名的)。