Giter VIP home page Giter VIP logo

zend-diactoros's Introduction

zend-diactoros

Repository abandoned 2019-12-31

This repository has moved to laminas/laminas-diactoros.

Master: Build status Coverage Status Develop: Build status Coverage Status

Diactoros (pronunciation: /dɪʌktɒrɒs/): an epithet for Hermes, meaning literally, "the messenger."

This package supercedes and replaces phly/http.

zend-diactoros is a PHP package containing implementations of the PSR-7 HTTP message interfaces and PSR-17 HTTP message factory interfaces.

Documentation

Documentation is available at:

Source files for documentation are in the docs/ tree.

zend-diactoros's People

Contributors

boesing avatar ezimuel avatar fcabralpacheco avatar franzliedke avatar froschdesign avatar hannesvdvreken avatar harikt avatar heiglandreas avatar ins0 avatar koopzington avatar lcobucci avatar localheinz avatar maks3w avatar michalbundyra avatar mnapoli avatar mtymek avatar mwillbanks avatar nyholm avatar ocramius avatar oscarotero avatar pdscopes avatar pine3ree avatar samsonasik avatar sasezaki avatar seriousken avatar snapshotpl avatar stefanotorresi avatar svycka avatar weierophinney avatar xerkus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zend-diactoros's Issues

Add a TextResponse?

There is currently the base Response, but also HtmlResponse, JsonResponse, etc.

That's practical when we want to return HTML or JSON, but there is no simple TextResponse (or PlainTextResponse. That's not a huge deal, but writing a simple hello world is just plain confusing.

Example:

// Super verbose
$response = new Response();
$res = $res->withHeader('content-type', 'text/plain');
$response->getBody()->write('Hello world!');
return $response;

// Wrong content type, but at least it's simpler and shorter
return new HtmlResponse('Hello world');

Do you think it would make sense to add a new TextResponse class?

Or even simpler if we could use the base Response class to return plain text content, but the $body parameter in the constructor seems to only accept streams. Maybe it could accept a plain string? (but then how to differentiate from a stream…)

withFragment() deviates from PSR-7

Looking at the following code-part:

zend-diactoros/src/Uri.php

Lines 627 to 629 in 6eb97f2

if (! empty($fragment) && strpos($fragment, '#') === 0) {
$fragment = substr($fragment, 1);
}

PSR-7 does not say that a leading hash must be removed from the fragment. I'm not quite sure, but theoretically, an encoded leading hash sign is valid in a fragment?

MessageTrait::withHeader does not check for existing header names

Not a massive issue but when when calling withHeader there is no check for an existing header name inside $this->headers. This means that the newly Message created message could have a duplicated property. This can only occur when the added header name has a different capitalisation than the already stored header of the same name. i.e.:

// Assume there is a response message called $response
// Also assume that $response has a header set 'Content-Type' => ['application/json']
$new = $response->withHeader('Content-type', ['text/html']);

$new will have one value in the $this->headerNames map but 'Content-Type' and 'Content-type' in $this->headers.

A potential solution is to perform a $this->hasHeader($name) check and unsetting that header value if true before setting the value in $new.

UploadedFile::writeFile being called without stream

On my windows xampp system using the builtin php server, PHP_SAPI is 'cli-server'

This causes UploadedFile::moveTo to call writeFile without a stream being created resulting in

Call to a member function rewind() on a non-object for $this->stream->rewind();

If in my controller I do:

$file = $request->getUploadedFiles()['file'];
$file->getStream(); // Causes a stream to be created, otherwise get exception
$file->moveTo('someplace');

Then all is well.

The fix will be easy but I'm not sure of the reasoning behind the switch statement in moveTo. I'll be glad to submit a pull request but should moveTo() be fixed or writeFile()?

It seems like move_uploaded_file should be used if $this->file is set but there is clearly more going on.

Encoding of "null" or scalar in JsonResponse

Hey @weierophinney ,

This is more of an open question than an issue.

In JsonResponse, encoding of "null" is transformed into [].
Encoding of a string like "foo" is transformed into ["foo"].

However, by default,

json_encode(null) === "null";
json_encode("foo") === '"foo"';

I feel that the default behaviour makes more sense, and is less tricky for the user. However, I guess there must be a reason why you wrap scalar types into arrays, and null into an empty array, but I don't understand why.

For information, in other places (Symfony JsonResponse), they seem to transform null into [], but they are not wrapping scalars into arrays. I don't know why either... Any clue why the wrapping?

HeaderSecurity overhead

Ran across this while doing some performance analysis with xdebug and cachegrind.

Looks like HeaderSecurity overhead is pretty substantial:

image

Do we need this (relatively expensive) header security when constructing a request model from superglobals? Doesn't the server take care of vetting incoming requests before it dispatches PHP?

Silent no seekable stream exception

As you probably already know, prior to PHP 5.6, php://input stream is not seekable.

I would like to know why you silent this exception in __toString() method.

It seems a little bit strange. If my stream can not be rewind, i would like to know it instead of get an empty string.

Request HTTP method defaults to empty string

Discovered while digging in php-http/curl-client#14

Apparently, diactoros defaults the HTTP method when building a new Request('http://example.com') to '' (empty string). As far as I know, an empty string is not a valid HTTP method (not sure if that assumption is reflected in the HTTP spec), and therefore the initial state of a diactoros HTTP request is invalid, and should lead to an exception.

RequestTrait

::getRequestTarget()

http://tools.ietf.org/html/rfc7230#section-5.3.1

The most common form of request-target is the origin-form.
origin-form = absolute-path [ "?" query ]

The query component is optional, the path is required.
But in code if exists only query - return it

        $target = $this->uri->getPath();
        if ($this->uri->getQuery()) {
            $target .= '?' . $this->uri->getQuery();
        }
        if (empty($target)) {
            $target = '/';
        }

probably it would be correct:

        $target = $this->uri->getPath();
        if (! $target) {
            $target = '/';
        }
        if ($this->uri->getQuery()) {
            $target .= '?' . $this->uri->getQuery();
        }
        return $target;

Why init stream property in the constructor?

In the Response class constructor, the stream property gets initialized:

$this->stream = ($body instanceof StreamInterface) ? $body : new Stream($body, 'wb+');

It has no explicit property definition, which means it is public, isn't it? But its usage is not specified in the ResponseInterface of the PSR-7.

My problem is, that the Response class creates files in my project folder. Their name is the same string which i used as $body before. I am wondering how to deal with it, because if i implement some specific code to deal with the stream afterwards it will most likely not be compatible with another PSR-7 implementation.

How to pronounce "diactoros" ?

Please provide Phonetic transcription or pronounce_diactoros.mp3 link at README.

It needs for developer's communication.

SapiEmitter with big streams

Hello.
I have a use case with a big file (a mp4 video) that needs to be emitted but I get an out of memory error. This is because the body is emitted at one time with an echo:

echo $response->getBody();

Is there any reason for that? Why not emit the body as a stream? Something like:

$body = $response->getBody();
$body->rewind();

while (!$body->eof()) {
    echo $body->read(8192);
}

I can make a PR, if you like.
Thanks

Cleaner Server semantics

The Node paradigm doesn't make any sense under PHP - a Server isn't something that can stay up and process more than one request, or produce more than one response; and the implemented model doesn't support serving more than one request to begin with, since both request and response are injected at the time when Server is constructed. For one, a Server can't "listen" for anything.

Here's a greatly simplified Server implementation with semantics that correspond better with the PHP request/response life-cycle.

<?php

namespace xyz; // (ignore this)

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Zend\Diactoros\Response;
use RuntimeException;

/**
 * This class implements server semantics, e.g. processing a request and
 * producing a response, and dispatching a response to the client.
 */
class Server
{
    /**
     * @var callable
     */
    private $callback;

    /**
     * Response emitter to use; by default, uses Response\SapiEmitter.
     *
     * @var Response\EmitterInterface
     */
    private $emitter;

    /**
     * Constructor
     *
     * Given a callback, a request, and a response, we can create a server.
     *
     * @param callable $callback function (ServerRequestInterface $req, ResponseInterface $res) : ResponseInterface
     */
    public function __construct(callable $callback)
    {
        $this->callback = $callback;
    }

    /**
     * Retrieve the current response emitter.
     *
     * If none has been registered, lazy-loads a Response\SapiEmitter.
     *
     * @return Response\EmitterInterface
     */
    public function getEmitter()
    {
        if (!$this->emitter) {
            $this->emitter = new Response\SapiEmitter();
        }

        return $this->emitter;
    }

    /**
     * Set alternate response emitter to use.
     *
     * @param Response\EmitterInterface $emitter
     */
    public function setEmitter(Response\EmitterInterface $emitter)
    {
        $this->emitter = $emitter;
    }

    /**
     * Pipe a given server request through the middleware stack and produce a response.
     *
     * @param ServerRequestInterface $request
     *
     * @return ResponseInterface
     */
    public function process(ServerRequestInterface $request)
    {
        $response = new Response();

        $callback = $this->callback;

        ob_start();

        $response = $callback($request, $response);

        if (! $response instanceof ResponseInterface) {
            throw new RuntimeException("middleware returned invalid or no Response\n" . print_r($response, true));
        }

        return $response;
    }

    /**
     * Dispatch a response to the current connected HTTP client.
     *
     * @param ResponseInterface $response
     */
    public function dispatch(ResponseInterface $response)
    {
        $this->getEmitter()->emit($response);
    }
}

Processing a request and dispatching the response isn't a one-liner anymore, but it moves the dependency on Request and Response outside of Server where it belongs, enabling transaction semantics in Server, e.g. provide a Request and get a Response:

$server = new Server(new MiddlewarePipe());

$response = $server->process(ServerRequestFactory::fromGlobals());

$server->dispatch($response);

This is simpler, and should facilitate easier testing as well, since you can now process a request without actually dispatching it - this should help with integration testing on your middleware stack, assertions about expected responses etc. as the response doesn't need to be sent at all anymore. (To me, this was one of the expected benefits of the request/response abstraction, which we didn't get with this.)

I realize this is a BC break, but I think it's worth considering for version 2.0 - Node semantics seem rather inappropriate for PHP, and modeling Server-style transaction semantics is actually quite a bit simpler. (I doubt anyone will fret over the fact that your front controller script needs two lines of code instead of one.)

Note that we throw if the final result isn't ResponseInterface in process() - this was a decision about stricter request/response adherence in our environment, and it's probably stricter than what you'd want in your library.

ServerRequest

Perhaps it makes sense to pass to the constructor $attributes like $_ENV.

Cookie helpers

Working with cookies right now is rather tedious, since PSR-7 does not offer any convenience methods (because cookies are essentially headers).

How about a utility class for making cookie manipulation easier?
What should a PR contain?

Parse body for common content types?

Right now the ServerRequestFactory::fromGlobals uses $_POST for the parsed body and does not deserialize the request body for common content types (json, xml, etc). Therefore getParsedBody() always returns the contents of $_POST.

Example: If you have a request with the body {"foo": "bar"} and call getParsedBody() you get an empty array.

Is this intended/not the responsibility of the request or not implemented yet?

Serialization of Request

    public function testSerialization()
    {
        $request = new \Zend\Diactoros\Request('https://example.com', 'GET');
        $serialized = \Zend\Diactoros\Request\Serializer::toString($request);
        $unserialized = \Zend\Diactoros\Request\Serializer::fromString($serialized);
        $this->assertEquals((string)$request->getUri(), (string)$unserialized->getUri());
        $this->assertEquals($request->getHeaders(), $unserialized->getHeaders());
        $this->assertEquals($request->getRequestTarget(), $unserialized->getRequestTarget());
    }
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'https://example.com'
+'/'

Absolute-form of request-target should be used during serialization of Request object because otherwise we lose information about uri schema (https in this case).

 public function testSerialization()
    {
        $request = new \Zend\Diactoros\Request();
        $serialized = \Zend\Diactoros\Request\Serializer::toString($request);
        $unserialized = \Zend\Diactoros\Request\Serializer::fromString($serialized);
        $this->assertEquals((string)$request->getUri(), (string)$unserialized->getUri());
        $this->assertEquals($request->getHeaders(), $unserialized->getHeaders());
        $this->assertEquals($request->getRequestTarget(), $unserialized->getRequestTarget());
    }
UnexpectedValueException: Invalid request line detected

Maybe there should be another approach for serializing of Request which allows serialization of partial filled objects?

Add ImageResponse?

How about adding an Zend\Diactoros\Response\ImageResponse that supports the most common file types like JPG, GIF and PNG? How could this be archieved?

Uri::__toString adds extra delimiters

I'm finishing coding League\Url v4 and it exposed the following class in public API

Url::sameValueAs(Psr\Http\Message\UriInterface $url); 

To compare two PSR-7 UriInterface object based on their __toString method output.

I tried to make it work with Diactoros but I failed with the following edge cases URLs:

  • http:/example.com
  • http:example.com

In both cases the object is instantiated and the respective Uri components are correctly set but the __toString method adds extra path and/or authority delimiters.

Below the code to reproduce the bugs:

use Zend\Diactoros\Uri;
$url = new Uri('http:/example.com');
echo $url->__toString(); //expected http:/example.com but got http:///example.com
new Uri($url->__toString()); //throw InvalidArgumentException

The authority delimiters are added (not required according to PSR-7) and the method returns an invalid Uri.

use Zend\Diactoros\Uri;
$url = new Uri('http:example.com');
echo $url->__toString(); //expected http:example.com but got http:///example.com
new Uri($url->__toString()); //throw InvalidArgumentException

The authority delimiters and a path delimiter are added (not required according to PSR-7) and the method returns an invalid Uri.

client

is there a plan to create a client in seperate library or does one already exists?

Parsing data from PUT method in ServerRequestFactory

Hello! Is there a way parse data from PUT method? As I check from PSR-7, to get data from GET method, getQueryParams is called while for POST method is getParsedBody. Thanks in advance!

As for now, to get me going, I'm using this snippet below and changing the Content-Type header to application/x-www-form-urlencoded as a workaround:

parse_str(file_get_contents('php://input'), $parameters);

Stream as callback

Hi.
I have an application that does some heavy work and I'd like to send to the client a stream with the output of the process. I mean something like this:

use Symfony\Component\Process\Process;

function handler ($request, $response) {
    $process = new Process($command);

    $stream = new StreamCallback(function () use ($process) {
        $process->run(function ($type, $buffer) {
            echo $buffer;
            flush();
        });
    });

    return $response->withBody($stream);
);

Is there any way to do something like this?

UriInterface string / NULL handling

After a discussion (asika32764/http#1) how to handle NULL values given to UriInterface::withPath(), UriInterface::withQuery() and UriInterface::withFragment(), @asika32764 noticed that it is not consistently implemented in zend-diactoros (ex phly/http).

The psr interface (https://github.com/php-fig/http-message/blob/master/src/UriInterface.php) docblocks define

@param string $query The query string to use with the new instance.
@param string $path The path to use with the new instance.
@param string $fragment The fragment to use with the new instance.

In zend-diactoros Uri::withQuery() (https://github.com/phly/http/blob/master/src/Uri.php#L338) and Uri::withPath() (https://github.com/zendframework/zend-diactoros/blob/master/src/Uri.php#L310) require string arguments and throw exceptions when NULL is passed as an argument, while Uri::withFragment() converts NULL to string explicitly (https://github.com/phly/http/blob/master/src/Uri.php#L565).

So I wonder what is correct, to require strings only or to allow also NULL?

It seems a bit meticulous but that actually broke the interoperability of two psr7 implementations (https://github.com/asika32764/http and http://github.com/guzzle/psr7, the latter is using phly/http's Uri class).

Error handling

Me and a colleague have been working hard trying to bypass the error handler - we want to use an alternative error handler (booboo) but the middleware stack catches and handles exceptions before they can get to the error handler.

We noticed the onerror callback in $options of the FinalHandler constructor, but this gets constructed internally in MiddlewarePipe, where everything is declared private, so we had no luck attempting to extend the class in order to provide the option.

How do we turn off built-in error handling?

Output buffering in server class

@weierophinney, as discussed yesterday (still on phly/http), I'm back with example use case where Diactoros works together with ReactPHP, creating asynchronous, node-like server.

Here's React PHP-compatible Emitter class:

use React\Socket\Connection;

class Emitter implements EmitterInterface
{
    private $conn;
    public function __construct(Connection $connection)
    {
        $this->conn = $connection;
    }
    public function emit(\Psr\Http\Message\ResponseInterface $response)
    {
        $this->conn->write(ResponseSerializer::toString($response));
    }
}

As you can see, it doesn't need to worry about output buffering, it simply sends response via React's Connection object.

Now here's the main server code, returning valid HTTP response saying "Hello world!" for every request. It looks ugly (things like creating Server Request, I want cover that later, in a different PR/issue), but you should get the glimpse on the actual use case. I want to output some debugging information straight to console using echo.

$socket = new React\Socket\Server($loop);
$socket->on('connection', function (Connection $conn) {
    $conn->on('data', function ($data) use ($conn) {
    // some debugging info - it will be visible only for the first request
        echo "DEBUG: Incoming request:\n";
        echo $data;

        // create PSR-7 server request from serialized "regular" request
        $request = RequestSerializer::fromString($data);
        $serverRequest = new ServerRequest($_SERVER, [], $request->getUri(), $request->getMethod(), $request->getBody(), $request->getHeaders());

        // prepare PSR-7 response
        $response = new Response();

        // Serve PSR-7 style
        $server = new Server(function (ServerRequest $serverRequest, Response $response) {
            $response = $response->withHeader('Content-type', 'text/html');
            $response->getBody()->write("Hello world!");
            return $response;
        }, $serverRequest, $response);
        $emitter = new Emitter($conn);
        $server->setEmitter($emitter);
        $server->listen();

        // This is not visible because of ob_start() called in listen()
        echo "DEBUG: Requested path: ", $request->getUri()->getPath(), "\n";
        $conn->end();
    });
});
$socket->listen(1337);

Full, working example is here: https://github.com/mtymek/react-loop-psr7/.
You can run it from the terminal, open http://localhost:1337/ in your browser, and refresh a few times. Debugging information will be only shown once, before first call to Server::listen.

This example shows that output buffering only matters for SAPI, so it should be kept away from "general" Server class. IMO it should stay in the Emitter, keeping ob_start and ob_flush together, for code readability.

withHeader('Cookie', '...') doesn't work as expected

Well, I know the most common use-case is that cookies come already parsed by PHP, e.g. via the $_COOKIES superglobal, but... what about middleware attempting to add a 'Cookie' header?

This doesn't work as I expected, e.g.:

$request = new ServerRequest(...);

$request = $request->withHeader('Cookie', 'MY_COOKIE=VALUE');

var_dump($request->getCookieParams()); // => array()

So this part of the implementation is dependent on $_COOKIES, which means it's dependent on PHP's global request context for this feature - it's incapable of actually parsing cookies from headers.

Maybe this is by design, but in my case, it hurts. I now have to detect the cookie header and parse it myself and manually inject the result using withCookieParams() which is messy.

It's also "weird" in relation to the role of Server, which is supposed to take a ServerRequest and produce a Response - you would think - regardless of how that ServerRequest came about. So there is an indirect dependency on superglobals and ServerRequestFactory, and there's an unwritten "law" that you can't read/write cookie headers the same way you would read/write any other headers.

Maybe this disparity is inherent with the spec, I'm not sure - the spec does not say much about cookies and their relationship with headers, it's unclear to me from reading the spec how this was intended to work.

The real problem, I think, is that the PSR model has, effectively, two interfaces to the same data. If you think about the HTTP request, as it was before PHP did it's magic, it did not have a cookie collection which was separate from the header collection, it's just modeled that way, because that's the way it's modeled in PHP - but that doesn't change the fact that means we have denormalization in the model, two representations of the same properties.

Can we fix that?

Relative stream possible issue with pointers

I was looking through stream implementation. Relative stream and the stream it wraps are sharing same pointer, right?
So if we rewind wrapped stream, read on relative will return data before offset position.
Also tell() will give negative position, which is out of bounds error.

This shared pointer in streams looks extremely bug prone to me.

May be on seekable streams we should store pointer locally, set it before performing operation and record new position after doing it?

As simplified example:

public function read()
{
    $this->seek($this->position, SEEK_SET);
    $result = fread($resource, $length);
    $this->position = $this->tell();
    return $result;
}

ServerRequestFactory

This all works fine. Great.
But why all the logic is concentrated in one place?
Moreover, there is a class of Server.
I think it would be better to make a directory of the factories.
Firstly, it allows to separate each logic element in its factory.
Secondly, because I can always get in the code of the original values.
For example, Zend\Diactoros\Factory\HttpProtocolFactory:

use UnexpectedValueException;

class HttpProtocolFactory
{
    public static function make(array $server = null)
    {
        if (empty($server)) {
            $server = $_SERVER;
        }

        if (! isset($server['SERVER_PROTOCOL'])) {
            return '1.1';
        }

        $protocol = $server['SERVER_PROTOCOL'];

        if (! preg_match('#\A(?:HTTP/)?(?P<version>\d{1}\.\d+)\Z#', $protocol, $matches)) {
            throw new UnexpectedValueException(sprintf(
                'Unrecognized protocol version "%s".',
                $server['SERVER_PROTOCOL']
            ));
        }

        return $matches['version'];
    }
}

All this is true for the request method, headers, Uri, uploaded files etc

Request stack?

I'm working on converting some projects from symfony/http-foundation to PSR7.

It implements a class named RequestStack (documented here and here), which classes that span multiple requests/subrequests could use to get the current request.

Is this something that could be within the scope of this package?

ServerRequest and fragments

Hello. I'm getting this error:

Invalid path provided; must not contain a URI fragment at /var/www/asociaciondag.org/releases/20151222083807/vendor/zendframework/zend-diactoros/src/Uri.php:356)

The $_SERVER global variable has the following values:

{"REDIRECT_HTTPS":"on","REDIRECT_SSL_TLS_SNI":"dag.gal","REDIRECT_STATUS":"200","HTTPS":"on","SSL_TLS_SNI":"dag.gal","HTTP_USER_AGENT":"WordPress/4.3.1; http://www.arinspunk.gal","HTTP_HOST":"dag.gal","HTTP_ACCEPT":"*/*","HTTP_ACCEPT_ENCODING":"deflate;q=1.0, compress;q=0.5, gzip;q=0.5","SERVER_SIGNATURE":"<address>Apache/2.4.7 (Ubuntu) Server at dag.gal Port 443</address>\n","SERVER_SOFTWARE":"Apache/2.4.7 (Ubuntu)","SERVER_NAME":"dag.gal","SERVER_ADDR":"178.62.79.169","SERVER_PORT":"443","REMOTE_ADDR":"188.121.41.219","DOCUMENT_ROOT":"/var/www/asociaciondag.org/current/public","REQUEST_SCHEME":"https","CONTEXT_PREFIX":"","CONTEXT_DOCUMENT_ROOT":"/var/www/asociaciondag.org/current/public","SCRIPT_FILENAME":"/var/www/asociaciondag.org/current/public/index.php","REMOTE_PORT":"49427","REDIRECT_URL":"/es/feed2015","GATEWAY_INTERFACE":"CGI/1.1","SERVER_PROTOCOL":"HTTP/1.0","REQUEST_METHOD":"HEAD","QUERY_STRING":"","REQUEST_URI":"/es/feed2015#oscar-otero","SCRIPT_NAME":"/index.php","PHP_SELF":"/index.php","REQUEST_TIME_FLOAT":1450798110.232,"REQUEST_TIME":1450798110}

Note that the REQUEST_URI is "/es/feed2015#oscar-otero" (with fragment) so I guess this makes to fail serverRequestFactory because the path is handled with the fragment.

withPort does not accept NULL

According to PSR-7, withPort should accept NULL as a valid value

    /**
     * Return an instance with the specified port.
     *
     * This method MUST retain the state of the current instance, and return
     * an instance that contains the specified port.
     *
     * Implementations MUST raise an exception for ports outside the
     * established TCP and UDP port ranges.
     *
     * A null value provided for the port is equivalent to removing the port
     * information.
     *
     * @param null|int $port The port to use with the new instance; a null value
     *     removes the port information.
     * @return self A new instance with the specified port.
     * @throws \InvalidArgumentException for invalid ports.
     */
    public function withPort($port);

Zend Diactoros throws an InvalidArgumentException

Upload files in subarrays

Hi.
It seems that this library does not handle upload files in subarrays. For example, I have a form with this both fields:

<input type="file" name="images[big]" >
<input type="file" name="images[small]" >

On submit the form, I have a $_FILES like this:

Array
(
    [images] => Array
        (
            [name] => Array
                (
                    [big] => 14417316530_7c593bdff2_m.jpg
                    [small] => 14987901784_79fa14dacc_z.jpg
                )

            [type] => Array
                (
                    [big] => image/jpeg
                    [small] => image/jpeg
                )

            [tmp_name] => Array
                (
                    [big] => /private/var/tmp/phpuVQC7S
                    [small] => /private/var/tmp/phppe8WJs
                )

            [error] => Array
                (
                    [big] => 0
                    [small] => 0
                )

            [size] => Array
                (
                    [big] => 14377
                    [small] => 84186
                )
        )
)

On create a ServerRequest using ServerRequestFactory I have the following error:

<b>Fatal error</b>:  Uncaught exception 'InvalidArgumentException' with message 'Invalid leaf in uploaded files structure' in /Volumes/Documentos/www/psr7-test/vendor/zendframework/zend-diactoros/src/ServerRequest.php:293
Stack trace:
#0 /Volumes/Documentos/www/psr7-test/vendor/zendframework/zend-diactoros/src/ServerRequest.php(288): Zend\Diactoros\ServerRequest-&gt;validateUploadedFiles(Array)
#1 /Volumes/Documentos/www/psr7-test/vendor/zendframework/zend-diactoros/src/ServerRequest.php(288): Zend\Diactoros\ServerRequest-&gt;validateUploadedFiles(Array)
#2 /Volumes/Documentos/www/psr7-test/vendor/zendframework/zend-diactoros/src/ServerRequest.php(82): Zend\Diactoros\ServerRequest-&gt;validateUploadedFiles(Array)
#3 /Volumes/Documentos/www/psr7-test/vendor/zendframework/zend-diactoros/src/ServerRequestFactory.php(70): Zend\Diactoros\ServerRequest-&gt;__construct(Array, Array, Object(Zend\Diactoros\Uri), 'POST', 'php://input', Array)
#4 /Volumes/Documentos/www/psr7-test/proba.php(18): Zend\Diactoros\ServerRequestFactory::fromGlobals()
#5 {mai in <b>/Volumes/Documentos/www/psr7-test/vendor/zendframework/zend-diactoros/src/ServerRequest.php</b> on line <b>293</b><br />

I guess ServerRequestFactory should normalize the $_FILES array, somethink like symfony httpfoundation does

Usage doc is out of date

Hi! In my test this example returns

RuntimeException: Stream is not writable
$request = (new Zend\Diactoros\Request())
    ->withUri(new Zend\Diactoros\Uri('http://example.com'))
    ->withMethod('PATCH')
    ->withAddedHeader('Content-Type', 'application/json');

$request->getBody()->write(json_encode($data));
$response = $client->send($request);

printf("Response status: %d (%s)\n", $response->getStatusCode(), $response->getReasonPhrase());
printf("Headers:\n");
foreach ($response->getHeaders() as $header => $values) {
    printf("    %s: %s\n", $header, implode(', ', $values));
}
printf("Message:\n%s\n", $response->getBody());

This is only my problem of this chapter is out of date?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.