PHPackages                             phoneburner/http-tortilla - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. phoneburner/http-tortilla

ActiveLibrary[HTTP &amp; Networking](/categories/http)

phoneburner/http-tortilla
=========================

Set of traits that make wrapping PSR-7 objects easier.

v2.0.1(7mo ago)227.5k↑90%35MITPHPPHP ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0CI failing

Since Nov 25Pushed 4mo ago10 watchersCompare

[ Source](https://github.com/phoneburner/http-tortilla)[ Packagist](https://packagist.org/packages/phoneburner/http-tortilla)[ RSS](/packages/phoneburner-http-tortilla/feed)WikiDiscussions develop Synced 2d ago

READMEChangelog (5)Dependencies (9)Versions (6)Used By (5)

HTTP Tortilla - HTTP Message (PSR-7) Wrapper
============================================

[](#http-tortilla---http-message-psr-7-wrapper)

This library provides a simple set of traits to allow wrapping (or decoration) of various PSR-7 classes. Wrapping the classes allows easy addition of convenience methods while maintaining compatibility with code that relies on the underlying PSR interfaces.

Requirements
------------

[](#requirements)

This package will work with either v1.1 or v2.0 of the PSR-7 interfaces, but does not provide the actual implementations to be wrapped. Those can be found in other packages, e.g [`guzzlehttp/psr-7`](https://github.com/guzzle/psr7)or [Laminas Diactoros](https://github.com/laminas/laminas-diactoros).

As the traits provide the interface methods, they also *enhance* the method signatures with type hints and return values. Because of that PHP 8.2 or higher is required.

Usage
-----

[](#usage)

To add behaviour to a PSR7 object that implements `MessageInterface` or one of its subclasses `use` the matching wrapper trait, and call `setMessage($message)` to wrap the target object.

Once `setMessage($message)` is called all interface methods will be proxied to the original object. Any of those methods can be redefined, however, most usage will probably be adding *additional* convenience methods to the object.

Because most `with*()` methods will likely evolve the *wrapped* object as the method is proxied to that underlying object. To maintain the wrapping through various calls to `with*()`, `setFactory($callable)`allows a callable that returns a wrapped object when given the product of the underlying `with*()` message.

If the underlying object needs to be accessed, `getMessage()` may be used.

```
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 instance of the current class
            return new self($request);
        });
    }
}
```

Example
-------

[](#example)

Perhaps it would be convenient to access query parameters as a collection (and not the interface's `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 instance of the current class
            return new self($request);
        });
    }

    public function getQueryCollection()
    {
        return new Collection($this->getQueryParams());
    }
}
```

Or perhaps the underlying library doesn't handle parsing JSON requests:

```
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 instance 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;
    }
}
```

###  Health Score

54

—

FairBetter than 96% of packages

Maintenance70

Regular maintenance activity

Popularity30

Limited adoption so far

Community22

Small or concentrated contributor base

Maturity79

Established project with proven stability

 Bus Factor1

Top contributor holds 84.4% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~545 days

Total

5

Last Release

233d ago

Major Versions

1.0.0-rc1 → v2.0.02025-07-31

PHP version history (4 changes)1.0.0-beta1PHP ^7.1

1.0.0-rc1PHP ^7.4 || ^8.0

v2.0.0PHP ~8.2.0 || ~8.3.0 || ~8.4.0

v2.0.1PHP ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/723899?v=4)[Kevin Reeves](/maintainers/kevinreeves)[@kevinreeves](https://github.com/kevinreeves)

---

Top Contributors

[![tjlytle](https://avatars.githubusercontent.com/u/125074?v=4)](https://github.com/tjlytle "tjlytle (38 commits)")[![andysnell](https://avatars.githubusercontent.com/u/7006523?v=4)](https://github.com/andysnell "andysnell (6 commits)")[![kevinreeves](https://avatars.githubusercontent.com/u/723899?v=4)](https://github.com/kevinreeves "kevinreeves (1 commits)")

---

Tags

httpresponserequestpsrpsr-7http-message

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Type Coverage Yes

### Embed Badge

![Health badge](/badges/phoneburner-http-tortilla/health.svg)

```
[![Health](https://phpackages.com/badges/phoneburner-http-tortilla/health.svg)](https://phpackages.com/packages/phoneburner-http-tortilla)
```

###  Alternatives

[guzzlehttp/psr7

PSR-7 message implementation that also provides common utility methods

8.0k1.1B4.0k](/packages/guzzlehttp-psr7)[psr/http-message

Common interface for HTTP messages

7.0k1.1B6.9k](/packages/psr-http-message)[fig/http-message-util

Utility classes and constants for use with PSR-7 (psr/http-message)

39397.5M314](/packages/fig-http-message-util)[art4/requests-psr18-adapter

Use WordPress/Requests as a PSR-18 HTTP client

157.1k](/packages/art4-requests-psr18-adapter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
