-
-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix of stream saving #176
Fix of stream saving #176
Conversation
The problem is in the case of multiple requests. For example, if you need use OAuth you need do several requests. |
I am not sure what behaviour this is fixing. PSR-7 defines two ways to read from a Stream instance: cast to string, or call the If you have code using PSR-7 Streams for some form of output, is there some reason you cannot cast to string to always get the full contents? Wondering if it is a behavioural error on the part of this implementation, or if it is just the fact that it is not super clear that PSR-7 has two ways to get Stream contents. Note that this PR breaks backwards compatibility and will neccessitate a major version bump for semver. As Stream instances will have the output of a number of methods changed (e.g. |
We have encountered an issue after upgrading a project. The body we send to an API is suddenly empty. Debugging it lead to this class (Stream) and stumbled upon this issue. I don't have extra context, but just wanted to say that we encountered it too :) Also I tried the code in this PR and that indeed fixed it; the request has a body again. |
I discovered the possible ways of getting response body. First way: ...
$result = (string)$response->getBody()->getContents(); // resut string will NOT be empty Second way: ...
$body = $response->getBody();
$body->rewind();
$result = $body->getContents(); // resut string will NOT be empty The problem is that if you try to read the stream data without rewind but just with That's why result is empty. This PR should fix this problem. Also I think that |
@Zegnat And here is the most basic failing test
Also this change is not really connected to psr-7 it tries to fix a problem with the psr-17 factory It's just that this library have the factory part on the And sure the specification doesn't specify if you should rewind the stream when creating it or not |
Very true. But what I am questioning is it being a problem 😉 PSR-7 does not give any guarantees that
I could have saved you some time, I already did this research, with 13 different PSR implementations, back in 2018. It was almost a 50/50 split in results. There is a full discussion on the PHP-FIG mailing list started by me, a PR under discussion to ammend PSR-17 by another contributor, and a PR to the interoperability unit tests to check for cursor positions also by me. Back in late 2018 / start 2019 we decided not to update the Nyholm/psr7 library because there was no consensus and we were hoping to get the PSR ammended instead. We would then follow wherever the PSR goes. Which would introduce a breaking change and would mean a version 2.0.0 release on our end. Maybe I need to repeat the research and see if libraries are more in favour of one solution over the other. Wondering if we should document this somewhere… But to reitterate: if you need to know the full contents of a Stream instance, you should never assume |
I would be fine with the idea of just updating the documentation. I remember being bitten by this when change implementation a couple of years ago. After that I use |
Hm. @Zegnat and I have been spending so much time telling people these exact arguments. PSR-7 nor PSR-17 does not specify this and you should never assume where the read pointer is. I think we can save us some time (and the users the headache) to just be pragmatic instead. I'll merge #177 because it has tests and a changelog entry. Thank you @Ryllaz |
`$response->getBody()->getContents()` 并不能保证拿到完整内容,PSR-7 里的原话: > Each stream instance will have various capabilities: it can be read-only, write-only, or read-write. It can also allow arbitrary random access (seeking forwards or backwards to any location), or only sequential access (for example in the case of a socket, pipe, or callback-based stream). > > Finally, StreamInterface defines a __toString() method to simplify retrieving or emitting the entire body contents at once. > -- https://www.php-fig.org/psr/psr-7/#13-streams 相关讨论: - Nyholm/psr7#176
Using rewind for correct stream reading - you can get empty body in stream_get_contents