PHPackages                             juliangut/negotiate - 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. [Utility &amp; Helpers](/categories/utility)
4. /
5. juliangut/negotiate

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

juliangut/negotiate
===================

Negotiation middleware

2.1(2y ago)02.8k[1 PRs](https://github.com/juliangut/negotiate/pulls)BSD-3-ClausePHPPHP ^8.0

Since Aug 8Pushed 1y ago1 watchersCompare

[ Source](https://github.com/juliangut/negotiate)[ Packagist](https://packagist.org/packages/juliangut/negotiate)[ Docs](https://github.com/juliangut/negotiate)[ GitHub Sponsors](https://github.com/juliangut)[ RSS](/packages/juliangut-negotiate/feed)WikiDiscussions master Synced 2w ago

READMEChangelog (6)Dependencies (12)Versions (10)Used By (0)

[![PHP version](https://camo.githubusercontent.com/6913801024bb6087176dec5fdb59388730a49b167cbb013222a7acbaecb48b7c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d253345253344382e302d3838393242462e7376673f7374796c653d666c61742d737175617265)](http://php.net)[![Latest Version](https://camo.githubusercontent.com/083ce81c3eafd0cd9192f20a3afdf7180ba46615b7bfb3b1ae876d542fad0c87/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6a756c69616e6775742f6e65676f74696174652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/juliangut/negotiate)[![License](https://camo.githubusercontent.com/bcfdd24ea370b418e86ccf27941e4978871a619b09b9ee23081736e08eb3392c/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6a756c69616e6775742f6e65676f74696174652e7376673f7374796c653d666c61742d737175617265)](https://github.com/juliangut/negotiate/blob/master/LICENSE)

[![Total Downloads](https://camo.githubusercontent.com/cb53589a5a7b906125f4935ac0f5eb4da8a5afed831cdff8cd463778b3561d51/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6a756c69616e6775742f6e65676f74696174652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/juliangut/negotiate/stats)[![Monthly Downloads](https://camo.githubusercontent.com/a1a68c1bff614725d2b02136a44a409169aec0e21e6b79c0bfcce4be167089c5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646d2f6a756c69616e6775742f6e65676f74696174652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/juliangut/negotiate/stats)

Negotiate
=========

[](#negotiate)

Simple and flexible negotiation middleware using [willdurand/negotiation](https://github.com/willdurand/Negotiation)

Installation
------------

[](#installation)

### Composer

[](#composer)

```
composer require juliangut/negotiate

```

Usage
-----

[](#usage)

Require composer autoload file

```
require './vendor/autoload.php';

use Jgut\Negotiate\Negotiator;
use Jgut\Negotiate\Scope\Language;
use Jgut\Negotiate\Scope\MediaType;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

$scopes = [
    new MediaType(['text/html', 'application/json'], 'text/html'),
    new Language(['en', 'es']),
];
/* @var \Psr\Http\Message\ResponseFactoryInterface $responseFactory */

$middleware = new Negotiator($scopes, $responseFactory);
$middleware->setAttributeName('negotiationProvider');

// Request handler
new class () implements RequestHandlerInterface {
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        $negotiationProvider = $request->getAttribute('negotiationProvider');

        $negotiationProvider->get('Accept-Language'); // \Negotiation\Accept
        $negotiationProvider->getAcceptLanguage(); // \Negotiation\AcceptLanguage
        $negotiationProvider->getAcceptLanguageLine(); // Negotiated language string
        $negotiationProvider->getAcceptCharset(); // null, not defined

        // ...
    }
};
```

### Scopes

[](#scopes)

Encapsulate negotiation in a context, for example media type or character set. Give it a list of priorities, and you are good to go

An optional second parameter controls behaviour if request header is empty or negotiation could not be determined successfully. If set, it will be used to create a `\Negotiation\AcceptHeader`, A `\Jgut\Negotiation\NegotiatorException` will be thrown and captured by the middleware otherwise

### Middleware

[](#middleware)

Middleware requires a list of negotiation scopes. Negotiation will take place in the middleware

- If everything goes well request will have
    - Headers of each scope overridden with negotiation result
    - An attribute with a `\Jgut\Negotiate\Provider` object with the result of the whole negotiation
- If negotiation goes south
    - A 415 response will be returned if Content-Type header negotiation fails
    - A 406 response will be returned if any other negotiation fails

Migration from 1.x
------------------

[](#migration-from-1x)

- PHP minimum required version is PHP 8.0
- Scope's default should be specified in each constructor should it be needed
- Scope's negotiateRequest now returns modified request (internal change)

Contributing
------------

[](#contributing)

Found a bug or have a feature request? [Please open a new issue](https://github.com/juliangut/negotiate/issues). Have a look at existing issues before.

See file [CONTRIBUTING.md](https://github.com/juliangut/negotiate/blob/master/CONTRIBUTING.md)

License
-------

[](#license)

See file [LICENSE](https://github.com/juliangut/negotiate/blob/master/LICENSE) included with the source code for a copy of the license terms.

###  Health Score

36

—

LowBetter than 79% of packages

Maintenance30

Infrequent updates — may be unmaintained

Popularity16

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity74

Established project with proven stability

 Bus Factor1

Top contributor holds 97.1% 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 ~343 days

Recently: every ~360 days

Total

8

Last Release

842d ago

Major Versions

0.2 → 1.02020-03-28

1.3 → 2.02023-11-08

PHP version history (5 changes)0.1PHP ^7.0

1.0PHP ^7.1

1.2PHP ^7.3|^8.0

1.3PHP ^7.4|^8.0

2.0PHP ^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/4c50421f1ab4148354dc2dd5dcaba168656b17ea913b310d112deb39a6f73ca1?d=identicon)[juliangut](/maintainers/juliangut)

---

Top Contributors

[![juliangut](https://avatars.githubusercontent.com/u/1104131?v=4)](https://github.com/juliangut "juliangut (33 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")

---

Tags

middlewarenegotiator

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/juliangut-negotiate/health.svg)

```
[![Health](https://phpackages.com/badges/juliangut-negotiate/health.svg)](https://phpackages.com/packages/juliangut-negotiate)
```

###  Alternatives

[league/uri-components

URI components manipulation library

31937.4M89](/packages/league-uri-components)[api-platform/symfony

Symfony API Platform integration

384.0M110](/packages/api-platform-symfony)[jaxon-php/jaxon-core

Jaxon is an open source PHP library for easily creating Ajax web applications

73147.2k29](/packages/jaxon-php-jaxon-core)[flarum/core

Delightfully simple forum software.

201.4M2.2k](/packages/flarum-core)[eliashaeussler/typo3-solver

Solver - Extends TYPO3's exception handling with AI generated solutions. Problems can also be solved from command line. Several OpenAI parameters are configurable and prompts and solution providers can be customized as desired.

302.1k](/packages/eliashaeussler-typo3-solver)[compwright/php-session

Standalone session implementation that does not rely on the PHP session module or the $\_SESSION global, ideal for ReactPHP applications

189.8k](/packages/compwright-php-session)

PHPackages © 2026

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