2014-02-18 18:15:12 +01:00
|
|
|
<?php
|
|
|
|
namespace cURL;
|
|
|
|
|
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcher;
|
|
|
|
|
|
|
|
class Request extends EventDispatcher implements RequestInterface
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var resource cURL handler
|
|
|
|
*/
|
|
|
|
protected $ch;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var RequestsQueue Queue instance when requesting async
|
|
|
|
*/
|
|
|
|
protected $queue;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Options Object containing options for current request
|
|
|
|
*/
|
|
|
|
protected $options = null;
|
2017-05-22 22:32:15 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var bool Whether requests to the target host should be serialized or not.
|
|
|
|
*/
|
|
|
|
protected $serializeRequests = false;
|
2014-02-18 18:15:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create new cURL handle
|
|
|
|
*
|
|
|
|
* @param string $url The URL to fetch.
|
|
|
|
*/
|
|
|
|
public function __construct($url = null)
|
|
|
|
{
|
|
|
|
if ($url !== null) {
|
|
|
|
$this->getOptions()->set(CURLOPT_URL, $url);
|
|
|
|
}
|
|
|
|
$this->ch = curl_init();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the cURL\Options instance
|
|
|
|
* Creates empty one if does not exist
|
|
|
|
*
|
|
|
|
* @return Options
|
|
|
|
*/
|
|
|
|
public function getOptions()
|
|
|
|
{
|
|
|
|
if (!isset($this->options)) {
|
2015-06-19 18:51:09 +02:00
|
|
|
$this->options = new Options();
|
2014-02-18 18:15:12 +01:00
|
|
|
}
|
|
|
|
return $this->options;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets Options
|
2017-05-21 17:52:56 +02:00
|
|
|
*
|
2014-02-18 18:15:12 +01:00
|
|
|
* @param Options $options Options
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function setOptions(Options $options)
|
|
|
|
{
|
|
|
|
$this->options = $options;
|
|
|
|
}
|
2017-05-21 17:52:56 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Closes cURL resource and frees the memory.
|
|
|
|
* It is neccessary when you make a lot of requests
|
|
|
|
* and you want to avoid fill up the memory.
|
|
|
|
*/
|
|
|
|
public function __destruct() {
|
|
|
|
if (isset($this->ch)) {
|
|
|
|
curl_close($this->ch);
|
|
|
|
}
|
|
|
|
}
|
2014-02-18 18:15:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns cURL raw resource
|
|
|
|
*
|
|
|
|
* @return resource cURL handle
|
|
|
|
*/
|
|
|
|
public function getHandle()
|
|
|
|
{
|
|
|
|
return $this->ch;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get unique id of cURL handle
|
|
|
|
* Useful for debugging or logging.
|
|
|
|
*
|
|
|
|
* @return int
|
|
|
|
*/
|
|
|
|
public function getUID()
|
|
|
|
{
|
|
|
|
return (int)$this->ch;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Perform a cURL session.
|
|
|
|
* Equivalent to curl_exec().
|
|
|
|
* This function should be called after initializing a cURL
|
|
|
|
* session and all the options for the session are set.
|
|
|
|
*
|
2015-06-19 18:51:09 +02:00
|
|
|
* Warning: it doesn't fire 'complete' event.
|
|
|
|
*
|
2014-02-18 18:15:12 +01:00
|
|
|
* @return Response
|
|
|
|
*/
|
|
|
|
public function send()
|
|
|
|
{
|
|
|
|
if ($this->options instanceof Options) {
|
|
|
|
$this->options->applyTo($this);
|
|
|
|
}
|
|
|
|
$content = curl_exec($this->ch);
|
|
|
|
|
|
|
|
$response = new Response($this, $content);
|
|
|
|
$errorCode = curl_errno($this->ch);
|
|
|
|
if ($errorCode !== CURLE_OK) {
|
|
|
|
$response->setError(new Error(curl_error($this->ch), $errorCode));
|
|
|
|
}
|
|
|
|
return $response;
|
|
|
|
}
|
2015-06-19 18:51:09 +02:00
|
|
|
|
2017-05-21 17:52:56 +02:00
|
|
|
/**
|
|
|
|
* Binds the request to a given RequestQueue.
|
|
|
|
*
|
|
|
|
* @param \cURL\RequestsQueue $requestsQueue
|
|
|
|
* @throws \cURL\Exception
|
|
|
|
*/
|
2017-05-22 22:32:15 +02:00
|
|
|
public function attachTo(RequestsQueue $requestsQueue)
|
|
|
|
{
|
2017-05-21 17:52:56 +02:00
|
|
|
if (isset($this->queue)) {
|
|
|
|
throw new Exception('Already bound to a RequestQueue.');
|
|
|
|
}
|
|
|
|
$this->queue = $requestsQueue;
|
|
|
|
$this->queue->attach($this);
|
|
|
|
}
|
|
|
|
|
2017-05-22 22:32:15 +02:00
|
|
|
/**
|
|
|
|
* Whether to serialize requests to the same host or not.
|
|
|
|
*
|
|
|
|
* @param bool $serialize
|
|
|
|
*/
|
|
|
|
public function setSerialize($serialize = true)
|
|
|
|
{
|
|
|
|
$this->serializeRequests = $serialize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public function getSerialize()
|
|
|
|
{
|
|
|
|
return $this->serializeRequests;
|
|
|
|
}
|
|
|
|
|
2015-06-19 18:51:09 +02:00
|
|
|
/**
|
|
|
|
* Creates new RequestsQueue with single Request attached to it
|
|
|
|
* and calls RequestsQueue::socketPerform() method.
|
|
|
|
*
|
|
|
|
* @see RequestsQueue::socketPerform()
|
|
|
|
*/
|
|
|
|
public function socketPerform()
|
2014-02-18 18:15:12 +01:00
|
|
|
{
|
|
|
|
if (!isset($this->queue)) {
|
2015-06-19 18:51:09 +02:00
|
|
|
$this->queue = new RequestsQueue();
|
2014-02-18 18:15:12 +01:00
|
|
|
$this->queue->attach($this);
|
|
|
|
}
|
|
|
|
return $this->queue->socketPerform();
|
|
|
|
}
|
2015-06-19 18:51:09 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Calls socketSelect() on previously created RequestsQueue
|
|
|
|
*
|
|
|
|
* @see RequestsQueue::socketSelect()
|
|
|
|
*/
|
2014-02-18 18:15:12 +01:00
|
|
|
public function socketSelect($timeout = 1)
|
|
|
|
{
|
|
|
|
if (!isset($this->queue)) {
|
2015-06-19 18:51:09 +02:00
|
|
|
throw new Exception('You need to call socketPerform() before.');
|
2014-02-18 18:15:12 +01:00
|
|
|
}
|
|
|
|
return $this->queue->socketSelect($timeout);
|
|
|
|
}
|
|
|
|
}
|