wechatpay-apiv3 / wechatpay-guzzle-middleware

微信支付 APIv3 Guzzle HTTP Client中间件(middleware)
Apache License 2.0
208 stars 46 forks source link

refs wechatpay-apiv3/wechatpay-guzzle-middleware#6, implementation th… #16

Closed TheNorthMemory closed 4 years ago

TheNorthMemory commented 4 years ago

不增加额外调整改动,仅使用 GuzzleHttp\Psr7\FnStream 来实现媒体文件上传,mac上已测试

均达预期效果。

测试环境信息如下:

php -v

PHP 7.3.11 (cli) (built: Dec 13 2019 19:21:21) ( NTS )

php -i|grep -i openssl

openssl
OpenSSL support => enabled
OpenSSL Library Version => LibreSSL 2.8.3
OpenSSL Header Version => LibreSSL 2.8.3
tpirc3 commented 4 years ago

感谢贡献,看了下实现方式,用FnStream来实现十分巧妙,确实非常厉害 👍

tpirc3 commented 4 years ago

我们在看了这份实现之后讨论了下,想到是不是也可以类似FnStream做一个实现StreamInterface接口的自定义Stream类,这个Stream里面可以有一个自定义的func,比如叫toStringForSign,专门返回用于计算签名的字符串,然后在WechatPay2Credentials中判断bodyStream对象是否是自定义Stream类的instance,或者是否有这个func,如果有的话,就调用toStringForSign,否则就走正常的(string)$bodyStream逻辑。 这个方式能够避免Guzzle后续版本可能会改变内部实现,进而有可能调用到__toString的风险,而相对Pull Request里的方式来说,缺点就是相对没有那么简洁。 @TheNorthMemory 觉得哪种方式会更好一些呢,希望能够一起讨论下 😀

TheNorthMemory commented 4 years ago

@tpirc3 确实如你所说, __toString 装饰器存在风险,其实 getSize 装饰器也一并存在风险;我刚翻看了下 GuzzleHttp\Handler\ applyBody 的代码块,逻辑处理基本有4-5年没变化了,所以可认为这俩方法的使用是安全的,至少可预见在 wechatpay-guzzle-middleware 0.x 甚至 1.x 系列内是安全的,可以放心使用。

我在实施这个实现时,也有考虑过上述风险,已经向外提供了 MediaUtil::getMeta 方法,实际在类内未使用,这个真实目的是向日志输出,方便调试;若需继承 StreamInterfaceFnStream 的功能实现,建议复用,这个作业交给你啦 😄。

另外,此方案思考及庖丁解牛过程可见这里