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.