@@ -18,6 +18,8 @@ class MultiCurl
1818 private $ errorFunction = null ;
1919 private $ completeFunction = null ;
2020
21+ private $ retry = null ;
22+
2123 private $ cookies = array ();
2224 private $ headers = array ();
2325 private $ options = array ();
@@ -587,6 +589,20 @@ public function setReferrer($referrer)
587589 $ this ->setOpt (CURLOPT_REFERER , $ referrer );
588590 }
589591
592+ /**
593+ * Set Retry
594+ *
595+ * Number of retries to attempt or decider callable. Maximum number of
596+ * attempts is $maximum_number_of_retries + 1.
597+ *
598+ * @access public
599+ * @param $mixed
600+ */
601+ public function setRetry ($ mixed )
602+ {
603+ $ this ->retry = $ mixed ;
604+ }
605+
590606 /**
591607 * Set Timeout
592608 *
@@ -661,17 +677,31 @@ public function start()
661677 $ ch ->curlErrorCode = $ info_array ['result ' ];
662678 $ ch ->exec ($ ch ->curl );
663679
664- // Remove completed instance from active curls.
665- unset($ this ->activeCurls [$ key ]);
666-
667- // Start a new request before removing the handle of the completed one.
668- if (count ($ this ->curls ) >= 1 ) {
669- $ this ->initHandle (array_shift ($ this ->curls ));
680+ if ($ ch ->attemptRetry ()) {
681+ // Remove completed handle before adding again in order to retry request.
682+ curl_multi_remove_handle ($ this ->multiCurl , $ ch ->curl );
683+
684+ $ curlm_error_code = curl_multi_add_handle ($ this ->multiCurl , $ ch ->curl );
685+ if (!($ curlm_error_code === CURLM_OK )) {
686+ throw new \ErrorException (
687+ 'cURL multi add handle error: ' . curl_multi_strerror ($ curlm_error_code )
688+ );
689+ }
690+ } else {
691+ $ ch ->execDone ();
692+
693+ // Remove completed instance from active curls.
694+ unset($ this ->activeCurls [$ key ]);
695+
696+ // Start a new request before removing the handle of the completed one.
697+ if (count ($ this ->curls ) >= 1 ) {
698+ $ this ->initHandle (array_shift ($ this ->curls ));
699+ }
700+ curl_multi_remove_handle ($ this ->multiCurl , $ ch ->curl );
701+
702+ // Clean up completed instance.
703+ $ ch ->close ();
670704 }
671- curl_multi_remove_handle ($ this ->multiCurl , $ ch ->curl );
672-
673- // Clean up completed instance.
674- $ ch ->close ();
675705
676706 break ;
677707 }
@@ -763,6 +793,7 @@ private function queueHandle($curl)
763793 {
764794 // Use sequential ids to allow for ordered post processing.
765795 $ curl ->id = $ this ->nextCurlId ++;
796+ $ curl ->isChildOfMultiCurl = true ;
766797 $ this ->curls [$ curl ->id ] = $ curl ;
767798 }
768799
@@ -791,6 +822,7 @@ private function initHandle($curl)
791822
792823 $ curl ->setOpts ($ this ->options );
793824 $ curl ->setHeaders ($ this ->headers );
825+ $ curl ->setRetry ($ this ->retry );
794826
795827 foreach ($ this ->cookies as $ key => $ value ) {
796828 $ curl ->setCookie ($ key , $ value );
0 commit comments