@@ -23,6 +23,72 @@ class Client
23
23
public const CONTENT_TYPE_MULTIPART_FORM_DATA = 'multipart/form-data ' ;
24
24
public const CONTENT_TYPE_GRAPHQL = 'application/graphql ' ;
25
25
26
+ /** @var array<string, string> headers */
27
+ private array $ headers = [];
28
+ private int $ timeout = 15 ;
29
+ private int $ connectTimeout = 60 ;
30
+ private int $ maxRedirects = 5 ;
31
+ private bool $ allowRedirects = true ;
32
+
33
+ /**
34
+ * @param string $key
35
+ * @param string $value
36
+ * @return self
37
+ */
38
+ public function addHeader (string $ key , string $ value ): self
39
+ {
40
+ $ this ->headers [$ key ] = $ value ;
41
+ return $ this ;
42
+ }
43
+
44
+ /**
45
+ * Set the request timeout.
46
+ *
47
+ * @param int $timeout
48
+ * @return self
49
+ */
50
+ public function setTimeout (int $ timeout ): self
51
+ {
52
+ $ this ->timeout = $ timeout ;
53
+ return $ this ;
54
+ }
55
+
56
+ /**
57
+ * Set whether to allow redirects.
58
+ *
59
+ * @param bool $allow
60
+ * @return self
61
+ */
62
+ public function setAllowRedirects (bool $ allow ): self
63
+ {
64
+ $ this ->allowRedirects = $ allow ;
65
+ return $ this ;
66
+ }
67
+
68
+ /**
69
+ * Set the maximum number of redirects.
70
+ *
71
+ * @param int $maxRedirects
72
+ * @return self
73
+ */
74
+ public function setMaxRedirects (int $ maxRedirects ): self
75
+ {
76
+ $ this ->maxRedirects = $ maxRedirects ;
77
+ return $ this ;
78
+ }
79
+
80
+ /**
81
+ * Set the connection timeout.
82
+ *
83
+ * @param int $connectTimeout
84
+ * @return self
85
+ */
86
+ public function setConnectTimeout (int $ connectTimeout ): self
87
+ {
88
+ $ this ->connectTimeout = $ connectTimeout ;
89
+ return $ this ;
90
+ }
91
+
26
92
/**
27
93
* Flatten request body array to PHP multiple format
28
94
*
@@ -45,86 +111,89 @@ private static function flatten(array $data, string $prefix = ''): array
45
111
46
112
return $ output ;
47
113
}
114
+
48
115
/**
49
- * This method is used to make a request to the server
116
+ * This method is used to make a request to the server.
117
+ *
50
118
* @param string $url
51
- * @param array<string, string> $headers
52
119
* @param string $method
53
120
* @param array<string>|array<string, mixed> $body
54
121
* @param array<string, mixed> $query
55
- * @param int $timeout
56
122
* @return Response
57
123
*/
58
- public static function fetch (
124
+ public function fetch (
59
125
string $ url ,
60
- array $ headers = [],
61
126
string $ method = self ::METHOD_GET ,
62
127
array $ body = [],
63
128
array $ query = [],
64
- int $ timeout = 15
65
129
): Response {
66
- // Process the data before making the request
67
- if (!in_array ($ method , [self ::METHOD_PATCH , self ::METHOD_GET , self ::METHOD_CONNECT , self ::METHOD_DELETE , self ::METHOD_POST , self ::METHOD_HEAD , self ::METHOD_OPTIONS , self ::METHOD_PUT , self ::METHOD_TRACE ])) { // If the method is not supported
130
+ if (!in_array ($ method , [self ::METHOD_PATCH , self ::METHOD_GET , self ::METHOD_CONNECT , self ::METHOD_DELETE , self ::METHOD_POST , self ::METHOD_HEAD , self ::METHOD_OPTIONS , self ::METHOD_PUT , self ::METHOD_TRACE ])) {
68
131
throw new FetchException ("Unsupported HTTP method " );
69
132
}
70
- if (isset ($ headers ['content-type ' ])) {
71
- match ($ headers ['content-type ' ]) { // Convert the body to the appropriate format
72
- self ::CONTENT_TYPE_APPLICATION_JSON => $ body = json_encode ($ body ),
73
- self ::CONTENT_TYPE_APPLICATION_FORM_URLENCODED , self ::CONTENT_TYPE_MULTIPART_FORM_DATA => $ body = self ::flatten ($ body ),
74
- self ::CONTENT_TYPE_GRAPHQL => $ body = $ body [0 ],
75
- default => $ body = $ body ,
133
+
134
+ if (isset ($ this ->headers ['content-type ' ])) {
135
+ $ body = match ($ this ->headers ['content-type ' ]) {
136
+ self ::CONTENT_TYPE_APPLICATION_JSON => json_encode ($ body ),
137
+ self ::CONTENT_TYPE_APPLICATION_FORM_URLENCODED , self ::CONTENT_TYPE_MULTIPART_FORM_DATA => self ::flatten ($ body ),
138
+ self ::CONTENT_TYPE_GRAPHQL => $ body [0 ],
139
+ default => $ body ,
76
140
};
77
141
}
78
- $ headers = array_map (function ($ i , $ header ) { // convert headers to appropriate format
79
- return $ i . ': ' . $ header ;
80
- }, array_keys ($ headers ), $ headers );
81
- if ($ query ) { // if the request has a query string, append it to the request URI
82
- $ url = rtrim ($ url , '? ' );
83
- $ url .= '? ' . http_build_query ($ query );
142
+
143
+ $ formattedHeaders = array_map (function ($ key , $ value ) {
144
+ return $ key . ': ' . $ value ;
145
+ }, array_keys ($ this ->headers ), $ this ->headers );
146
+
147
+ if ($ query ) {
148
+ $ url = rtrim ($ url , '? ' ) . '? ' . http_build_query ($ query );
84
149
}
150
+
85
151
$ responseHeaders = [];
86
- // Initialize the curl session
87
152
$ ch = curl_init ();
88
- // Set the request URI
89
- curl_setopt ($ ch , CURLOPT_URL , $ url );
90
- // Set the request headers
91
- curl_setopt ($ ch , CURLOPT_HTTPHEADER , $ headers );
92
- // Set the request method
93
- curl_setopt ($ ch , CURLOPT_CUSTOMREQUEST , $ method );
94
- // Set the request body
95
- curl_setopt ($ ch , CURLOPT_POSTFIELDS , $ body );
96
- // Save the response headers
97
- curl_setopt ($ ch , CURLOPT_HEADERFUNCTION , function ($ curl , $ header ) use (&$ responseHeaders ) {
98
- $ len = strlen ($ header );
99
- $ header = explode (': ' , $ header , 2 );
100
-
101
- if (count ($ header ) < 2 ) { // ignore invalid headers
153
+ $ curlOptions = [
154
+ CURLOPT_URL => $ url ,
155
+ CURLOPT_HTTPHEADER => $ formattedHeaders ,
156
+ CURLOPT_CUSTOMREQUEST => $ method ,
157
+ CURLOPT_POSTFIELDS => $ body ,
158
+ CURLOPT_HEADERFUNCTION => function ($ curl , $ header ) use (&$ responseHeaders ) {
159
+ $ len = strlen ($ header );
160
+ $ header = explode (': ' , $ header , 2 );
161
+ if (count ($ header ) < 2 ) { // ignore invalid headers
162
+ return $ len ;
163
+ }
164
+ $ responseHeaders [strtolower (trim ($ header [0 ]))] = trim ($ header [1 ]);
102
165
return $ len ;
103
- }
166
+ },
167
+ CURLOPT_CONNECTTIMEOUT => $ this ->connectTimeout ,
168
+ CURLOPT_TIMEOUT => $ this ->timeout ,
169
+ CURLOPT_MAXREDIRS => $ this ->maxRedirects ,
170
+ CURLOPT_FOLLOWLOCATION => $ this ->allowRedirects ,
171
+ CURLOPT_RETURNTRANSFER => true ,
172
+ ];
104
173
105
- $ responseHeaders [strtolower (trim ($ header [0 ]))] = trim ($ header [1 ]);
106
- return $ len ;
107
- });
108
- curl_setopt ($ ch , CURLOPT_CONNECTTIMEOUT , 60 );
109
- curl_setopt ($ ch , CURLOPT_TIMEOUT , $ timeout );
110
- curl_setopt ($ ch , CURLOPT_FOLLOWLOCATION , true );
111
- curl_setopt ($ ch , CURLOPT_RETURNTRANSFER , true );
112
- $ responseBody = curl_exec ($ ch ); // Execute the curl session
113
- $ responseStatusCode = curl_getinfo ($ ch , CURLINFO_HTTP_CODE );
174
+ // Merge user-defined CURL options with defaults
175
+ foreach ($ curlOptions as $ option => $ value ) {
176
+ curl_setopt ($ ch , $ option , $ value );
177
+ }
114
178
179
+ $ responseBody = curl_exec ($ ch );
180
+ $ responseStatusCode = curl_getinfo ($ ch , CURLINFO_HTTP_CODE );
115
181
if (curl_errno ($ ch )) {
116
182
$ errorMsg = curl_error ($ ch );
117
183
}
184
+
118
185
curl_close ($ ch );
119
186
120
187
if (isset ($ errorMsg )) {
121
188
throw new FetchException ($ errorMsg );
122
189
}
190
+
123
191
$ response = new Response (
124
192
statusCode: $ responseStatusCode ,
125
193
headers: $ responseHeaders ,
126
194
body: $ responseBody
127
195
);
196
+
128
197
return $ response ;
129
198
}
130
199
}
0 commit comments