mirror of
https://github.com/php-curl-class/php-curl-class.git
synced 2026-08-27 10:33:37 +00:00
Remove support for parallel requests
This commit is contained in:
+35
-110
@@ -11,8 +11,6 @@ class Curl
|
||||
private $headers = array();
|
||||
private $options = array();
|
||||
|
||||
private $multi_parent = false;
|
||||
private $multi_child = false;
|
||||
private $before_send_function = null;
|
||||
private $success_function = null;
|
||||
private $error_function = null;
|
||||
@@ -23,7 +21,6 @@ class Curl
|
||||
private $xml_pattern = '~^(?:text/|application/(?:atom\+|rss\+)?)xml~i';
|
||||
|
||||
public $curl;
|
||||
public $curls;
|
||||
|
||||
public $error = false;
|
||||
public $error_code = 0;
|
||||
@@ -59,70 +56,14 @@ class Curl
|
||||
$this->headers = new CaseInsensitiveArray();
|
||||
}
|
||||
|
||||
public function get($url_mixed, $data = array())
|
||||
public function get($url, $data = array())
|
||||
{
|
||||
if (is_array($url_mixed)) {
|
||||
$curl_multi = curl_multi_init();
|
||||
$this->multi_parent = true;
|
||||
|
||||
$this->curls = array();
|
||||
|
||||
foreach ($url_mixed as $url) {
|
||||
$curl = new Curl();
|
||||
$curl->multi_child = true;
|
||||
|
||||
$curl->beforeSend($this->before_send_function);
|
||||
$curl->success($this->success_function);
|
||||
$curl->error($this->error_function);
|
||||
$curl->complete($this->complete_function);
|
||||
|
||||
$curl->base_url = $url;
|
||||
$curl->url = $this->buildURL($url, $data);
|
||||
$curl->setOpt(CURLOPT_URL, $curl->url, $curl->curl);
|
||||
$curl->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
|
||||
$curl->setOpt(CURLOPT_HTTPGET, true);
|
||||
$this->curls[] = $curl;
|
||||
|
||||
$curlm_error_code = curl_multi_add_handle($curl_multi, $curl->curl);
|
||||
if (!($curlm_error_code === CURLM_OK)) {
|
||||
throw new \ErrorException('cURL multi add handle error: ' . curl_multi_strerror($curlm_error_code));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->curls as $ch) {
|
||||
foreach ($this->options as $key => $value) {
|
||||
$ch->setOpt($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
curl_multi_select($curl_multi);
|
||||
$status = curl_multi_exec($curl_multi, $active);
|
||||
} while ($status === CURLM_CALL_MULTI_PERFORM || $active);
|
||||
|
||||
while (!($info_array = curl_multi_info_read($curl_multi)) === false) {
|
||||
if (!($info_array['msg'] === CURLMSG_DONE)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($this->curls as $ch) {
|
||||
if ($ch->curl === $info_array['handle']) {
|
||||
$ch->curl_error_code = $info_array['result'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->curls as $ch) {
|
||||
$this->exec($ch);
|
||||
}
|
||||
} else {
|
||||
$this->base_url = $url_mixed;
|
||||
$this->url = $this->buildURL($url_mixed, $data);
|
||||
$this->setOpt(CURLOPT_URL, $this->url);
|
||||
$this->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
|
||||
$this->setOpt(CURLOPT_HTTPGET, true);
|
||||
return $this->exec();
|
||||
}
|
||||
$this->base_url = $url;
|
||||
$this->url = $this->buildURL($url, $data);
|
||||
$this->setOpt(CURLOPT_URL, $this->url);
|
||||
$this->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
|
||||
$this->setOpt(CURLOPT_HTTPGET, true);
|
||||
return $this->exec();
|
||||
}
|
||||
|
||||
public function post($url, $data = array())
|
||||
@@ -306,10 +247,8 @@ class Curl
|
||||
$this->setOpt(CURLOPT_COOKIEJAR, $cookie_jar);
|
||||
}
|
||||
|
||||
public function setOpt($option, $value, $_ch = null)
|
||||
public function setOpt($option, $value)
|
||||
{
|
||||
$ch = $_ch === null ? $this->curl : $_ch;
|
||||
|
||||
$required_options = array(
|
||||
CURLINFO_HEADER_OUT => 'CURLINFO_HEADER_OUT',
|
||||
CURLOPT_RETURNTRANSFER => 'CURLOPT_RETURNTRANSFER',
|
||||
@@ -320,7 +259,7 @@ class Curl
|
||||
}
|
||||
|
||||
$this->options[$option] = $value;
|
||||
return curl_setopt($ch, $option, $value);
|
||||
return curl_setopt($this->curl, $option, $value);
|
||||
}
|
||||
|
||||
public function getOpt($option)
|
||||
@@ -335,12 +274,6 @@ class Curl
|
||||
|
||||
public function close()
|
||||
{
|
||||
if ($this->multi_parent) {
|
||||
foreach ($this->curls as $curl) {
|
||||
$curl->close();
|
||||
}
|
||||
}
|
||||
|
||||
if (is_resource($this->curl)) {
|
||||
curl_close($this->curl);
|
||||
}
|
||||
@@ -493,67 +426,59 @@ class Curl
|
||||
|
||||
protected function exec($_ch = null)
|
||||
{
|
||||
$ch = $_ch === null ? $this : $_ch;
|
||||
|
||||
$ch->call($this->before_send_function, $ch);
|
||||
$this->call($this->before_send_function);
|
||||
|
||||
$response_headers_fh = fopen('php://memory', 'wb+');
|
||||
|
||||
// Fallback to storing data in a temporary file when storing data in
|
||||
// memory errors with "Warning: curl_setopt(): cannot represent a stream
|
||||
// of type MEMORY as a STDIO FILE*".
|
||||
if (!@$ch->setOpt(CURLOPT_WRITEHEADER, $response_headers_fh)) {
|
||||
if (!@$this->setOpt(CURLOPT_WRITEHEADER, $response_headers_fh)) {
|
||||
$response_headers_fh = fopen('php://temp', 'wb+');
|
||||
$ch->setOpt(CURLOPT_WRITEHEADER, $response_headers_fh);
|
||||
$this->setOpt(CURLOPT_WRITEHEADER, $response_headers_fh);
|
||||
}
|
||||
|
||||
if ($ch->multi_child) {
|
||||
$ch->raw_response = curl_multi_getcontent($ch->curl);
|
||||
} else {
|
||||
$ch->raw_response = curl_exec($ch->curl);
|
||||
$ch->curl_error_code = curl_errno($ch->curl);
|
||||
}
|
||||
$this->raw_response = curl_exec($this->curl);
|
||||
$this->curl_error_code = curl_errno($this->curl);
|
||||
|
||||
rewind($response_headers_fh);
|
||||
$ch->raw_response_headers = stream_get_contents($response_headers_fh);
|
||||
$this->raw_response_headers = stream_get_contents($response_headers_fh);
|
||||
fclose($response_headers_fh);
|
||||
|
||||
$ch->curl_error_message = curl_error($ch->curl);
|
||||
$ch->curl_error = !($ch->curl_error_code === 0);
|
||||
$ch->http_status_code = curl_getinfo($ch->curl, CURLINFO_HTTP_CODE);
|
||||
$ch->http_error = in_array(floor($ch->http_status_code / 100), array(4, 5));
|
||||
$ch->error = $ch->curl_error || $ch->http_error;
|
||||
$ch->error_code = $ch->error ? ($ch->curl_error ? $ch->curl_error_code : $ch->http_status_code) : 0;
|
||||
$this->curl_error_message = curl_error($this->curl);
|
||||
$this->curl_error = !($this->curl_error_code === 0);
|
||||
$this->http_status_code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
|
||||
$this->http_error = in_array(floor($this->http_status_code / 100), array(4, 5));
|
||||
$this->error = $this->curl_error || $this->http_error;
|
||||
$this->error_code = $this->error ? ($this->curl_error ? $this->curl_error_code : $this->http_status_code) : 0;
|
||||
|
||||
$ch->request_headers = $this->parseRequestHeaders(curl_getinfo($ch->curl, CURLINFO_HEADER_OUT));
|
||||
$ch->response_headers = $this->parseResponseHeaders($ch->raw_response_headers);
|
||||
list($ch->response, $ch->raw_response) = $this->parseResponse($ch->response_headers, $ch->raw_response);
|
||||
$this->request_headers = $this->parseRequestHeaders(curl_getinfo($this->curl, CURLINFO_HEADER_OUT));
|
||||
$this->response_headers = $this->parseResponseHeaders($this->raw_response_headers);
|
||||
list($this->response, $this->raw_response) = $this->parseResponse($this->response_headers, $this->raw_response);
|
||||
|
||||
$ch->http_error_message = '';
|
||||
if ($ch->error) {
|
||||
if (isset($ch->response_headers['Status-Line'])) {
|
||||
$ch->http_error_message = $ch->response_headers['Status-Line'];
|
||||
$this->http_error_message = '';
|
||||
if ($this->error) {
|
||||
if (isset($this->response_headers['Status-Line'])) {
|
||||
$this->http_error_message = $this->response_headers['Status-Line'];
|
||||
}
|
||||
}
|
||||
$ch->error_message = $ch->curl_error ? $ch->curl_error_message : $ch->http_error_message;
|
||||
$this->error_message = $this->curl_error ? $this->curl_error_message : $this->http_error_message;
|
||||
|
||||
if (!$ch->error) {
|
||||
$ch->call($this->success_function, $ch);
|
||||
if (!$this->error) {
|
||||
$this->call($this->success_function);
|
||||
} else {
|
||||
$ch->call($this->error_function, $ch);
|
||||
$this->call($this->error_function);
|
||||
}
|
||||
|
||||
$ch->call($this->complete_function, $ch);
|
||||
$this->call($this->complete_function);
|
||||
|
||||
return $ch->response;
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
private function call($function)
|
||||
{
|
||||
if (is_callable($function)) {
|
||||
$args = func_get_args();
|
||||
array_shift($args);
|
||||
call_user_func_array($function, $args);
|
||||
call_user_func_array($function, array($this));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -887,89 +887,6 @@ class CurlTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertEquals('foo=bar&baz[qux]=&baz[wibble]=wobble', urldecode($test->curl->response));
|
||||
}
|
||||
|
||||
public function testParallelRequests()
|
||||
{
|
||||
$test = new Test();
|
||||
$curl = $test->curl;
|
||||
$curl->setHeader('X-DEBUG-TEST', 'request_uri');
|
||||
$curl->get(array(
|
||||
Test::TEST_URL . 'a/',
|
||||
Test::TEST_URL . 'b/',
|
||||
Test::TEST_URL . 'c/',
|
||||
), array(
|
||||
'foo' => 'bar',
|
||||
));
|
||||
|
||||
$len = strlen('/a/?foo=bar');
|
||||
$this->assertEquals('/a/?foo=bar', substr($curl->curls['0']->response, - $len));
|
||||
$this->assertEquals('/b/?foo=bar', substr($curl->curls['1']->response, - $len));
|
||||
$this->assertEquals('/c/?foo=bar', substr($curl->curls['2']->response, - $len));
|
||||
}
|
||||
|
||||
public function testParallelRequestErrors()
|
||||
{
|
||||
$test = new Test();
|
||||
$curl = $test->curl;
|
||||
$curl->setOpt(CURLOPT_CONNECTTIMEOUT_MS, 4000);
|
||||
$curl->complete(function ($instance) use (&$success_called, &$error_called, &$complete_called) {
|
||||
PHPUnit_Framework_Assert::assertTrue($instance->error);
|
||||
PHPUnit_Framework_Assert::assertTrue($instance->curl_error);
|
||||
PHPUnit_Framework_Assert::assertEquals(CURLE_OPERATION_TIMEOUTED, $instance->error_code);
|
||||
PHPUnit_Framework_Assert::assertEquals(CURLE_OPERATION_TIMEOUTED, $instance->curl_error_code);
|
||||
});
|
||||
$curl->get(array(
|
||||
Test::ERROR_URL . 'a/',
|
||||
Test::ERROR_URL . 'b/',
|
||||
Test::ERROR_URL . 'c/',
|
||||
));
|
||||
}
|
||||
|
||||
public function testParallelSetOptions()
|
||||
{
|
||||
$test = new Test();
|
||||
$curl = $test->curl;
|
||||
$curl->setHeader('X-DEBUG-TEST', 'server');
|
||||
$curl->setOpt(CURLOPT_USERAGENT, 'useragent');
|
||||
$curl->complete(function ($instance) {
|
||||
PHPUnit_Framework_Assert::assertEquals('useragent', $instance->response);
|
||||
});
|
||||
$curl->get(array(
|
||||
Test::TEST_URL,
|
||||
), array(
|
||||
'key' => 'HTTP_USER_AGENT',
|
||||
));
|
||||
}
|
||||
|
||||
public function testParallelUrl()
|
||||
{
|
||||
$data = array('foo' => 'bar');
|
||||
|
||||
$test = new Test();
|
||||
$curl = $test->curl;
|
||||
$curl->setHeader('X-DEBUG-TEST', 'server');
|
||||
$curl->complete(function ($instance) use ($data) {
|
||||
PHPUnit_Framework_Assert::assertEquals(Test::TEST_URL, $instance->base_url);
|
||||
PHPUnit_Framework_Assert::assertEquals(Test::TEST_URL . '?' . http_build_query($data), $instance->url);
|
||||
});
|
||||
$curl->get(array(
|
||||
Test::TEST_URL,
|
||||
), $data);
|
||||
}
|
||||
|
||||
public function testParallelGetOptions()
|
||||
{
|
||||
$test = new Test();
|
||||
$curl = $test->curl;
|
||||
$curl->setHeader('X-DEBUG-TEST', 'server');
|
||||
$curl->setOpt(CURLOPT_USERAGENT, 'useragent');
|
||||
$curl->complete(function ($instance) {
|
||||
PHPUnit_Framework_Assert::assertEquals('useragent', $instance->getOpt(CURLOPT_USERAGENT));
|
||||
});
|
||||
$curl->get(array(
|
||||
Test::TEST_URL,
|
||||
));
|
||||
}
|
||||
|
||||
public function testSuccessCallback()
|
||||
{
|
||||
$before_send_called = false;
|
||||
@@ -1020,79 +937,6 @@ class CurlTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertTrue($complete_called);
|
||||
}
|
||||
|
||||
public function testParallelSuccessCallback()
|
||||
{
|
||||
$success_called = false;
|
||||
$error_called = false;
|
||||
$complete_called = false;
|
||||
|
||||
$success_called_once = false;
|
||||
$error_called_once = false;
|
||||
$complete_called_once = false;
|
||||
|
||||
$test = new Test();
|
||||
$curl = $test->curl;
|
||||
$curl->setHeader('X-DEBUG-TEST', 'get');
|
||||
|
||||
$curl->success(function ($instance) use (
|
||||
&$success_called,
|
||||
&$error_called,
|
||||
&$complete_called,
|
||||
&$success_called_once
|
||||
) {
|
||||
PHPUnit_Framework_Assert::assertInstanceOf('Curl\Curl', $instance);
|
||||
PHPUnit_Framework_Assert::assertFalse($success_called);
|
||||
PHPUnit_Framework_Assert::assertFalse($error_called);
|
||||
PHPUnit_Framework_Assert::assertFalse($complete_called);
|
||||
$success_called = true;
|
||||
$success_called_once = true;
|
||||
});
|
||||
$curl->error(function ($instance) use (
|
||||
&$success_called,
|
||||
&$error_called,
|
||||
&$complete_called,
|
||||
&$curl,
|
||||
&$error_called_once
|
||||
) {
|
||||
PHPUnit_Framework_Assert::assertInstanceOf('Curl\Curl', $instance);
|
||||
PHPUnit_Framework_Assert::assertFalse($success_called);
|
||||
PHPUnit_Framework_Assert::assertFalse($error_called);
|
||||
PHPUnit_Framework_Assert::assertFalse($complete_called);
|
||||
$error_called = true;
|
||||
$error_called_once = true;
|
||||
});
|
||||
$curl->complete(function ($instance) use (
|
||||
&$success_called,
|
||||
&$error_called,
|
||||
&$complete_called,
|
||||
&$complete_called_once
|
||||
) {
|
||||
PHPUnit_Framework_Assert::assertInstanceOf('Curl\Curl', $instance);
|
||||
PHPUnit_Framework_Assert::assertTrue($success_called);
|
||||
PHPUnit_Framework_Assert::assertFalse($error_called);
|
||||
PHPUnit_Framework_Assert::assertFalse($complete_called);
|
||||
$complete_called = true;
|
||||
$complete_called_once = true;
|
||||
|
||||
PHPUnit_Framework_Assert::assertTrue($success_called);
|
||||
PHPUnit_Framework_Assert::assertFalse($error_called);
|
||||
PHPUnit_Framework_Assert::assertTrue($complete_called);
|
||||
|
||||
$success_called = false;
|
||||
$error_called = false;
|
||||
$complete_called = false;
|
||||
});
|
||||
|
||||
$curl->get(array(
|
||||
Test::TEST_URL . 'a/',
|
||||
Test::TEST_URL . 'b/',
|
||||
Test::TEST_URL . 'c/',
|
||||
));
|
||||
|
||||
$this->assertTrue($success_called_once || $error_called_once);
|
||||
$this->assertTrue($complete_called_once);
|
||||
}
|
||||
|
||||
public function testErrorCallback()
|
||||
{
|
||||
$before_send_called = false;
|
||||
|
||||
Reference in New Issue
Block a user