Content Negotiation tools for PHP.

Overview

Negotiation

Build Status Build status Total Downloads Latest Stable Version

Negotiation is a standalone library without any dependencies that allows you to implement content negotiation in your application, whatever framework you use. This library is based on RFC 7231. Negotiation is easy to use, and extensively unit tested!

Important: You are browsing the documentation of Negotiation 3.x+.

Documentation for version 1.x is available here: Negotiation 1.x documentation.

Documentation for version 2.x is available here: Negotiation 2.x documentation.

Installation

The recommended way to install Negotiation is through Composer:

$ composer require willdurand/negotiation

Usage Examples

Media Type Negotiation

$negotiator = new \Negotiation\Negotiator();

$acceptHeader = 'text/html, application/xhtml+xml, application/xml;q=0.9, */*;q=0.8';
$priorities   = array('text/html; charset=UTF-8', 'application/json', 'application/xml;q=0.5');

$mediaType = $negotiator->getBest($acceptHeader, $priorities);

$value = $mediaType->getValue();
// $value == 'text/html; charset=UTF-8'

The Negotiator returns an instance of Accept, or null if negotiating the best media type has failed.

Language Negotiation

<?php

$negotiator = new \Negotiation\LanguageNegotiator();

$acceptLanguageHeader = 'en; q=0.1, fr; q=0.4, fu; q=0.9, de; q=0.2';
$priorities          = array('de', 'fu', 'en');

$bestLanguage = $negotiator->getBest($acceptLanguageHeader, $priorities);

$type = $bestLanguage->getType();
// $type == 'fu';

$quality = $bestLanguage->getQuality();
// $quality == 0.9

The LanguageNegotiator returns an instance of AcceptLanguage.

Encoding Negotiation

<?php

$negotiator = new \Negotiation\EncodingNegotiator();
$encoding   = $negotiator->getBest($acceptHeader, $priorities);

The EncodingNegotiator returns an instance of AcceptEncoding.

Charset Negotiation

<?php

$negotiator = new \Negotiation\CharsetNegotiator();

$acceptCharsetHeader = 'ISO-8859-1, UTF-8; q=0.9';
$priorities          = array('iso-8859-1;q=0.3', 'utf-8;q=0.9', 'utf-16;q=1.0');

$bestCharset = $negotiator->getBest($acceptCharsetHeader, $priorities);

$type = $bestCharset->getType();
// $type == 'utf-8';

$quality = $bestCharset->getQuality();
// $quality == 0.81

The CharsetNegotiator returns an instance of AcceptCharset.

Accept* Classes

Accept and Accept* classes share common methods such as:

  • getValue() returns the accept value (e.g. text/html; z=y; a=b; c=d)
  • getNormalizedValue() returns the value with parameters sorted (e.g. text/html; a=b; c=d; z=y)
  • getQuality() returns the quality if available (q parameter)
  • getType() returns the accept type (e.g. text/html)
  • getParameters() returns the set of parameters (excluding the q parameter if provided)
  • getParameter() allows to retrieve a given parameter by its name. Fallback to a $default (nullable) value otherwise.
  • hasParameter() indicates whether a parameter exists.

Versioning

Negotiation follows Semantic Versioning.

End Of Life

1.x

As of October 2016, branch 1.x is not supported anymore, meaning major version 1 reached end of life. Last version is: 1.5.0.

2.x

As of November 2020, branch 2.x is not supported anymore, meaning major version 2 reached end of life. Last version is: 2.3.1.

Stable Version

3.x (and dev-master)

Negotiation 3.0 has been released on November 26th, 2020. This is the current stable version and it is in sync with the main branch (a.k.a. master).

Unit Tests

Setup the test suite using Composer:

$ composer install --dev

Run it using PHPUnit:

$ phpunit

Contributing

See CONTRIBUTING file.

Credits

License

Negotiation is released under the MIT License. See the bundled LICENSE file for details.

Comments
  • E_WARNING: array_map(): An error occurred while invoking the map callback

    E_WARNING: array_map(): An error occurred while invoking the map callback

    After deploying the negotiation library as part of FriendsOfSymfony/FOSRestBundle version 2.0.0 we started to get

    E_WARNING: array_map(): An error occurred while invoking the map callback

    from Negotiation\AbstractNegotiator::getBest() (27 or 28). I assume this happens because Negotiation\Accept::__construct() may throw an exception when constructed with an invalid value. This in turn seems to trigger PHP bug #55416 causing a warning to be emitted.

    I don't know which exact value seems to cause this problem as the issue is not reproducible and only happens sparsely on our live servers - most often with some Android phones.

    Can this part be rewritten somehow to circumvent PHP bug #55416? Or can the logic be implemented a little bit more tolerant to weird values coming in from web clients?

    bug 
    opened by sgehrig 26
  • Api format negotiator

    Api format negotiator

    When creating a RESTful API you'd like to be able to have a clear overview and simple configuration of which versions you (will) accept / are able to provide. In your API code you'd like to keep your versions separated in a nice way. This implementation is the result of my approach to give every version of a RESTful API their own namespace under a particular directory. This way the directory containing that namespace can be 'closed' for modification to freeze an API version and keep all code for a particular version in one place to prevent mistakes / 'fixes' which lead to broken versions.

    opened by pvankouteren 21
  • Undefined Offset Error

    Undefined Offset Error

    I'm not sure if this is an issue with my install or something else that I can help resolve. I am occasionally receiving the following error in this class:

    PHP Notice: Undefined offset: 1 in /../vendor/willdurand/negotiation/src/Negotiation/Negotiator.php on line 161

    I am using Symfony 2.4.1 with FOSRestBundle 0.13.0.

    Thanks for the help!

    bug 
    opened by jeremylivingston 16
  • Add a failing test with IE8 Accept

    Add a failing test with IE8 Accept

    Related with: https://github.com/FriendsOfSymfony/FOSRestBundle/issues/682

    Configuration read from /var/www/Negotiation/phpunit.xml.dist
    
    ............................F.................................... 65 / 98 ( 66%)
    .................................
    
    Time: 79 ms, Memory: 4.00Mb
    
    There was 1 failure:
    
    1) Negotiation\Tests\FormatNegotiatorTest::testGetBest with data set #24 ('image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, */*', array('text/html', 'application/xhtml+xml', '*/*'), 'text/html')
    Failed asserting that two strings are equal.
    --- Expected
    +++ Actual
    @@ @@
    -'text/html'
    +'image/jpeg'
    
    /var/www/Negotiation/tests/Negotiation/Tests/FormatNegotiatorTest.php:43
    
    FAILURES!
    Tests: 98, Assertions: 231, Failures: 1.
    
    bug 
    opened by entering 13
  • Does not match generic language priorities with specific Accept

    Does not match generic language priorities with specific Accept

    Given this code:

    $negotiator = new \Negotiation\LanguageNegotiator(); $language = $negotiator->getBest('en-US', array('fi','sv','en'));
    echo $language->getValue() . "\n";

    the result is "en-US", so the returned result is not among the given priorities.

    I guess this is sort of allowed by RFC2616, as it doesn't consider an available generic language resource (e.g. "en") to be a match for a requested variant (e.g. "en-US"). But I think it is rather unfortunate that getBest() returns a result that is not even available on the server...

    This is due to this line in Negotiator.php setting the default for $best: $best = reset($acceptHeaders); and when all matching fails, this is what eventually gets returned by getBest().

    I think the correct response in this case would be either "en" (though it sort of violates RFC2616), or NULL.

    If you agree with my reasoning I can produce a pull request implementing the chosen solution.

    bug 
    opened by osma 11
  • Add support for PHP 8

    Add support for PHP 8

    The biggest change to support PHP 8 is the Match class which fails due to the new match expression (match is now a reserved keyword).

    This PR also adds PHP nightly on Travis in order to run the unit tests on PHP 8. This requires an upgrade on PHPUnit to 9.3-dev which is the only version to support PHP 8. But this means PHP 7.0 - 7.2 support needs to be dropped (7.2 is in security-fix for the next 3 months only).

    An alternative option to keep support for PHP < 7.3 is to install different PHPUnit versions in Travis for each build. If you want to go that route then I'll update the PR accordingly.

    opened by pierredup 10
  • Does not work with single language

    Does not work with single language

    When youve only selected a single language in your browser (I tried it in Firefox 68) the library will not detect the language. The header sent is:

    Accept-Language: de-DE
    
    opened by crtl 10
  • BC break? - Fix for issue #81 - silently skip invalid header values coming in from clients

    BC break? - Fix for issue #81 - silently skip invalid header values coming in from clients

    silently skip invalid header values coming in from a client

    instead of throwing exceptions on invalid headers from clients, the new code silently skips these header values and continues to parse the header for a best match

    opened by sgehrig 10
  • Skip invalid headers

    Skip invalid headers

    Commit 4e4802509d599d7be6cef919c5e79b3324cb34b4 silently skips invalid headers. I want this library to catch invalid headers so I can 406. It seems silly that I should have to parse the headers again to determine if they are invalid when the library is already doing this.

    What do you think about reversing this change or adding a flag to getBest() to enable/disable this? I'm willing to implement this change.

    enhancement question 
    opened by neural-wetware 8
  • Do not compare + segments unless wildcards in either accept or priority

    Do not compare + segments unless wildcards in either accept or priority

    Fixes #93. If there are no wildcard segments in either the subtype or + segment of either the Accept header or priority, do not attempt to compare them.

    Adds more tests for #92 as well, using * subtypes in both the Accept header and priorities, to validate that different combinations work as expected.

    opened by weierophinney 7
  • InvalidMediaType exception

    InvalidMediaType exception

    Hi. From the google spiders, I get the following Accept header: text/html, image/gif, image/jpeg, *; q=0.2, */*; q=0.2 And this generate the following exception:

    Negotiation\\Exception\\InvalidMediaType(code: 0):  at /vendor/willdurand/negotiation/src/Negotiation/Accept.php:20)
    

    I think the problem is the first * that should be */*. Maybe this library should treat * as equivalent to */*?

    question 
    opened by oscarotero 7
  • Improvements to Type Hinting and Object Model

    Improvements to Type Hinting and Object Model

    This PR fixes #89 - IDEs will not complain about the use of type hints or object inheritance any more.

    I have used PHPStan set to level 5 checks to expose any ambiguous/incorrect uses of type hinting. My IDE is happy now!

    opened by g105b 1
  • Support */* for EncodingNegotiator

    Support */* for EncodingNegotiator

    Currently passing in an accept header equals */* does not work. It tells that there's no match and EncodingNegotiator::getBest() returns null instead it should return the highest prioritized available content type.

    $negotiator = new EncodingNegotiator();
    $mediaType = $negotiator->getBest('*/*', ['application/json']);
    var_dump($mediaType); // -> null, but should be 'application/json'
    
    opened by TiMESPLiNTER 1
  • Content type application/json selected incorrectly using Microsoft Edge headers

    Content type application/json selected incorrectly using Microsoft Edge headers

    Hi all,

    This was a interesting case encountered using the Microsoft Edge (41.16299.15.0) browser, which sends the following headers by default.

    Accept: text/html, application/xhtml+xml, image/jxr, */*

    When the priorities are prioritised with application/json, text/html; then the Content Negotiation will prefer the application/json response type; this should clearly prefer text/html based on the headers send by Edge.

    I worked around the issue by changing the priority from application/json, text/html => text/html, application/json. But I thought it a good idea to flag this issue.

    I've written some tests which expose this behaviour, the following is the (invalid) 'passing' test.

    array(
        array(new Accept('text/html'), new Accept('application/xhtml+xml'), new Accept('image/jxr'), new Accept('*/*')),
        array(new Accept('application/json'), new Accept('text/html')),
        array(
            new Match(1.0, 0, 0),   // application/json
            new Match(1.0, 110, 1), // text/html
            new Match(1.0, 0, 1),   // */*
        )
    )
    

    This seems to be caused by the index, but I am not exactly sure what the correct fix would be, hense the lack of a PR. My best guess is that application/xhtml+xml should not match application/json in any way, as they are radically different.

    opened by emrysal 7
  • Negotiator::getBest() return type hint?

    Negotiator::getBest() return type hint?

    To get offline source inspection (phan, Php Storm, etc.) currently I have to manually type-hint the return-type of getBest() inline - for example:

                $negotiator = new Negotiator();
    
                /** @var Accept $result */
                $result = $negotiator->getBest(
                    $request->getHeaderLine("Accept"),
                    ["application/json", "text/html"]
                );
    
                if ($result->getValue() === "application/json") {
                    // ...
                }
    

    Without the @var annotation, the if-statement will fail inspection, because the return-type of getBest() was declared as AcceptHeader rather than Accept, which appears to be the actual return-type.

    What's the purpose of the empty AcceptHeader interface?

    opened by mindplay-dk 6
  • '*' preferred over earlier specified language

    '*' preferred over earlier specified language

    Given a list of languages like:

    ['en-US' => '...', 'en-UK' => '....']

    And a language string of:

    en-US, *

    I get the value for en-UK using getBest and based on my (admittedly new) reading of the RFC suggests that I should get the 'en-US' value since it is listed first and they have the same quality factor. (Common sense suggests that is the better value.)

    Switching the accept string to be en-US, *;q=0 resolves the matter but seems either incorrect or at least unnecessary.

    Am I doing something wrong or is this a bug? It looked similar to some of the other open issues, but not quite the same. It also wasn't a problem in the 1.x release series.

    opened by brianjmiller 1
Releases(3.1.0)
  • 3.1.0(Jan 30, 2022)

    This new release should be fully compatible with PHP 8.1.

    What's Changed

    • Added: add missed fallback to generic language (in LanguageNegotiator) by @rtm-ctrlz in https://github.com/willdurand/Negotiation/pull/113
    • Fixed: invalid PHPDocs return comment by @michalbundyra in https://github.com/willdurand/Negotiation/pull/112
    • Fixed: incompatibilities with some null values for PHP 8.1 by @W0rma in https://github.com/willdurand/Negotiation/pull/114
    • Fixed: switch from travis to github actions by @willdurand in https://github.com/willdurand/Negotiation/pull/116

    New Contributors

    • @michalbundyra made their first contribution in https://github.com/willdurand/Negotiation/pull/112
    • @rtm-ctrlz made their first contribution in https://github.com/willdurand/Negotiation/pull/113
    • @W0rma made their first contribution in https://github.com/willdurand/Negotiation/pull/114

    Full Changelog:

    See https://github.com/willdurand/Negotiation/compare/3.0.0...3.1.0

    Source code(tar.gz)
    Source code(zip)
  • 3.0.0(Nov 26, 2020)

    👋 Hi! It's been a long time.

    This new major version is very similar to the 2.x version. In fact, the only main benefit is to support PHP 8, which required some changes that might be considered backward incompatible (see https://github.com/willdurand/Negotiation/pull/106).

    Upgrade should be safe and it's recommended. This library has been very stable over the years so we didn't change a lot of things between the versions 2 and 3. Have fun!

    Source code(tar.gz)
    Source code(zip)
  • 3.0.0-alpha3(May 14, 2017)

  • v2.3.1(May 14, 2017)

  • 3.0.0-alpha2(May 4, 2017)

  • v2.3.0(May 4, 2017)

  • 3.0.0-alpha1(Mar 4, 2017)

    This is the very first alpha release of the next major version of this library. This version works almost like the current major version (v2) but fixes a sort of regression for some users that could not be merged into the v2 (cf. version 2.2.1).

    💬 Everyone is encouraged to migrate to the v3.


    • Added: Implement getOrderedElements() (cf. #90)
    • Added: a third optional (boolean) parameter is now available in the getBest($header, array $priorities, $strict = false) method. This parameter allows to throw exceptions if the Accept header is incorrect (default behavior is to silently ignore this case, cf. release 2.0.3).
    Source code(tar.gz)
    Source code(zip)
  • v2.2.1(Oct 14, 2016)

    I revert the code introduced in version 2.2.0 about 2 hours after having released it because the code changed the public API, and therefore introduced a BC break. This version fixes the issue and I am going to publish a new major version for the code previously introduced in 2.2.0.

    Please use this version and not 2.2.0

    Source code(tar.gz)
    Source code(zip)
  • v2.2.0(Oct 14, 2016)

    :warning: PLEASE DO NOT USE THIS VERSION, USE 2.2.1 INSTEAD. SORRY 😕

    Added: a third optional (boolean) parameter is now available in the getBest($header, array $priorities, $strict = false) method. This parameter allows to throw exceptions if the Accept header is incorrect (default behavior is to silently ignore this case, cf. release 2.0.3).

    :warning: PLEASE DO NOT USE THIS VERSION, USE 2.2.1 INSTEAD. SORRY 😕

    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Sep 21, 2016)

  • v2.0.3(Aug 30, 2016)

  • v2.0.2(Dec 4, 2015)

    • Fixed: allow to have more than to parts (#70, #74)
    • Fixed: Accept header with '*' (#71)
    • Fixed: reduce try/catch block to getBest() method only
    Source code(tar.gz)
    Source code(zip)
  • v2.0.1(Oct 2, 2015)

  • 1.5.0(Oct 1, 2015)

  • v2.0.0(Oct 1, 2015)

  • v2.0.0-alpha1(Jul 29, 2015)

    UPDATE: Negotiation 2.0.0 has been released on October 1st, 2015.


    Hi! It's been a long time, right?

    Negotiation is stable for years now, and it works like a charm for most of the common use cases. It has been installed more than two million times. Yes! 2,000,000. That's awesome!

    However, we found tricky edge cases we could not fix easily, and our interpretation of the specification has changed over time. That is why I am proud to announce the immediate availability of Negotiation 2.0 (not entirely stable yet).

    This new version is a full rewrite, and therefore it is not backward compatible with Negotiation 1.0. However, migrating should not be too complicated as the API has been drastically simplified: there is only one single method to use now (getBest()), and different classes (Negotiator and *Negotiator) for different needs.

    Here is the first pre-release (2.0.0-alpha1) of Negotiation 2.0. Please test it, and report feedback, ideas, bugs so that we can work on providing the best content negotiation library written in PHP ever!

    Human Readable Changelog

    • Support for wildcard priorities has been removed (#49).
    • Register formats have been removed, as well as the logic to retrieve a format given a media type. Hence, isMediaRange() method has been removed. It has been considered out of scope of the library, and it will avoid missing formats, adding too many mapping formats, etc.
    • Header parsing has been improved both in term of speed, strictness, and design (for instance, it now accepts quoted parameter).
    • Support for partial media ranges has been added.
    • The overall negotiation logic has changed (#45, #48, #51).
    • More named exceptions (#50).
    • And, of course, even more tests!

    Scrutinizer Code Quality Code Coverage

    All the commits can be found here: https://github.com/willdurand/Negotiation/compare/4dd46432a0dc4a30d3aca70a95c60ed849974bab...v2.0.0-alpha1 or in #60.

    Last but not the least, THANK YOU to @neural-wetware for his huge contribution on this new major version! :yellow_heart: :blue_heart: :heart: :green_heart: :ship: :star: :star2: :blue_heart: :stars: :gift_heart:

    Let's celebrate now!

    Source code(tar.gz)
    Source code(zip)
  • 1.4.0(Jul 28, 2015)

    • Added: support PSR-4
    • Added: JSON-LD format
    • Added: new method AcceptHeader::getMediaType()
    • Added: Better detection of formats based on mime types
    • Added: Speed improvements (see #42)
    • Fixed: getValue()'s DocBlock fix
    • Fixed: doc in FormatNegotiatorInterface::getBestFormat
    Source code(tar.gz)
    Source code(zip)
  • 1.3.4(Oct 2, 2014)

    Fixed: LanguageNegotiator returns null when getBest() result does not match priorities (#38) Fixed: undefined variable: $wildcardAccept (#39)

    Source code(tar.gz)
    Source code(zip)
  • 1.2.5(Oct 2, 2014)

  • 1.3.3(May 16, 2014)

    • Fixed: check quality > 0.0 in FormatNegotiator::getBestFormat() (#29)
    • Fixed: incorrect behavior with priorities, related to IE8 Accept header (#24)
    Source code(tar.gz)
    Source code(zip)
  • 1.2.4(May 16, 2014)

  • 1.1.2(May 16, 2014)

  • 1.0.5(May 16, 2014)

  • 1.2.3(Feb 28, 2014)

  • 1.3.2(Feb 27, 2014)

  • 1.2.2(Feb 11, 2014)

  • 1.1.1(Feb 11, 2014)

  • 1.3.1(Feb 11, 2014)

  • 1.0.4(Feb 6, 2014)

  • 1.3.0(Jan 20, 2014)

    • Added: made priority matching return item from priorities in favor of headers from user agent, still backward compatible
    • Added: tests to cover a condition in LanguageNegotiator
    • Added: introduce FormatNegotiatorInterface interface
    • Added: more tests
    • Fixed: getFormat() for specific media types
    • Fixed: PHPDoc, documentation

    The LanguageNegotiator gets better with this new release!

    Special thanks to @abstrus.

    Source code(tar.gz)
    Source code(zip)
This bundle provides tools to build a complete GraphQL server in your Symfony App.

OverblogGraphQLBundle This Symfony bundle provides integration of GraphQL using webonyx/graphql-php and GraphQL Relay. It also supports: batching with

Webedia - Overblog 720 Dec 25, 2022
Laravel api tool kit is a set of tools that will help you to build a fast and well-organized API using laravel best practices.

Laravel API tool kit and best API practices Laravel api tool kit is a set of tools that will help you to build a fast and well-organized API using lar

Ahmed Esa 106 Nov 22, 2022
a tool to get Facebook data, and some Facebook bots, and extra tools found on Facebook Toolkit ++.

FACEBOOK TOOLKIT a tool to get Facebook data, and some Facebook bots, and extra tools found on Facebook Toolkit ++. Graph API Facebook. Made with ❤️ b

Wahyu Arif Purnomo 569 Dec 27, 2022
Provides tools for building modules that integrate Nosto into your e-commerce platform

php-sdk Provides tools for building modules that integrate Nosto into your e-commerce platform. Requirements The Nosto PHP SDK requires at least PHP v

Nosto 5 Dec 21, 2021
Read and write OpenAPI 3.0.x YAML and JSON files and make the content accessible in PHP objects.

php-openapi Read and write OpenAPI 3.0.x YAML and JSON files and make the content accessible in PHP objects. It also provides a CLI tool for validatin

Carsten Brandt 399 Dec 23, 2022
The maker bundle allows you to generate content elements, front end modules

Contao 4 maker bundle The maker bundle allows you to generate content elements, front end modules, event listener, callbacks and hooks using interacti

Contao 7 Aug 3, 2022
The 1Password Connect PHP SDK provides your PHP applications access to the 1Password Connect API hosted on your infrastructure and leverage the power of 1Password Secrets Automation

1Password Connect PHP SDK The 1Password Connect PHP SDK provides your PHP applications access to the 1Password Connect API hosted on your infrastructu

Michelangelo van Dam 12 Dec 26, 2022
API for Symbiota using the Lumen PHP PHP Micro-Framework By Laravel

symbiota-api API for Symbiota using the Lumen PHP PHP Micro-Framework By Laravel Laravel Lumen Official Documentation Documentation for the Lumen fram

Biodiversity Knowledge Integration Center 2 Jan 3, 2022
Facebook SDK for PHP (v6) - allows you to access the Facebook Platform from your PHP app

Facebook SDK for PHP (v6) This repository contains the open source PHP SDK that allows you to access the Facebook Platform from your PHP app. Installa

null 0 Aug 10, 2022
Single file PHP script that adds a REST API to a SQL database

PHP-CRUD-API Single file PHP script that adds a REST API to a MySQL/MariaDB, PostgreSQL, SQL Server or SQLite database. NB: This is the TreeQL referen

Maurits van der Schee 3.2k Jan 8, 2023
Simple and effective multi-format Web API Server to host your PHP API as Pragmatic REST and / or RESTful API

Luracast Restler ![Gitter](https://badges.gitter.im/Join Chat.svg) Version 3.0 Release Candidate 5 Restler is a simple and effective multi-format Web

Luracast 1.4k Dec 14, 2022
Unofficial Firebase Admin SDK for PHP

Firebase Admin PHP SDK Table of Contents Overview Installation Documentation Support License Overview Firebase provides the tools and infrastructure y

kreait 1.9k Jan 3, 2023
Simple utility and class library for generating php classes from a wsdl file.

wsdl2phpgenerator Simple WSDL to PHP classes converter. Takes a WSDL file and outputs class files ready to use. Uses the MIT license. Announcement: We

null 802 Dec 10, 2022
A PHP library to support implementing representations for HATEOAS REST web services.

Hateoas A PHP library to support implementing representations for HATEOAS REST web services. Installation Working With Symfony Usage Introduction Conf

William Durand 998 Dec 5, 2022
This PHP library will help you to work with your Pinterest account without using any API account credentials.

Pinterest Bot for PHP A PHP library to help you work with your Pinterest account without API credentials. The Pinterest API is painful: receiving an a

Sergey Zhuk 414 Nov 21, 2022
Pure PHP implementation of GraphQL Server – Symfony Bundle

Symfony GraphQl Bundle This is a bundle based on the pure PHP GraphQL Server implementation This bundle provides you with: Full compatibility with the

null 283 Dec 15, 2022
application/hal builder / formatter for PHP 5.4+

Nocarrier\Hal This is a library for creating documents in the application/hal+json and application/hal+xml hypermedia formats It requires PHP 5.4 or l

Ben Longden 204 Sep 28, 2022
PHP REST API Framework

PSX Framework About PSX is a framework written in PHP dedicated to build REST APIs. It is based on multiple components which cover many aspects of the

Apioo 121 Dec 30, 2022
A simple PHP package for sending messages to Slack, with a focus on ease of use and elegant syntax.

Slack for PHP | A simple PHP package for sending messages to Slack with incoming webhooks, focused on ease-of-use and elegant syntax. supports: PHP 7.

null 128 Nov 28, 2022