Complex classes like CurlMulti often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use CurlMulti, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
17 | class CurlMulti extends AbstractHasDispatcher implements CurlMultiInterface |
||
18 | { |
||
19 | /** @var resource cURL multi handle. */ |
||
20 | protected $multiHandle; |
||
21 | |||
22 | /** @var array Attached {@see RequestInterface} objects. */ |
||
23 | protected $requests; |
||
24 | |||
25 | /** @var \SplObjectStorage RequestInterface to CurlHandle hash */ |
||
26 | protected $handles; |
||
27 | |||
28 | /** @var array Hash mapping curl handle resource IDs to request objects */ |
||
29 | protected $resourceHash; |
||
30 | |||
31 | /** @var array Queued exceptions */ |
||
32 | protected $exceptions = array(); |
||
33 | |||
34 | /** @var array Requests that succeeded */ |
||
35 | protected $successful = array(); |
||
36 | |||
37 | /** @var array cURL multi error values and codes */ |
||
38 | protected $multiErrors = array( |
||
39 | CURLM_BAD_HANDLE => array('CURLM_BAD_HANDLE', 'The passed-in handle is not a valid CURLM handle.'), |
||
40 | CURLM_BAD_EASY_HANDLE => array('CURLM_BAD_EASY_HANDLE', "An easy handle was not good/valid. It could mean that it isn't an easy handle at all, or possibly that the handle already is in used by this or another multi handle."), |
||
41 | CURLM_OUT_OF_MEMORY => array('CURLM_OUT_OF_MEMORY', 'You are doomed.'), |
||
42 | CURLM_INTERNAL_ERROR => array('CURLM_INTERNAL_ERROR', 'This can only be returned if libcurl bugs. Please report it to us!') |
||
43 | ); |
||
44 | |||
45 | /** @var float */ |
||
46 | protected $selectTimeout; |
||
47 | |||
48 | public function __construct($selectTimeout = 1.0) |
||
59 | |||
60 | public function __destruct() |
||
66 | |||
67 | public function add(RequestInterface $request) |
||
77 | |||
78 | public function all() |
||
82 | |||
83 | public function remove(RequestInterface $request) |
||
96 | |||
97 | public function reset($hard = false) |
||
109 | |||
110 | public function send() |
||
121 | |||
122 | public function count() |
||
126 | |||
127 | /** |
||
128 | * Build and throw a MultiTransferException |
||
129 | * |
||
130 | * @param array $exceptions Exceptions encountered |
||
131 | * @param array $successful Successful requests |
||
132 | * @throws MultiTransferException |
||
133 | */ |
||
134 | protected function throwMultiException(array $exceptions, array $successful) |
||
151 | |||
152 | /** |
||
153 | * Prepare for sending |
||
154 | * |
||
155 | * @param RequestInterface $request Request to prepare |
||
156 | * @throws \Exception on error preparing the request |
||
157 | */ |
||
158 | protected function beforeSend(RequestInterface $request) |
||
177 | |||
178 | private function addHandle(RequestInterface $request) |
||
185 | |||
186 | /** |
||
187 | * Create a curl handle for a request |
||
188 | * |
||
189 | * @param RequestInterface $request Request |
||
190 | * |
||
191 | * @return CurlHandle |
||
192 | */ |
||
193 | protected function createCurlHandle(RequestInterface $request) |
||
201 | |||
202 | /** |
||
203 | * Get the data from the multi handle |
||
204 | */ |
||
205 | protected function perform() |
||
237 | |||
238 | /** |
||
239 | * Execute and select curl handles |
||
240 | */ |
||
241 | private function executeHandles() |
||
257 | |||
258 | /** |
||
259 | * Process any received curl multi messages |
||
260 | */ |
||
261 | private function processMessages() |
||
273 | |||
274 | /** |
||
275 | * Remove a request that encountered an exception |
||
276 | * |
||
277 | * @param RequestInterface $request Request to remove |
||
278 | * @param \Exception $e Exception encountered |
||
279 | */ |
||
280 | protected function removeErroredRequest(RequestInterface $request, \Exception $e = null) |
||
286 | |||
287 | /** |
||
288 | * Check for errors and fix headers of a request based on a curl response |
||
289 | * |
||
290 | * @param RequestInterface $request Request to process |
||
291 | * @param CurlHandle $handle Curl handle object |
||
292 | * @param array $curl Array returned from curl_multi_info_read |
||
293 | * |
||
294 | * @throws CurlException on Curl error |
||
295 | */ |
||
296 | protected function processResponse(RequestInterface $request, CurlHandle $handle, array $curl) |
||
335 | |||
336 | /** |
||
337 | * Remove a curl handle from the curl multi object |
||
338 | * |
||
339 | * @param RequestInterface $request Request that owns the handle |
||
340 | */ |
||
341 | protected function removeHandle(RequestInterface $request) |
||
351 | |||
352 | /** |
||
353 | * Check if a cURL transfer resulted in what should be an exception |
||
354 | * |
||
355 | * @param RequestInterface $request Request to check |
||
356 | * @param CurlHandle $handle Curl handle object |
||
357 | * @param array $curl Array returned from curl_multi_info_read |
||
358 | * |
||
359 | * @return CurlException|bool |
||
360 | */ |
||
361 | private function isCurlException(RequestInterface $request, CurlHandle $handle, array $curl) |
||
377 | |||
378 | /** |
||
379 | * Throw an exception for a cURL multi response if needed |
||
380 | * |
||
381 | * @param int $code Curl response code |
||
382 | * @throws CurlException |
||
383 | */ |
||
384 | private function checkCurlResult($code) |
||
393 | |||
394 | /** |
||
395 | * @link https://github.com/guzzle/guzzle/issues/710 |
||
396 | */ |
||
397 | private function validateResponseWasSet(RequestInterface $request) |
||
432 | } |
||
433 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.