1. <?php
  2. /**
  3. * OO cURL Class
  4. * Object oriented wrapper for the cURL library.
  5. * @author David Hopkins (semlabs.co.uk)
  6. * @version 0.3
  7. */
  8. class CURL
  9. {
  10. public $sessions = array();
  11. public $retry = 0;
  12. /**
  13. * Adds a cURL session to stack
  14. * @param $url string, session's URL
  15. * @param $opts array, optional array of cURL options and values
  16. */
  17. public function addSession( $url, $opts = false )
  18. {
  19. $this->sessions[] = curl_init( $url );
  20. if( $opts != false )
  21. {
  22. $key = count( $this->sessions ) - 1;
  23. $this->setOpts( $opts, $key );
  24. }
  25. }
  26. /**
  27. * Sets an option to a cURL session
  28. * @param $option constant, cURL option
  29. * @param $value mixed, value of option
  30. * @param $key int, session key to set option for
  31. */
  32. public function setOpt( $option, $value, $key = 0 )
  33. {
  34. curl_setopt( $this->sessions[$key], $option, $value );
  35. }
  36. /**
  37. * Sets an array of options to a cURL session
  38. * @param $options array, array of cURL options and values
  39. * @param $key int, session key to set option for
  40. */
  41. public function setOpts( $options, $key = 0 )
  42. {
  43. curl_setopt_array( $this->sessions[$key], $options );
  44. }
  45. /**
  46. * Executes as cURL session
  47. * @param $key int, optional argument if you only want to execute one session
  48. */
  49. public function exec( $key = false )
  50. {
  51. $no = count( $this->sessions );
  52. if( $no == 1 )
  53. $res = $this->execSingle();
  54. elseif( $no > 1 ) {
  55. if( $key === false )
  56. $res = $this->execMulti();
  57. else
  58. $res = $this->execSingle( $key );
  59. }
  60. if( $res )
  61. return $res;
  62. }
  63. /**
  64. * Executes a single cURL session
  65. * @param $key int, id of session to execute
  66. * @return array of content if CURLOPT_RETURNTRANSFER is set
  67. */
  68. public function execSingle( $key = 0 )
  69. {
  70. if( $this->retry > 0 )
  71. {
  72. $retry = $this->retry;
  73. $code = 0;
  74. while( $retry >= 0 && ( $code[0] == 0 || $code[0] >= 400 ) )
  75. {
  76. $res = curl_exec( $this->sessions[$key] );
  77. $code = $this->info( $key, CURLINFO_HTTP_CODE );
  78. $retry--;
  79. }
  80. }
  81. else
  82. $res = curl_exec( $this->sessions[$key] );
  83. return $res;
  84. }
  85. /**
  86. * Executes a stack of sessions
  87. * @return array of content if CURLOPT_RETURNTRANSFER is set
  88. */
  89. public function execMulti()
  90. {
  91. $mh = curl_multi_init();
  92. #Add all sessions to multi handle
  93. foreach ( $this->sessions as $i => $url )
  94. curl_multi_add_handle( $mh, $this->sessions[$i] );
  95. do
  96. $mrc = curl_multi_exec( $mh, $active );
  97. while ( $mrc == CURLM_CALL_MULTI_PERFORM );
  98. while ( $active && $mrc == CURLM_OK )
  99. {
  100. if ( curl_multi_select( $mh ) != -1 )
  101. {
  102. do
  103. $mrc = curl_multi_exec( $mh, $active );
  104. while ( $mrc == CURLM_CALL_MULTI_PERFORM );
  105. }
  106. }
  107. if ( $mrc != CURLM_OK )
  108. echo "Curl multi read error $mrc\n";
  109. #Get content foreach session, retry if applied
  110. foreach ( $this->sessions as $i => $url )
  111. {
  112. $code = $this->info( $i, CURLINFO_HTTP_CODE );
  113. if( $code[0] > 0 && $code[0] < 400 )
  114. $res[] = curl_multi_getcontent( $this->sessions[$i] );
  115. else
  116. {
  117. if( $this->retry > 0 )
  118. {
  119. $retry = $this->retry;
  120. $this->retry -= 1;
  121. $eRes = $this->execSingle( $i );
  122. if( $eRes )
  123. $res[] = $eRes;
  124. else
  125. $res[] = false;
  126. $this->retry = $retry;
  127. echo '1';
  128. }
  129. else
  130. $res[] = false;
  131. }
  132. curl_multi_remove_handle( $mh, $this->sessions[$i] );
  133. }
  134. curl_multi_close( $mh );
  135. return $res;
  136. }
  137. /**
  138. * Closes cURL sessions
  139. * @param $key int, optional session to close
  140. */
  141. public function close( $key = false )
  142. {
  143. if( $key === false )
  144. {
  145. foreach( $this->sessions as $session )
  146. curl_close( $session );
  147. }
  148. else
  149. curl_close( $this->sessions[$key] );
  150. }
  151. /**
  152. * Remove all cURL sessions
  153. */
  154. public function clear()
  155. {
  156. foreach( $this->sessions as $session )
  157. curl_close( $session );
  158. unset( $this->sessions );
  159. }
  160. /**
  161. * Returns an array of session information
  162. * @param $key int, optional session key to return info on
  163. * @param $opt constant, optional option to return
  164. */
  165. public function info( $key = false, $opt = false )
  166. {
  167. if( $key === false )
  168. {
  169. foreach( $this->sessions as $key => $session )
  170. {
  171. if( $opt )
  172. $info[] = curl_getinfo( $this->sessions[$key], $opt );
  173. else
  174. $info[] = curl_getinfo( $this->sessions[$key] );
  175. }
  176. }
  177. else
  178. {
  179. if( $opt )
  180. $info[] = curl_getinfo( $this->sessions[$key], $opt );
  181. else
  182. $info[] = curl_getinfo( $this->sessions[$key] );
  183. }
  184. return $info;
  185. }
  186. /**
  187. * Returns an array of errors
  188. * @param $key int, optional session key to retun error on
  189. * @return array of error messages
  190. */
  191. public function error( $key = false )
  192. {
  193. if( $key === false )
  194. {
  195. foreach( $this->sessions as $session )
  196. $errors[] = curl_error( $session );
  197. }
  198. else
  199. $errors[] = curl_error( $this->sessions[$key] );
  200. return $errors;
  201. }
  202. /**
  203. * Returns an array of session error numbers
  204. * @param $key int, optional session key to retun error on
  205. * @return array of error codes
  206. */
  207. public function errorNo( $key = false )
  208. {
  209. if( $key === false )
  210. {
  211. foreach( $this->sessions as $session )
  212. $errors[] = curl_errno( $session );
  213. }
  214. else
  215. $errors[] = curl_errno( $this->sessions[$key] );
  216. return $errors;
  217. }
  218. }
  219. ?>