A set of PSR-7 object decorators providing useful convenience methods

Related tags

Frameworks Slim-Http
Overview

Slim-Http

Slim PSR-7 Object Decorators

Build Status Coverage Status Total Downloads License

Installation

It's recommended that you use Composer to install this library.

$ composer require slim/http

This will install the slim/http component and all required dependencies. PHP 7.4, or newer, is required.

Tests

To execute the test suite, you'll need to install all development dependencies.

$ git clone https://github.com/slimphp/Slim-Http
$ composer install
$ composer test

Usage

The Decoration Repo Provides 3 Factories which instantiate the Decorators. They respectively return PSR-7 Compatible Interfaces.

  • DecoratedResponseFactory
  • DecoratedServerRequestFactory
  • DecoratedUriFactory

Example for Instantiating a Decorated Nyholm/Psr7 Response

<?php

use Nyholm\Psr7\Factory\Psr17Factory;
use Slim\Http\Factory\DecoratedResponseFactory;

$nyholmFactory = new Psr17Factory();

/**
 * DecoratedResponseFactory takes 2 parameters
 * @param \Psr\Http\Message\ResponseFactoryInterface which should be a ResponseFactory originating from the PSR-7 Implementation of your choice
 * @param \Psr\Http\Message\StreamFactoryInterface which should be a StreamFactory originating from the PSR-7 Implementation of your choice
 * Note: Nyholm/Psr17 has one factory which implements Both ResponseFactoryInterface and StreamFactoryInterface see https://github.com/Nyholm/psr7/blob/master/src/Factory/Psr17Factory.php
 */
$decoratedResponseFactory = new DecoratedResponseFactory($nyholmFactory, $nyholmFactory);

/**
 * @var \Slim\Http\Response $response
 * The returned variable is a Response which has methods like withJson()
 */
$response = $decoratedResponseFactory->createResponse(200, 'OK');
$response = $response->withJson(['data' => [1, 2, 3]]);

Example for Instantiating a Decorated Laminas Diactoros Response

<?php

use Laminas\Diactoros\ResponseFactory;
use Laminas\Diactoros\StreamFactory;
use Slim\Http\Factory\DecoratedResponseFactory;

$responseFactory = new ResponseFactory();
$streamFactory = new StreamFactory();

/**
 * DecoratedResponseFactory takes 2 parameters
 * @param \Psr\Http\Message\ResponseFactoryInterface which should be a ResponseFactory originating from the PSR-7 Implementation of your choice
 * @param \Psr\Http\Message\StreamFactoryInterface which should be a StreamFactory originating from the PSR-7 Implementation of your choice
 */
$decoratedResponseFactory = new DecoratedResponseFactory($responseFactory, $streamFactory);

/**
 * @var \Slim\Http\Response $response
 * The returned variable is a Response which has methods like withJson()
 */
$response = $decoratedResponseFactory->createResponse(200, 'OK');
$response = $response->withJson(['data' => [1, 2, 3]]);

Decorated Response Object Methods

The decorated ResponseInterface provides the following additional methods:

Response::withJson($data, $status, $options, $depth)

Parameter Type Description
$data mixed The data to encode
$status int The HTTP Status Code
$depth int JSON encoding max depth

Response::withFileDownload($file, $name)

Triggers the client to download the specified file.

Parameter Type Description
$file `string resource
$name `string null`
$contentType `bool string`

Response::withFile($file, $contentType)

Response with file to client

Parameter Type Description
$file `string resource
$contentType `bool string`

Response::withRedirect($url, $status)

Parameter Type Description
$url string The redirect destination url
$status int The HTTP Status Code

Response::write($data)

Parameter Type Description
$url string The data to write to the Response body

Response::isClientError()

Assert the underlying response's status code is between 400 and 500.

Response::isEmpty()

Assert the underlying response's status code is 204, 205 or 304.

Response::isForbidden()

Assert the underlying response's status code is 403.

Response::isInformational()

Assert the underlying response's status code is between 100 and 200.

Response::isOk()

Assert the underlying response's status code is 200.

Response::isNotFound()

Assert the underlying response's status code is 404.

Response::isRedirect()

Assert the underlying response's status code is 301, 302, 303, 307 or 308.

Response::isRedirection()

Assert the underlying response's status code is between 300 and 400.

Response::isServerError()

Assert the underlying response's status code is between 500 and 600.

Response::isSuccessful()

Assert the underlying response's status code is between 200 and 300.

Response::__toString()

Will return a string formatted representation of the underlying response object.

HTTP/1.1 200 OK
Content-Type: application/json;charset=utf-8

{"Hello": "World"}

Decorated ServerRequest Object Methods

The decorated ServerRequestInterface provides the following additional methods:

ServerRequest::withAttributes($attributes)

Parameter Type Description
$attributes array Attributes to be appended to the request

ServerRequest::getContentCharset()

Returns the detected charset from the Content-Type header of the underlying server request object. Returns null if no value is present.

ServerRequest::getContentType()

Returns the value from the Content-Type header of the underlying server request object. Returns null if no value is present.

ServerRequest::getContentLength()

Returns the value from the Content-Length header of the underlying server request object. Returns null if no value is present.

ServerRequest::getCookieParam($key, $default)

Parameter Type Description
$key string The attribute name
$default mixed Default value to return if the attribute does not exist

ServerRequest::getMediaType()

Returns the first detected value from the Content-Type header of the underlying server request object. Returns null if no value is present.

ServerRequest::getMediaTypeParams()

Returns an array of detected values from the Content-Type header of the underlying server request object. Returns an empty array if no values are present.

ServerRequest::getParam($key, $default)

Returns the value from key in $_POST or $_GET

Parameter Type Description
$key string The attribute name
$default mixed Default value to return if the attribute does not exist

ServerRequest::getParams()

Returns a merged associative array of the $_POST and $_GET parameters.

ServerRequest::getParsedBody()

Returns the parsed body from the underlying server request object if it already has been parsed by the underlying PSR-7 implementation. If the parsed body is empty, our decorator attempts to detect the content type and parse the body using one of the registered media type parsers.

The default media type parsers support:

  • JSON
  • XML

You can register your own media type parser using the ServerRequest::registerMediaTypeParser() method.

ServerRequest::getParsedBodyParam($key, $default)

Returns the value from key in the parsed body of the underlying server request object.

Parameter Type Description
$key string The attribute name
$default mixed Default value to return if the attribute does not exist

ServerRequest::getQueryParam($key, $default)

Returns the value from key in the parsed ServerRequest query string

Parameter Type Description
$key string The attribute name
$default mixed Default value to return if the attribute does not exist

ServerRequest::getServerParam($key, $default)

Returns the value from key in parsed server parameters from the underlying underlying server request object.

Parameter Type Description
$key string The attribute name
$default mixed Default value to return if the attribute does not exist

ServerRequest::registerMediaTypeParser($key, $default)

Returns the value from key in parsed server parameters from the underlying server request object.

Parameter Type Description
$mediaType string A HTTP media type (excluding content-type params)
$callable callable A callable that returns parsed contents for media type

ServerRequest::isMethod($method)

Parameter Type Description
$method string The method name

ServerRequest::isDelete()

Asserts that the underlying server request's method is DELETE

ServerRequest::isGet()

Asserts that the underlying server request's method is GET

ServerRequest::isHead()

Asserts that the underlying server request's method is HEAD

ServerRequest::isOptions()

Asserts that the underlying server request's method is OPTIONS

ServerRequest::isPatch()

Asserts that the underlying server request's method is PATCH

ServerRequest::isPost()

Asserts that the underlying server request's method is POST

ServerRequest::isPut()

Asserts that the underlying server request's method is PUT

ServerRequest::isXhr()

Asserts that the header X-Requested-With from the underlying server request is XMLHttpRequest

Decorated Uri Object Methods

The decorated UriInterface provides the following additional methods:

Uri::getBaseUrl()

Returns the fully qualified base URL of the underlying uri object.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover security related issues, please email [email protected] instead of using the issue tracker.

Credits

License

This component is licensed under the MIT license. See License File for more information.

Comments
  • [Discussion] Should we use an existing PSR-7 Implementation?

    [Discussion] Should we use an existing PSR-7 Implementation?

    We have been going back and forth a lot on PSR-7 Compliance and some issues that are related to our current implementation of PSR-7.

    I believe that we should decorate an existing implementation of PSR-7 instead of implementing our own. I would like all contributors to vote on this so we can move forward with some of the current issues.

    This repo will essentially become a decorated implementation of an existing PSR-7 implementation.

    There are 2 implementations that come to mind:

    • Nyholm/psr7 - This is the fastest, strictest and most lightweight implementation at the moment
    • Guzzle/psr7 - This is the implementation used by the Guzzle Client. It is not as strict but adds some nice functionality for Streams and file handling. It is the second fastest implementation but is a bit bulkier
    • zend-diactoros - This is the Zend implementation. It is the slowest implementation of the 3.

    I'm in favor of dropping our PSR-7 Implementation altogether and creating a PSR-7 Decorator repo which will work with any PSR-7 implementation (Nyholm, Guzzle, Diactoros).

    Vote Count

    • Nyholm/psr7 - 1 in favor
    • Guzzle/psr7 - 2 in favor
    • Zend Diactoros - 0 in favor
    • Keep current implementation - 1 in favor
    • Transform this into a PSR-7 Decorator Repo - 5 in favor

    Edit The more we talk about this, the more this thread is heading towards not including any PSR-7 implementation with Slim/Slim and have the user pass in PSR-7 objects of their choice into App::run($req, $res). Slim-Http could be transformed into a Slim-Psr7-Decorator which will work with any PSR-7 implementation. Objects passed into App::run() will be decorated by default with our decorators, an option which could be turned off in App settings.

    Slim 4 discussion 
    opened by l0gicgate 28
  • Http-Factory

    Http-Factory

    I just tried to implement the PSR-17 interfaces for Slim-Http addressing #1. I copied some of the existing static methods, such as Request::createFromGlobals(). Maybe we could even call them inside the factories - else not we should remove them. This is still not done as the classes needs some tests and there still is a todo in the ServerRequestFactory. I just wanted to leave this here to get a review before I waste additional hours, and to start a discussion wheter we should implement them here or in an additional package.

    • [x] Write some tests
    • [x] call static methods or remove them
    • [x] fix the todo in ServerRequestFactory
    • [x] ...
    opened by danopz 22
  • getParsedBody() not working in slim v4

    getParsedBody() not working in slim v4

    In https://github.com/slimphp/Slim-Http/blob/master/src/ServerRequest.php#L165

            $parsedBody = $this->serverRequest->getParsedBody();
            if ($parsedBody !== null) {
                return $parsedBody;
            }
    

    The $parsedBody is checked against null. When a POST request is received with Content-Type: application/json the php server will set $_POST to an empty array.

    In https://github.com/Nyholm/psr7-server/blob/master/src/ServerRequestCreator.php#L54 https://github.com/Nyholm/psr7-server/blob/master/src/ServerRequestCreator.php#L75

    The serverRequest $parsedBody is initialized to the empty array and fails the check above so no parsed body data is returned from $request->getParsedBody();.

    opened by esetnik 14
  • [WIP] Add Response::withFile() method

    [WIP] Add Response::withFile() method

    This PR addresses the issue https://github.com/slimphp/Slim-Http/issues/82.

    Question: What is the best way for a user to change the file name of the download (Content-Disposition)?

    1. Pass the file name as optional param.
    2. Let the user overwrite the Content-Disposition header after calling this method.
    3. Pass an optional config param (of class FileResponseConfig) to the method which would contain the file name. This allows other configs as well - for example the desired Content-Type, or whether the disposition is attachment or inline.

    So far I think the following configs should be possible:

    • Content type(s) If null, the method should try to guess the mime-type from the file name. Fallback is application/octet-stream.
    • Content Disposition Either inline or attachment. Defaults to attachment.
    • Auto ETag If true, the method would set an HTTP ETag header automatically.
    • Auto Last Modified If true, the method would set the Last-Modified header based on the filemtime.
    • File Name If not null, this should be used as file name in the Content-Disposition header. Defaults to the file name of the file given to the method.

    Not sure about this config (found in Silex code mentioned in the original issue https://github.com/slimphp/Slim/issues/2536):

    • Fallback File Name A fallback file name, containing only ASCII characters. Defaults to an automatically encoded file name.

    Note
    Currently there are no unit tests for this method.

    opened by adriansuter 14
  • Ensure headers are consistent

    Ensure headers are consistent

    • Ensure that our headers implementation is completely compliant with PSR-7
    • Ensure that getHeader() and getHeaders() are consistent. See https://github.com/slimphp/Slim/issues/2400
    opened by akrabat 11
  • Response::withFile() and Response::withFileDownload()

    Response::withFile() and Response::withFileDownload()

    Resuming to adopt the proposed direction in #88

    New Response Methods:

    • Response::withFile($file, $contentType)
    • Response::withFileDownload($file, $name, $contentType)

    Behavior The $file parameter can be a string which points to a file, an existing resource handle or a StreamInterface as proposed by @roxblnfk

    The $name parameter overrides the default attachment value for the Content-Disposition header. The given $name is filtered through urlencode() to ensure it is a valid header value.

    The $contentType parameter accepts a string to override the Content-Type header to a user defined value. Defaults to true which attempts to detect the mime type via mime_content_type() and falls back to application/octet-stream otherwise. If set to false the Content-Type header is not appended at all.

    Closes #82

    opened by l0gicgate 9
  • Refactor Request Media Parsers

    Refactor Request Media Parsers

    Should these be moved to a static registry inside the Request class? This would make it easier to inject custom parsers... e.g., \Slim\Http\Request::addParser('text/csv', function ($input) { ... });

    opened by codeguy 8
  • New tagged release

    New tagged release

    Hello Slim maintainer team!

    We're making use of the new Slim Framework 4.x alongside Slim-Http, and in particular we've needed to take advantage of a few of the changes that have been made in the last few months since the last tagged release back in May.

    I was curious if there is a roadmap for the next tagged release, or if another one can be dropped in by the team, just so we're not sitting on dev-master, which always gives me a sketchy feeling deep inside.

    If there's anything we outsider folks can do to help contribute toward that end, let me know as well. Happy to help. :)

    opened by BusterNeece 6
  • Update minimum php version to 7.0.0

    Update minimum php version to 7.0.0

    Fixes #58

    Updates the minimum version requirement to PHP >= 7.0.0.

    Also fixes some of the broken unit tests in PHP 7.1 and higher. These were due to two problems:

    1. The way the temp files were created to test uploaded files used tmpfile() which creates a resource, instead of a file name. fopen() no longer allows resources to be passed in. An alternative way to handle this would be to check for a resource and to use it directly, instead of calling fopen(), however we wouldn't be able to guarantee that the w flag was used. Opted to just fix how tests were written to use file names instead.
    2. In URL creation empty checks were using falsy checks, which matched "0" as well. Updated to use exact !== '' checks instead.
    opened by dbtlr 6
  • Psr7 integration tests

    Psr7 integration tests

    Added php-http/psr7-integration-tests for testing our implementation. Fixed the only failing part right now - Host in Uri must be lowercase as of

    The value returned MUST be normalized to lowercase, per RFC 3986

    closes #31

    opened by danopz 5
  • PHP 8 support

    PHP 8 support

    This PR allows Slim to be installed in PHP 8 and passes all the tests and checks.

    See also https://github.com/slimphp/Slim/pull/3015 and https://github.com/slimphp/Slim-Psr7/pull/169 for corresponding changes.

    The same questions apply here:

    • I implemented disableXmlEntityLoader as a private static method. Is this okay? I thought about making it protected or extracting it to a class, but I'm unsure about creating new "contracts".
    • Coverage – conditional call to libxml_disable_entity_loader. Is it okay to just @codeCoverageIgnore some part that will only run in PHP 7 or PHP 8? How should situations like this be handled?

    Dependencies: all dependencies have PHP 8-compatible releases now!

    • [x] https://github.com/laminas/laminas-diactoros/pull/46
    opened by edudobay 4
  • ServerRequest getQueryParams doesn't allow to unset all QueryParams using withQueryParams

    ServerRequest getQueryParams doesn't allow to unset all QueryParams using withQueryParams

    Hi,

    I have a middleware which parses the lang query parameter and set's the language in the container. Afterwards it removes the lang parameter from the query array and gives this new request to the next handler. This works aslong as you have at least another query parameter.

    if you don't have a query parameter this psr-7 implementation automatically parses Uri directly.

        public function __invoke(Request $request, RequestHandler $handler): Response
        {
            $query = $request->getQueryParams();
    
            // do somthing with the $query['lang] entry
    
            // cleanup Parameters
            unset($query['lang']);
            $request = $request->withQueryParams($query);
    
            return $handler->handle($request);
        }
    

    When I later validate the request for "unwanted" parameters with something like:

    public function __invoke(Request $request, Response $response)
    {
      $params = $request->getQueryParams();
      if (isset($params['lang'])) {
        // throw exception or what ever.
      }
    }
    

    The $params has the lang parameter set again because of this line https://github.com/slimphp/Slim-Http/blob/master/src/ServerRequest.php#L220

    Not sure why slim/http does it this way but I think it's wrong, because then Request::withQueryParams([]) is pretty useless and doesn't work.

    Not sure if there is a workaround...

    thanks

    opened by HLeithner 0
  • add charset=utf-8 to withJson response

    add charset=utf-8 to withJson response

    Requesting the addition of a charset with the withJson response. This PR sets it to uff-8; maybe a parameter with a default value would be preferable.

    opened by pzzd 4
  • A way to disable some automatic body parsing

    A way to disable some automatic body parsing

    Hello, Is it possible to disable automatic request parsing?

    At least in version 3 it parses like this:

    JSON requests are converted into associative arrays with json_decode($input, true). XML requests are converted into a SimpleXMLElement with simplexml_load_string($input). URL-encoded requests are converted into a PHP array with parse_str($input).

    But I don't have installed the xml extension or have the functions disabled for security reasons. When an attacker sends a xml requests it wants to parse and I get an error like:

    Call to undefined function Slim\Http\simplexml_load_string() on /var/www/website/vendor/slim/slim/Slim/Http/Request.php at 230

    I would like to choose what parsing is done from these 3 options.

    opened by cypherbits 7
  • Question: rewind() after pulling ServerRequest body contents?

    Question: rewind() after pulling ServerRequest body contents?

    I've noticed that in the decorated ServerRequest, when calling getParsedBody, the original body is pulled via (string)$request->getBody(), but the StreamInterface is not rewind-ed after the fact.

    In my tests, this means that any call to $request->getBody()->getContents() that takes place after that call happens have the internal stream pointer moved to the end of the input stream, and thus pulls basically always nothing.

    I'm not sure if this is just a natural and intended byproduct of how PSR-7's StreamInterface works, or if this is something that could be worked around at this level.

    opened by BusterNeece 1
  • Documentation?

    Documentation?

    Unfortunately I have not found a documentation nor any best-practices on how to use this library with slim 4. The README explains the instantiation process only.

    In a test installation I used it in the route callable (an invokable class) the following way - is that correct?

    // .... strict types and namespace
    
    use Slim\Http\Response;
    use Slim\Http\ServerRequest;
    
    class HomeController
    {
        public function __invoke(ServerRequest $request, Response $response, array $args = []): Response
        {
            return $response->withJson(['foo' => 'bar']);
        }
    }
    

    Am I loosing anything by directly typehinting Slim\Http\ServerRequest and Slim\Http\Response for the first two params?

    The documentarion should mention that after installation (which works out-of-the-box), the first two arguments of the route callables would be decorated. I assume the same holds for the middleware $request param and for $response in the middleware code $response = $handler->handle($request);.

    opened by adriansuter 4
Releases(1.2.0)
Owner
Slim Framework
Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs.
Slim Framework
A set of ready-made regex helper methods for use in your Laravel application.

Regex A set of ready-made regex helper methods for use in your Laravel application. Installation composer require hotmeteor/regex Usage Regex comes wi

Adam Campbell 231 Sep 20, 2022
PSR Log - This repository holds all interfaces/classes/traits related to PSR-3.

PSR Log This repository holds all interfaces/classes/traits related to PSR-3. Note that this is not a logger of its own. It is merely an interface tha

PHP-FIG 10k Sep 23, 2022
Yii2 console application used to write our processors of methods to responsible to client calling.

Microservice Application Skeleton Yii2 console application used to write our processors of methods to responsible to client calling. This application

Jafaripur 0 Mar 10, 2022
🐘🎓📝 PHP Library providing an easy way to spellcheck multiple sources of text by many spellcheckers

PHP-Spellchecker Check misspellings from any text source with the most popular PHP spellchecker. About PHP-Spellchecker is a spellchecker abstraction

Philippe SEGATORI 245 Sep 19, 2022
It validates PSR-7 messages (HTTP request/response) against OpenAPI specifications

NOTICE - THE PACKAGE HAS BEEN CONTRIBUTED TO THE PHP LEAGUE Go to https://github.com/thephpleague/openapi-psr7-validator This package is here for exis

Dmitry Lezhnev 168 Jul 18, 2022
PSR-15 Adapter for InertiaJS

inertia-psr15 Before using this library, is important to know what is Inertia.js, what is it for and how it works, in the official Inertia.js website

Mohamed Cherif Bouchelaghem 27 Aug 18, 2022
PSR-7 HTTP message library

PSR-7 Message Implementation This repository contains a full PSR-7 message implementation, several stream decorators, and some helpful functionality l

Guzzle 7.6k Sep 26, 2022
Strict PSR-7 implementation used by the Slim Framework

Strict PSR-7 implementation used by the Slim Framework, but you may use it separately with any framework compatible with the PSR-7 standard.

Slim Framework 91 Jul 6, 2022
Spiral Framework is a High-Performance PHP/Go Full-Stack framework and group of over sixty PSR-compatible components

Spiral HTTP Application Skeleton Spiral Framework is a High-Performance PHP/Go Full-Stack framework and group of over sixty PSR-compatible components.

Spiral Scout 142 Sep 13, 2022
The package provides definition syntax. Definition is describing a way to create and configure a service or an object.

Yii Definitions The package ... Requirements PHP 7.4 or higher. Installation The package could be installed with composer: composer require yiisoft/de

Yii Software 6 Jul 15, 2022
An Hydrator class that can be used for filling object from array and extracting data from objects back to arrays.

Hydrator namespace: Meow\Hydrator Library that can hydrate (fill object with data from array) and extract data from object back to array. Installation

Meow 2 Feb 3, 2022
A set of shady Slim Framework middlewares that can solve some annoyances...

Shady A set of shady Slim Framework middlewares that can solve some annoyances... What does it contain? Available middlewares: ApacheVirtualHostFix Ur

Jan-Age Laroo 7 Jun 22, 2021
A simple and flexible PHP middleware dispatcher based on PSR-7, PSR-11, and PSR-15

Woohoo Labs. Harmony Woohoo Labs. Harmony is a PSR-15 compatible middleware dispatcher. Harmony was born to be a totally flexible and almost invisible

Woohoo Labs. 153 Sep 5, 2022
A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package.

Net A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package. Features: No hard dependencies; Favours

Minibase 16 Jun 7, 2022
A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package.

Net A small, modern, PSR-7 compatible PSR-17 and PSR-18 network library for PHP, inspired by Go's net package. Features: No hard dependencies; Favours

Minibase 16 Jun 7, 2022
This package provides some basic methods to implement a self updating functionality for your Laravel application. Already bundled are some methods to provide a self-update mechanism via Github or some private repository via http.

This package provides some basic methods to implement a self updating functionality for your Laravel 5 application. Already bundled are some methods to provide a self-update mechanism via Github.

Holger Lösken 268 Sep 21, 2022
Smart File System - Use SmartFileInfo with useful methods that you need everyday

Smart File System - Use SmartFileInfo with useful methods that you need everyday

null 75 Apr 20, 2022
An opinionated extension package for Laravel Orchid to extend its table handling capabilities, and some further useful helper methods.

OrchidTables An opinionated extension package for Laravel Orchid to extend its table handling capabilities, and some further useful helper methods. In

null 20 Aug 25, 2022
Composer package providing HTTP Methods, Status Codes and Reason Phrases for PHP

HTTP Enums For PHP 8.1 and above This package provides HTTP Methods, Status Codes and Reason Phrases as PHP 8.1+ enums All IANA registered HTTP Status

Alexander Pas 71 Jul 20, 2022