1414
1515class Httpie
1616{
17+ private static bool $ extensionChecked = false ;
18+
1719 private string $ method = 'GET ' ;
1820 private string $ url = '' ;
1921 private array $ headers = [];
@@ -23,48 +25,50 @@ class Httpie
2325
2426 public function __construct ()
2527 {
26- if (!extension_loaded ('curl ' )) {
27- throw new \Exception (
28- "Please, install curl extension. \n"
29- . "https://php.net/curl.installation " ,
30- );
28+ if (!self ::$ extensionChecked ) {
29+ if (!extension_loaded ('curl ' )) {
30+ throw new \Exception (
31+ "Please, install curl extension. \n"
32+ . "https://php.net/curl.installation " ,
33+ );
34+ }
35+ self ::$ extensionChecked = true ;
3136 }
3237 }
3338
34- public static function get (string $ url ): Httpie
39+ public static function get (string $ url ): self
3540 {
3641 $ http = new self ();
3742 $ http ->method = 'GET ' ;
3843 $ http ->url = $ url ;
3944 return $ http ;
4045 }
4146
42- public static function post (string $ url ): Httpie
47+ public static function post (string $ url ): self
4348 {
4449 $ http = new self ();
4550 $ http ->method = 'POST ' ;
4651 $ http ->url = $ url ;
4752 return $ http ;
4853 }
4954
50- public static function patch (string $ url ): Httpie
55+ public static function patch (string $ url ): self
5156 {
5257 $ http = new self ();
5358 $ http ->method = 'PATCH ' ;
5459 $ http ->url = $ url ;
5560 return $ http ;
5661 }
5762
58-
59- public static function put (string $ url ): Httpie
63+ public static function put (string $ url ): self
6064 {
6165 $ http = new self ();
6266 $ http ->method = 'PUT ' ;
6367 $ http ->url = $ url ;
6468 return $ http ;
6569 }
6670
67- public static function delete (string $ url ): Httpie
71+ public static function delete (string $ url ): self
6872 {
6973 $ http = new self ();
7074 $ http ->method = 'DELETE ' ;
@@ -74,7 +78,8 @@ public static function delete(string $url): Httpie
7478
7579 public function query (array $ params ): self
7680 {
77- $ this ->url .= '? ' . http_build_query ($ params );
81+ $ separator = str_contains ($ this ->url , '? ' ) ? '& ' : '? ' ;
82+ $ this ->url .= $ separator . http_build_query ($ params );
7883 return $ this ;
7984 }
8085
@@ -84,32 +89,52 @@ public function header(string $header, string $value): self
8489 return $ this ;
8590 }
8691
92+ public function bearerToken (string $ token ): self
93+ {
94+ $ this ->headers ['Authorization ' ] = 'Bearer ' . $ token ;
95+ return $ this ;
96+ }
97+
98+ public function basicAuth (string $ user , string $ pass ): self
99+ {
100+ $ this ->curlopts [CURLOPT_USERPWD ] = "$ user: $ pass " ;
101+ return $ this ;
102+ }
103+
104+ public function timeout (int $ seconds ): self
105+ {
106+ $ this ->curlopts [CURLOPT_TIMEOUT ] = $ seconds ;
107+ $ this ->curlopts [CURLOPT_CONNECTTIMEOUT ] = $ seconds ;
108+ return $ this ;
109+ }
110+
111+ public function noTimeout (): self
112+ {
113+ $ this ->curlopts [CURLOPT_TIMEOUT ] = 0 ;
114+ $ this ->curlopts [CURLOPT_CONNECTTIMEOUT ] = 0 ;
115+ return $ this ;
116+ }
117+
87118 public function body (string $ body ): self
88119 {
89120 $ this ->body = $ body ;
90- $ this ->headers = array_merge ($ this ->headers , [
91- 'Content-Length ' => strlen ($ this ->body ),
92- ]);
121+ $ this ->headers ['Content-Length ' ] = (string ) strlen ($ this ->body );
93122 return $ this ;
94123 }
95124
96125 public function jsonBody (array $ data ): self
97126 {
98127 $ this ->body = json_encode ($ data , JSON_PRETTY_PRINT );
99- $ this ->headers = array_merge ($ this ->headers , [
100- 'Content-Type ' => 'application/json ' ,
101- 'Content-Length ' => strlen ($ this ->body ),
102- ]);
128+ $ this ->headers ['Content-Type ' ] = 'application/json ' ;
129+ $ this ->headers ['Content-Length ' ] = (string ) strlen ($ this ->body );
103130 return $ this ;
104131 }
105132
106133 public function formBody (array $ data ): self
107134 {
108135 $ this ->body = http_build_query ($ data );
109- $ this ->headers = array_merge ($ this ->headers , [
110- 'Content-type ' => 'application/x-www-form-urlencoded ' ,
111- 'Content-Length ' => strlen ($ this ->body ),
112- ]);
136+ $ this ->headers ['Content-type ' ] = 'application/x-www-form-urlencoded ' ;
137+ $ this ->headers ['Content-Length ' ] = (string ) strlen ($ this ->body );
113138 return $ this ;
114139 }
115140
@@ -129,9 +154,9 @@ public function nothrow(bool $on = true): self
129154 }
130155
131156 /**
132- * @param-out array $info
157+ * Send the request and return a response object.
133158 */
134- public function send (?array &$ info = null ): string
159+ public function send (?array &$ info = null ): HttpResponse
135160 {
136161 if ($ this ->url === '' ) {
137162 throw new \RuntimeException ('URL must not be empty to Httpie::send() ' );
@@ -157,26 +182,55 @@ public function send(?array &$info = null): string
157182 $ info = curl_getinfo ($ ch ) ?: [];
158183 if ($ result === false ) {
159184 if ($ this ->nothrow ) {
160- $ result = '' ;
161- } else {
162- $ error = curl_error ($ ch );
163- $ errno = curl_errno ($ ch );
164- throw new HttpieException ($ error , $ errno );
185+ return new HttpResponse ('' , $ info );
165186 }
187+ $ error = curl_error ($ ch );
188+ $ errno = curl_errno ($ ch );
189+ throw new HttpieException ($ error , $ errno );
166190 }
167- return $ result ;
191+ return new HttpResponse ( $ result, $ info ) ;
168192 }
169193
194+ /**
195+ * Send the request and return the decoded JSON response.
196+ */
197+ public function sendJson (): mixed
198+ {
199+ return $ this ->send ()->json ();
200+ }
201+
202+ /**
203+ * @deprecated Use sendJson() instead.
204+ */
170205 public function getJson (): mixed
171206 {
172- $ result = $ this ->send ();
173- $ response = json_decode ($ result , true );
174- if (json_last_error () !== JSON_ERROR_NONE ) {
175- throw new HttpieException (
176- 'JSON Error: ' . json_last_error_msg () . '\n '
177- . 'Response: ' . $ result ,
178- );
179- }
180- return $ response ;
207+ return $ this ->sendJson ();
208+ }
209+
210+ // Getters for testing.
211+
212+ public function getMethod (): string
213+ {
214+ return $ this ->method ;
215+ }
216+
217+ public function getUrl (): string
218+ {
219+ return $ this ->url ;
220+ }
221+
222+ public function getHeaders (): array
223+ {
224+ return $ this ->headers ;
225+ }
226+
227+ public function getBody (): string
228+ {
229+ return $ this ->body ;
230+ }
231+
232+ public function getCurlopts (): array
233+ {
234+ return $ this ->curlopts ;
181235 }
182236}
0 commit comments