phoneburner/http-tortilla

一组特性,使包装PSR-7对象更加容易。

1.0.0-rc1 2020-12-17 21:09 UTC

This package is auto-updated.

Last update: 2024-09-18 05:24:07 UTC


README

此库提供了一组简单的特性,允许包装(或装饰)各种PSR-7类。包装这些类可以轻松添加便利方法,同时保持与依赖底层PSR接口的代码的兼容性。

PHP 7.1

因为这些特性提供了接口方法,所以它们也用类型提示和返回值增强了方法签名。因此,需要PHP 7.1或更高版本。

用法

要将行为添加到实现了MessageInterface或其子类之一的PSR7对象,请使用匹配的包装器特性,并调用setMessage($message)来包装目标对象。

一旦调用setMessage($message),所有接口方法都将代理到原始对象。然而,任何这些方法都可以被重新定义,但大多数使用情况可能是在对象中添加额外的便利方法。

因为大多数with*()方法很可能会在代理到底层对象的方法中演变包装对象。为了通过多次调用with*()来保持包装,setFactory($callable)允许一个可调用的函数,当给定底层with*()消息的产物时,返回一个包装对象。

如果需要访问底层对象,可以使用getMessage()

class Request implements ServerRequestInterface
{
    use ServerRequestWrapper;
    
    public function __construct(ServerRequestInterface $request) 
    {
        // wrap this object, and proxy all the interface methods to it
        $this->setMessage($request); 
        
        // wrap all proxied `with*` methods in this function 
        $this->setFactory(function(ServerRequestInterface $request){
            // now `with*` will return an instnace of the current class
            return new self($request); 
        });
    }
}

示例

也许将查询参数作为集合(而不是接口的array)访问会更加方便

class Request implements ServerRequestInterface
{
    use ServerRequestWrapper;
    
    public function __construct(ServerRequestInterface $request) 
    {
        // wrap this object, and proxy all the interface methods to it
        $this->setMessage($request); 
        
        // wrap all proxied `with*` methods in this function 
        $this->setFactory(function(ServerRequestInterface $request){
            // now `with*` will return an instnace of the current class
            return new self($request); 
        });
    }
    
    public function getQueryCollection()
    {
        return new Collection($this->getQueryParams());
    }
}

或者,底层库可能无法处理解析JSON请求

class Request implements ServerRequestInterface
{
    use ServerRequestWrapper;
    
    public function __construct(ServerRequestInterface $request) 
    {
        // wrap this object, and proxy all the interface methods to it
        $this->setMessage($request); 
        
        // wrap all proxied `with*` methods in this function 
        $this->setFactory(function(ServerRequestInterface $request){
            // now `with*` will return an instnace of the current class
            return new self($request); 
        });
    }
    
    public function getParsedBody()
    {
        if ($parsed = $this->getMessage()->getParsedBody()) {
            return $parsed;
        }
        
        $decoded = json_decode($this->getBody(), true);

        if (json_last_error() == JSON_ERROR_NONE) {
            return $decoded;
        }
        
        return $parsed;
    }
}