Skip to content

Commit 84e7017

Browse files
committed
#41: Support PSR-18
1 parent 8ac288b commit 84e7017

20 files changed

+543
-555
lines changed

composer.json

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
{
22
"name": "php-http/curl-client",
3-
"description": "cURL client for PHP-HTTP",
3+
"description": "PSR-18 cURL client",
44
"license": "MIT",
5-
"keywords": ["http", "curl"],
5+
"keywords": [
6+
"curl",
7+
"http",
8+
"psr-18"
9+
],
610
"homepage": "http://php-http.org",
711
"authors": [
812
{
@@ -12,23 +16,20 @@
1216
],
1317
"prefer-stable": true,
1418
"minimum-stability": "dev",
15-
"config": {
16-
"bin-dir": "vendor/bin"
17-
},
1819
"require": {
1920
"php": "^7.1",
2021
"ext-curl": "*",
21-
"php-http/httplug": "^2.0",
22-
"php-http/message-factory": "^1.0.2",
23-
"php-http/message": "^1.2",
2422
"php-http/discovery": "^1.0",
23+
"php-http/httplug": "^2.0",
24+
"psr/http-client": "^1.0",
25+
"psr/http-factory": "^1.0",
2526
"symfony/options-resolver": "^3.4 || ^4.0"
2627
},
2728
"require-dev": {
2829
"guzzlehttp/psr7": "^1.0",
2930
"php-http/client-integration-tests": "dev-master",
3031
"phpunit/phpunit": "^7.5",
31-
"zendframework/zend-diactoros": "^1.0"
32+
"zendframework/zend-diactoros": "^2.0"
3233
},
3334
"autoload": {
3435
"psr-4": {

phpunit.xml.dist

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,41 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<phpunit colors="true" bootstrap="tests/bootstrap.php">
2+
3+
<!-- https://phpunit.de/manual/current/en/appendixes.configuration.html -->
4+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/7.0/phpunit.xsd"
6+
bootstrap="tests/bootstrap.php"
7+
colors="true"
8+
>
9+
<php>
10+
<server name="TEST_SERVER" value="http://127.0.0.1:10000/server.php"/>
11+
</php>
12+
313
<testsuites>
4-
<testsuite name="Curl Client Test Suite">
5-
<directory>tests/</directory>
14+
15+
<testsuite name="All">
16+
<directory>tests</directory>
17+
<!-- Exclude till https://github.com/php-http/message/issues/105 resolved. -->
18+
<exclude>tests/Functional/HttpAsyncClientGuzzleTest.php</exclude>
19+
<exclude>tests/Functional/HttpClientGuzzleTest.php</exclude>
20+
</testsuite>
21+
22+
<testsuite name="Unit">
23+
<directory>tests/Unit</directory>
624
</testsuite>
25+
26+
<testsuite name="Functional">
27+
<directory>tests/Functional</directory>
28+
<!-- Exclude till https://github.com/php-http/message/issues/105 resolved. -->
29+
<exclude>tests/Functional/HttpAsyncClientGuzzleTest.php</exclude>
30+
<exclude>tests/Functional/HttpClientGuzzleTest.php</exclude>
31+
</testsuite>
32+
733
</testsuites>
8-
<php>
9-
<server name="TEST_SERVER" value="http://127.0.0.1:10000/server.php" />
10-
</php>
34+
1135
<filter>
1236
<whitelist>
13-
<directory suffix=".php">src/</directory>
37+
<directory>src</directory>
1438
</whitelist>
1539
</filter>
40+
1641
</phpunit>

src/Client.php

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
<?php
22

3+
declare(strict_types=1);
4+
35
namespace Http\Client\Curl;
46

57
use Http\Client\Exception;
68
use Http\Client\HttpAsyncClient;
79
use Http\Client\HttpClient;
810
use Http\Discovery\MessageFactoryDiscovery;
911
use Http\Discovery\StreamFactoryDiscovery;
10-
use Http\Message\MessageFactory;
11-
use Http\Message\StreamFactory;
1212
use Http\Promise\Promise;
1313
use Psr\Http\Message\RequestInterface;
14+
use Psr\Http\Message\ResponseFactoryInterface;
1415
use Psr\Http\Message\ResponseInterface;
16+
use Psr\Http\Message\StreamFactoryInterface;
1517
use Symfony\Component\OptionsResolver\OptionsResolver;
1618

1719
/**
@@ -35,16 +37,16 @@ class Client implements HttpClient, HttpAsyncClient
3537
private $options;
3638

3739
/**
38-
* PSR-7 message factory.
40+
* PSR-17 response factory.
3941
*
40-
* @var MessageFactory
42+
* @var ResponseFactoryInterface
4143
*/
42-
private $messageFactory;
44+
private $responseFactory;
4345

4446
/**
45-
* PSR-7 stream factory.
47+
* PSR-17 stream factory.
4648
*
47-
* @var StreamFactory
49+
* @var StreamFactoryInterface
4850
*/
4951
private $streamFactory;
5052

@@ -53,37 +55,43 @@ class Client implements HttpClient, HttpAsyncClient
5355
*
5456
* @var resource|null
5557
*/
56-
private $handle = null;
58+
private $handle;
5759

5860
/**
5961
* Simultaneous requests runner.
6062
*
6163
* @var MultiRunner|null
6264
*/
63-
private $multiRunner = null;
65+
private $multiRunner;
6466

6567
/**
66-
* @param MessageFactory|null $messageFactory HTTP Message factory
67-
* @param StreamFactory|null $streamFactory HTTP Stream factory
68-
* @param array $options cURL options {@link http://php.net/curl_setopt}
68+
* Construct client.
69+
*
70+
* @param ResponseFactoryInterface|null $responseFactory PSR-17 HTTP response factory.
71+
* @param StreamFactoryInterface|null $streamFactory PSR-17 HTTP stream factory.
72+
* @param array $options cURL options {@link http://php.net/curl_setopt}
6973
*
7074
* @throws \Http\Discovery\Exception\NotFoundException If factory discovery failed
7175
*
76+
* @since x.x $messageFactory changed to PSR-17 ResponseFactoryInterface $responseFactory.
77+
* @since x.x $streamFactory type changed to PSR-17 StreamFactoryInterface.
7278
* @since 1.0
7379
*/
7480
public function __construct(
75-
MessageFactory $messageFactory = null,
76-
StreamFactory $streamFactory = null,
81+
ResponseFactoryInterface $responseFactory = null,
82+
StreamFactoryInterface $streamFactory = null,
7783
array $options = []
7884
) {
79-
$this->messageFactory = $messageFactory ?: MessageFactoryDiscovery::find();
80-
$this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find();
85+
$this->responseFactory = $responseFactory; // FIXME ?: MessageFactoryDiscovery::find();
86+
$this->streamFactory = $streamFactory; // FIXME ?: StreamFactoryDiscovery::find();
8187
$resolver = new OptionsResolver();
82-
$resolver->setDefaults([
83-
CURLOPT_HEADER => false,
84-
CURLOPT_RETURNTRANSFER => false,
85-
CURLOPT_FOLLOWLOCATION => false,
86-
]);
88+
$resolver->setDefaults(
89+
[
90+
CURLOPT_HEADER => false,
91+
CURLOPT_RETURNTRANSFER => false,
92+
CURLOPT_FOLLOWLOCATION => false,
93+
]
94+
);
8795
$resolver->setAllowedValues(CURLOPT_HEADER, [false]); // our parsing will fail if this is set to true
8896
$resolver->setAllowedValues(CURLOPT_RETURNTRANSFER, [false]); // our parsing will fail if this is set to true
8997

@@ -105,7 +113,7 @@ public function __destruct()
105113
}
106114

107115
/**
108-
* Sends a PSR-7 request.
116+
* Sends a PSR-7 request and returns a PSR-7 response.
109117
*
110118
* @param RequestInterface $request
111119
*
@@ -363,17 +371,14 @@ private function createHeaders(RequestInterface $request, array $options): array
363371
* Create new ResponseBuilder instance.
364372
*
365373
* @return ResponseBuilder
366-
*
367-
* @throws \RuntimeException If creating the stream from $body fails
368374
*/
369375
private function createResponseBuilder(): ResponseBuilder
370376
{
371-
try {
372-
$body = $this->streamFactory->createStream(fopen('php://temp', 'w+b'));
373-
} catch (\InvalidArgumentException $e) {
374-
throw new \RuntimeException('Can not create "php://temp" stream.');
375-
}
376-
$response = $this->messageFactory->createResponse(200, null, [], $body);
377+
$body = $this->streamFactory->createStreamFromFile('php://temp', 'w+b');
378+
379+
$response = $this->responseFactory
380+
->createResponse(200)
381+
->withBody($body);
377382

378383
return new ResponseBuilder($response);
379384
}

src/MultiRunner.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class MultiRunner
1919
*
2020
* @var resource|null
2121
*/
22-
private $multiHandle = null;
22+
private $multiHandle;
2323

2424
/**
2525
* Awaiting cores.
@@ -43,7 +43,7 @@ public function __destruct()
4343
*
4444
* @param PromiseCore $core
4545
*/
46-
public function add(PromiseCore $core)
46+
public function add(PromiseCore $core): void
4747
{
4848
foreach ($this->cores as $existed) {
4949
if ($existed === $core) {
@@ -64,7 +64,7 @@ public function add(PromiseCore $core)
6464
*
6565
* @param PromiseCore $core
6666
*/
67-
public function remove(PromiseCore $core)
67+
public function remove(PromiseCore $core): void
6868
{
6969
foreach ($this->cores as $index => $existed) {
7070
if ($existed === $core) {
@@ -81,7 +81,7 @@ public function remove(PromiseCore $core)
8181
*
8282
* @param PromiseCore|null $targetCore
8383
*/
84-
public function wait(PromiseCore $targetCore = null)
84+
public function wait(PromiseCore $targetCore = null): void
8585
{
8686
do {
8787
$status = curl_multi_exec($this->multiHandle, $active);
@@ -118,7 +118,7 @@ public function wait(PromiseCore $targetCore = null)
118118
*
119119
* @return PromiseCore|null
120120
*/
121-
private function findCoreByHandle($handle)
121+
private function findCoreByHandle($handle): ?PromiseCore
122122
{
123123
foreach ($this->cores as $core) {
124124
if ($core->getHandle() === $handle) {

src/PromiseCore.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ public function __construct(
109109
*
110110
* @param callable $callback
111111
*/
112-
public function addOnFulfilled(callable $callback)
112+
public function addOnFulfilled(callable $callback): void
113113
{
114114
if ($this->getState() === Promise::PENDING) {
115115
$this->onFulfilled[] = $callback;
@@ -126,7 +126,7 @@ public function addOnFulfilled(callable $callback)
126126
*
127127
* @param callable $callback
128128
*/
129-
public function addOnRejected(callable $callback)
129+
public function addOnRejected(callable $callback): void
130130
{
131131
if ($this->getState() === Promise::PENDING) {
132132
$this->onRejected[] = $callback;
@@ -150,7 +150,7 @@ public function getHandle()
150150
*
151151
* @return string
152152
*/
153-
public function getState()
153+
public function getState(): string
154154
{
155155
return $this->state;
156156
}
@@ -160,17 +160,17 @@ public function getState()
160160
*
161161
* @return RequestInterface
162162
*/
163-
public function getRequest()
163+
public function getRequest(): RequestInterface
164164
{
165165
return $this->request;
166166
}
167167

168168
/**
169169
* Return the value of the promise (fulfilled).
170170
*
171-
* @return ResponseInterface Response Object only when the Promise is fulfilled
171+
* @return ResponseInterface Response object only when the Promise is fulfilled
172172
*/
173-
public function getResponse()
173+
public function getResponse(): ResponseInterface
174174
{
175175
return $this->responseBuilder->getResponse();
176176
}
@@ -181,11 +181,11 @@ public function getResponse()
181181
* If the exception is an instance of Http\Client\Exception\HttpException it will contain
182182
* the response object with the status code and the http reason.
183183
*
184-
* @return Exception Exception Object only when the Promise is rejected
184+
* @return \Throwable Exception Object only when the Promise is rejected
185185
*
186186
* @throws \LogicException When the promise is not rejected
187187
*/
188-
public function getException()
188+
public function getException(): \Throwable
189189
{
190190
if (null === $this->exception) {
191191
throw new \LogicException('Promise is not rejected');
@@ -197,7 +197,7 @@ public function getException()
197197
/**
198198
* Fulfill promise.
199199
*/
200-
public function fulfill()
200+
public function fulfill(): void
201201
{
202202
$this->state = Promise::FULFILLED;
203203
$response = $this->responseBuilder->getResponse();
@@ -225,7 +225,7 @@ public function fulfill()
225225
*
226226
* @param Exception $exception Reject reason
227227
*/
228-
public function reject(Exception $exception)
228+
public function reject(Exception $exception): void
229229
{
230230
$this->exception = $exception;
231231
$this->state = Promise::REJECTED;

src/ResponseBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class ResponseBuilder extends OriginalResponseBuilder
1717
*
1818
* @param ResponseInterface $response
1919
*/
20-
public function setResponse(ResponseInterface $response)
20+
public function setResponse(ResponseInterface $response): void
2121
{
2222
$this->response = $response;
2323
}

0 commit comments

Comments
 (0)