Skip to content

Commit ad1b152

Browse files
committed
Implement strict_types for PHP8 support. Updated unit tests to PHPUnit 9.5. Performance improvements & modernization courtesy of @spider4216. Dependency versions bump. Package version bump.
1 parent 4522e85 commit ad1b152

File tree

5 files changed

+62
-57
lines changed

5 files changed

+62
-57
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.phpunit.result.cache

README.markdown

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
PHP REST Client
22
===============
33
https://github.com/tcdent/php-restclient
4-
(c) 2013-2017 Travis Dent <tcdent@gmail.com>
4+
(c) 2013-2022 Travis Dent <tcdent@gmail.com>
55

66
Installation
77
-----------
8+
Requires PHP 8.0 or above. Use [0.1.7](https://github.com/tcdent/php-restclient/releases/tag/0.1.7) for legacy versions of PHP.
9+
810
``` sh
9-
$ php composer.phar require tcdent/php-restclient
11+
$ composer require tcdent/php-restclient
1012
```
1113

1214

@@ -240,8 +242,8 @@ Tests
240242
The test package includes a simple server script which returns debug information for verifying functionality. Start the server first, then run tests:
241243

242244
``` sh
243-
$ php -S localhost:8888 test.php
244-
$ phpunit test
245+
$ php -S localhost:8888 RestClientTest.php
246+
$ phpunit RestClientTest
245247
```
246248

247249
* Requires PHP > 5.5.7 in order for `getallheaders` data to populate.

test.php renamed to RestClientTest.php

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<?php
22

3+
use PHPUnit\Framework\TestCase;
4+
35
// Test are comprised of two components: a simple json response for testing
46
// interaction via the built-in PHP server, and PHPUnit test methods.
57

@@ -8,14 +10,14 @@
810
// JSON debug information for validating behavior.
911
if(php_sapi_name() == 'cli-server'){
1012
header("Content-Type: application/json");
11-
die(json_encode(array(
13+
die(json_encode([
1214
'SERVER' => $_SERVER,
1315
'REQUEST' => $_REQUEST,
1416
'POST' => $_POST,
1517
'GET' => $_GET,
1618
'body' => file_get_contents('php://input'),
1719
'headers' => getallheaders()
18-
)));
20+
]));
1921
}
2022

2123

@@ -28,9 +30,9 @@
2830
if(!isset($TEST_SERVER_URL))
2931
$TEST_SERVER_URL = "http://localhost:8888";
3032

31-
class RestClientTest extends PHPUnit_Framework_TestCase {
33+
class RestClientTest extends TestCase {
3234

33-
public function test_get(){
35+
public function test_get() : void {
3436
global $TEST_SERVER_URL;
3537

3638
$api = new RestClient;
@@ -47,7 +49,7 @@ public function test_get(){
4749
$response_json->body);
4850
}
4951

50-
public function test_post(){
52+
public function test_post() : void {
5153
global $TEST_SERVER_URL;
5254

5355
$api = new RestClient;
@@ -62,7 +64,7 @@ public function test_post(){
6264
$response_json->body);
6365
}
6466

65-
public function test_put(){
67+
public function test_put() : void {
6668
global $TEST_SERVER_URL;
6769

6870
$api = new RestClient;
@@ -76,7 +78,7 @@ public function test_put(){
7678
$response_json->body);
7779
}
7880

79-
public function test_delete(){
81+
public function test_delete() : void {
8082
global $TEST_SERVER_URL;
8183

8284
$api = new RestClient;
@@ -90,7 +92,7 @@ public function test_delete(){
9092
$response_json->body);
9193
}
9294

93-
public function test_user_agent(){
95+
public function test_user_agent() : void {
9496
global $TEST_SERVER_URL;
9597

9698
$api = new RestClient(array(
@@ -103,7 +105,7 @@ public function test_user_agent(){
103105
$response_json->headers->{"User-Agent"});
104106
}
105107

106-
public function test_json_patch(){
108+
public function test_json_patch() : void {
107109
global $TEST_SERVER_URL;
108110

109111
$api = new RestClient;
@@ -124,7 +126,7 @@ public function test_json_patch(){
124126
$response_json->body);
125127
}
126128

127-
public function test_json_post(){
129+
public function test_json_post() : void {
128130
global $TEST_SERVER_URL;
129131

130132
$api = new RestClient;
@@ -140,7 +142,7 @@ public function test_json_post(){
140142
$response_json->body);
141143
}
142144

143-
public function test_multiheader_response(){
145+
public function test_multiheader_response() : void {
144146
$RESPONSE = "HTTP/1.1 200 OK\r\nContent-type: text/json\r\nContent-Type: application/json\r\n\r\nbody";
145147

146148
$api = new RestClient;
@@ -155,7 +157,7 @@ public function test_multiheader_response(){
155157
$this->assertEquals("body", $api->response);
156158
}
157159

158-
public function test_multistatus_response(){
160+
public function test_multistatus_response() : void {
159161
$RESPONSE = "HTTP/1.1 100 Continue\r\n\r\nHTTP/1.1 200 OK\r\nCache-Control: no-cache\r\nContent-Type: application/json\r\n\r\nbody";
160162

161163
$api = new RestClient;
@@ -171,7 +173,7 @@ public function test_multistatus_response(){
171173
$this->assertEquals("body", $api->response);
172174
}
173175

174-
public function test_status_only_response(){
176+
public function test_status_only_response() : void {
175177
$RESPONSE = "HTTP/1.1 100 Continue\r\n\r\n";
176178

177179
$api = new RestClient;
@@ -184,7 +186,7 @@ public function test_status_only_response(){
184186
$this->assertEquals("", $api->response);
185187
}
186188

187-
public function test_build_indexed_queries(){
189+
public function test_build_indexed_queries() : void {
188190
global $TEST_SERVER_URL;
189191

190192
$api = new RestClient(['build_indexed_queries' => TRUE]);
@@ -197,7 +199,7 @@ public function test_build_indexed_queries(){
197199
$response_json->SERVER->QUERY_STRING);
198200
}
199201

200-
public function test_build_non_indexed_queries(){
202+
public function test_build_non_indexed_queries() : void {
201203
global $TEST_SERVER_URL;
202204

203205
$api = new RestClient;

composer.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tcdent/php-restclient",
3-
"version": "0.1.7",
3+
"version": "0.1.8",
44
"description": "A generic REST API client for PHP",
55
"type": "library",
66
"keywords": ["REST", "api", "client", "curl", "JSON", "XML"],
@@ -17,15 +17,15 @@
1717
"issues": "http://github.com/tcdent/php-restclient/issues"
1818
},
1919
"require": {
20-
"php": ">=5.4.0",
20+
"php": ">=8.0",
2121
"ext-curl": "*",
2222
"ext-json": "*"
2323
},
2424
"require-dev": {
25-
"php": ">=5.5.7",
26-
"phpunit/phpunit": ">=4.5"
25+
"php": ">=8.0",
26+
"phpunit/phpunit": ">=9.5"
2727
},
2828
"autoload": {
2929
"files": ["restclient.php"]
3030
}
31-
}
31+
}

restclient.php

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
<?php
1+
<?php declare(strict_types=1);
22

33
/**
44
* PHP REST Client
55
* https://github.com/tcdent/php-restclient
6-
* (c) 2013-2017 Travis Dent <tcdent@gmail.com>
6+
* (c) 2013-2022 Travis Dent <tcdent@gmail.com>
77
*/
88

99
class RestClientException extends Exception {}
@@ -23,13 +23,13 @@ class RestClient implements Iterator, ArrayAccess {
2323
// Populated as-needed.
2424
public $decoded_response; // Decoded response body.
2525

26-
public function __construct($options=[]){
26+
public function __construct(array $options=[]){
2727
$default_options = [
2828
'headers' => [],
2929
'parameters' => [],
3030
'curl_options' => [],
3131
'build_indexed_queries' => FALSE,
32-
'user_agent' => "PHP RestClient/0.1.7",
32+
'user_agent' => "PHP RestClient/0.1.8",
3333
'base_url' => NULL,
3434
'format' => NULL,
3535
'format_regex' => "/(\w+)\/(\w+)(;[.+])?/",
@@ -47,47 +47,47 @@ public function __construct($options=[]){
4747
$default_options['decoders'], $options['decoders']);
4848
}
4949

50-
public function set_option($key, $value){
50+
public function set_option($key, $value) : void {
5151
$this->options[$key] = $value;
5252
}
5353

54-
public function register_decoder($format, $method){
54+
public function register_decoder(string $format, callable $method) : void {
5555
// Decoder callbacks must adhere to the following pattern:
5656
// array my_decoder(string $data)
5757
$this->options['decoders'][$format] = $method;
5858
}
5959

6060
// Iterable methods:
61-
public function rewind(){
61+
public function rewind() : void {
6262
$this->decode_response();
63-
return reset($this->decoded_response);
63+
reset($this->decoded_response);
6464
}
6565

66-
public function current(){
66+
public function current() : mixed {
6767
return current($this->decoded_response);
6868
}
6969

70-
public function key(){
70+
public function key() : mixed {
7171
return key($this->decoded_response);
7272
}
7373

74-
public function next(){
75-
return next($this->decoded_response);
74+
public function next() : void {
75+
next($this->decoded_response);
7676
}
7777

78-
public function valid(){
78+
public function valid() : bool {
7979
return is_array($this->decoded_response)
8080
&& (key($this->decoded_response) !== NULL);
8181
}
8282

8383
// ArrayAccess methods:
84-
public function offsetExists($key){
84+
public function offsetExists($key) : bool {
8585
$this->decode_response();
8686
return is_array($this->decoded_response)?
8787
isset($this->decoded_response[$key]) : isset($this->decoded_response->{$key});
8888
}
8989

90-
public function offsetGet($key){
90+
public function offsetGet($key) : mixed {
9191
$this->decode_response();
9292
if(!$this->offsetExists($key))
9393
return NULL;
@@ -96,40 +96,40 @@ public function offsetGet($key){
9696
$this->decoded_response[$key] : $this->decoded_response->{$key};
9797
}
9898

99-
public function offsetSet($key, $value){
99+
public function offsetSet($key, $value) : void {
100100
throw new RestClientException("Decoded response data is immutable.");
101101
}
102102

103-
public function offsetUnset($key){
103+
public function offsetUnset($key) : void {
104104
throw new RestClientException("Decoded response data is immutable.");
105105
}
106106

107107
// Request methods:
108-
public function get($url, $parameters=[], $headers=[]){
108+
public function get(string $url, array|string $parameters=[], array $headers=[]) : RestClient {
109109
return $this->execute($url, 'GET', $parameters, $headers);
110110
}
111111

112-
public function post($url, $parameters=[], $headers=[]){
112+
public function post(string $url, array|string $parameters=[], array $headers=[]) : RestClient {
113113
return $this->execute($url, 'POST', $parameters, $headers);
114114
}
115115

116-
public function put($url, $parameters=[], $headers=[]){
116+
public function put(string $url, array|string $parameters=[], array $headers=[]) : RestClient {
117117
return $this->execute($url, 'PUT', $parameters, $headers);
118118
}
119119

120-
public function patch($url, $parameters=[], $headers=[]){
120+
public function patch(string $url, array|string $parameters=[], array $headers=[]) : RestClient {
121121
return $this->execute($url, 'PATCH', $parameters, $headers);
122122
}
123123

124-
public function delete($url, $parameters=[], $headers=[]){
124+
public function delete(string $url, array|string $parameters=[], array $headers=[]) : RestClient {
125125
return $this->execute($url, 'DELETE', $parameters, $headers);
126126
}
127127

128-
public function head($url, $parameters=[], $headers=[]){
128+
public function head(string $url, array|string $parameters=[], array $headers=[]) : RestClient {
129129
return $this->execute($url, 'HEAD', $parameters, $headers);
130130
}
131131

132-
public function execute($url, $method='GET', $parameters=[], $headers=[]){
132+
public function execute(string $url, string $method='GET', array|string $parameters=[], array $headers=[]) : RestClient {
133133
$client = clone $this;
134134
$client->url = $url;
135135
$client->handle = curl_init();
@@ -173,11 +173,11 @@ public function execute($url, $method='GET', $parameters=[], $headers=[]){
173173
else
174174
$parameters_string = (string) $parameters;
175175

176-
if(strtoupper($method) == 'POST'){
176+
if(strtoupper($method) === 'POST'){
177177
$curlopt[CURLOPT_POST] = TRUE;
178178
$curlopt[CURLOPT_POSTFIELDS] = $parameters_string;
179179
}
180-
elseif(strtoupper($method) != 'GET'){
180+
elseif(strtoupper($method) !== 'GET'){
181181
$curlopt[CURLOPT_CUSTOMREQUEST] = strtoupper($method);
182182
$curlopt[CURLOPT_POSTFIELDS] = $parameters_string;
183183
}
@@ -187,7 +187,7 @@ public function execute($url, $method='GET', $parameters=[], $headers=[]){
187187
}
188188

189189
if($client->options['base_url']){
190-
if($client->url[0] != '/' && substr($client->options['base_url'], -1) != '/')
190+
if($client->url[0] !== '/' && !str_ends_with($client->options['base_url'], '/'))
191191
$client->url = '/' . $client->url;
192192
$client->url = $client->options['base_url'] . $client->url;
193193
}
@@ -209,7 +209,7 @@ public function execute($url, $method='GET', $parameters=[], $headers=[]){
209209
return $client;
210210
}
211211

212-
public function parse_response($response){
212+
public function parse_response($response) : void {
213213
$headers = [];
214214
$this->response_status_lines = [];
215215
$line = strtok($response, "\n");
@@ -218,14 +218,14 @@ public function parse_response($response){
218218
// Since we tokenize on \n, use the remaining \r to detect empty lines.
219219
if(count($headers) > 0) break; // Must be the newline after headers, move on to response body
220220
}
221-
elseif(strpos($line, 'HTTP') === 0){
221+
elseif(str_starts_with($line, 'HTTP')){
222222
// One or more HTTP status lines
223223
$this->response_status_lines[] = trim($line);
224224
}
225225
else {
226226
// Has to be a header
227-
list($key, $value) = explode(':', $line, 2);
228-
$key = trim(strtolower(str_replace('-', '_', $key)));
227+
[$key, $value] = explode(':', $line, 2);
228+
$key = strtolower(trim(str_replace('-', '_', $key)));
229229
$value = trim($value);
230230

231231
if(empty($headers[$key]))
@@ -241,7 +241,7 @@ public function parse_response($response){
241241
$this->response = strtok("");
242242
}
243243

244-
public function get_response_format(){
244+
public function get_response_format() : string {
245245
if(!$this->response)
246246
throw new RestClientException(
247247
"A response must exist before it can be decoded.");
@@ -259,7 +259,7 @@ public function get_response_format(){
259259
"Response format could not be determined.");
260260
}
261261

262-
public function decode_response(){
262+
public function decode_response() : mixed {
263263
if(empty($this->decoded_response)){
264264
$format = $this->get_response_format();
265265
if(!array_key_exists($format, $this->options['decoders']))

0 commit comments

Comments
 (0)