1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282 |
- <?php
- namespace App\Services\Common;
- class CurlService
- {
- const VERSION = '5.1.0';
- const DEFAULT_TIMEOUT = 30;
- public static $RFC2616 = array(
- // RFC2616: "any CHAR except CTLs or separators".
- // CHAR = <any US-ASCII character (octets 0 - 127)>
- // CTL = <any US-ASCII control character
- // (octets 0 - 31) and DEL (127)>
- // separators = "(" | ")" | "<" | ">" | "@"
- // | "," | ";" | ":" | "\" | <">
- // | "/" | "[" | "]" | "?" | "="
- // | "{" | "}" | SP | HT
- // SP = <US-ASCII SP, space (32)>
- // HT = <US-ASCII HT, horizontal-tab (9)>
- // <"> = <US-ASCII double-quote mark (34)>
- '!', '#', '$', '%', '&', "'", '*', '+', '-', '.', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B',
- 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
- 'Y', 'Z', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
- 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '|', '~',
- );
- public static $RFC6265 = array(
- // RFC6265: "US-ASCII characters excluding CTLs, whitespace DQUOTE, comma, semicolon, and backslash".
- // %x21
- '!',
- // %x23-2B
- '#', '$', '%', '&', "'", '(', ')', '*', '+',
- // %x2D-3A
- '-', '.', '/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':',
- // %x3C-5B
- '<', '=', '>', '?', '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
- 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[',
- // %x5D-7E
- ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
- 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
- );
- public $curl;
- public $id = null;
- public $error = false;
- public $errorCode = 0;
- public $errorMessage = null;
- public $curlError = false;
- public $curlErrorCode = 0;
- public $curlErrorMessage = null;
- public $httpError = false;
- public $httpStatusCode = 0;
- public $httpErrorMessage = null;
- public $baseUrl = null;
- public $url = null;
- public $requestHeaders = null;
- public $responseHeaders = null;
- public $rawResponseHeaders = '';
- public $response = null;
- public $rawResponse = null;
- public $beforeSendFunction = null;
- public $downloadCompleteFunction = null;
- public $successFunction = null;
- public $errorFunction = null;
- public $completeFunction = null;
- public $fileHandle = null;
- private $cookies = array();
- private $responseCookies = array();
- private $headers = array();
- private $options = array();
- private $jsonDecoder = null;
- private $jsonPattern = '/^(?:application|text)\/(?:[a-z]+(?:[\.-][0-9a-z]+){0,}[\+\.]|x-)?json(?:-[a-z]+)?/i';
- private $xmlDecoder = null;
- private $xmlPattern = '~^(?:text/|application/(?:atom\+|rss\+)?)xml~i';
- private $defaultDecoder = null;
- private static $deferredProperties = array(
- 'effectiveUrl',
- 'totalTime',
- );
- /**
- * Construct
- *
- * @access public
- * @param $base_url
- * @throws \ErrorException
- */
- public function __construct($base_url = null)
- {
- if (!extension_loaded('curl')) {
- throw new \ErrorException('cURL library is not loaded');
- }
- $this->curl = curl_init();
- $this->id = 1;
- $this->setDefaultUserAgent();
- $this->setDefaultJsonDecoder();
- $this->setDefaultXmlDecoder();
- $this->setDefaultTimeout();
- $this->setOpt(CURLINFO_HEADER_OUT, true);
- $this->setOpt(CURLOPT_HEADERFUNCTION, array($this, 'headerCallback'));
- $this->setOpt(CURLOPT_RETURNTRANSFER, true);
- $this->headers = new CaseInsensitiveArrayService();
- $this->setURL($base_url);
- $this->rfc2616 = array_fill_keys(self::$RFC2616, true);
- $this->rfc6265 = array_fill_keys(self::$RFC6265, true);
- }
- /**
- * Before Send
- *
- * @access public
- * @param $callback
- */
- public function beforeSend($callback)
- {
- $this->beforeSendFunction = $callback;
- }
- /**
- * Build Post Data
- *
- * @access public
- * @param $data
- *
- * @return array|string
- */
- public function buildPostData($data)
- {
- $binary_data = false;
- if (is_array($data)) {
- // Return JSON-encoded string when the request's content-type is JSON.
- if (isset($this->headers['Content-Type']) &&
- preg_match($this->jsonPattern, $this->headers['Content-Type'])) {
- $json_str = json_encode($data);
- if (!($json_str === false)) {
- $data = $json_str;
- }
- } else {
- // Manually build a single-dimensional array from a multi-dimensional array as using curl_setopt($ch,
- // CURLOPT_POSTFIELDS, $data) doesn't correctly handle multi-dimensional arrays when files are
- // referenced.
- if (self::is_array_multidim($data)) {
- $data = self::array_flatten_multidim($data);
- }
- // Modify array values to ensure any referenced files are properly handled depending on the support of
- // the @filename API or CURLFile usage. This also fixes the warning "curl_setopt(): The usage of the
- // @filename API for file uploading is deprecated. Please use the CURLFile class instead". Ignore
- // non-file values prefixed with the @ character.
- foreach ($data as $key => $value) {
- if (is_string($value) && strpos($value, '@') === 0 && is_file(substr($value, 1))) {
- $binary_data = true;
- if (class_exists('CURLFile')) {
- $data[$key] = new \CURLFile(substr($value, 1));
- }
- } elseif ($value instanceof \CURLFile) {
- $binary_data = true;
- }
- }
- }
- }
- if (!$binary_data && (is_array($data) || is_object($data))) {
- $data = http_build_query($data, '', '&');
- }
- return $data;
- }
- /**
- * Call
- *
- * @access public
- */
- public function call()
- {
- $args = func_get_args();
- $function = array_shift($args);
- if (is_callable($function)) {
- array_unshift($args, $this);
- call_user_func_array($function, $args);
- }
- }
- /**
- * Close
- *
- * @access public
- */
- public function close()
- {
- if (is_resource($this->curl)) {
- curl_close($this->curl);
- }
- $this->options = null;
- $this->jsonDecoder = null;
- $this->xmlDecoder = null;
- }
- /**
- * Complete
- *
- * @access public
- * @param $callback
- */
- public function complete($callback)
- {
- $this->completeFunction = $callback;
- }
- /**
- * Progress
- *
- * @access public
- * @param $callback
- */
- public function progress($callback)
- {
- $this->setOpt(CURLOPT_PROGRESSFUNCTION, $callback);
- $this->setOpt(CURLOPT_NOPROGRESS, false);
- }
- /**
- * Delete
- *
- * @access public
- * @param $url
- * @param $query_parameters
- * @param $data
- *
- * @return string
- */
- public function delete($url, $query_parameters = array(), $data = array())
- {
- if (is_array($url)) {
- $data = $query_parameters;
- $query_parameters = $url;
- $url = $this->baseUrl;
- }
- $this->setURL($url, $query_parameters);
- $this->setOpt(CURLOPT_CUSTOMREQUEST, 'DELETE');
- $this->setOpt(CURLOPT_POSTFIELDS, $this->buildPostData($data));
- return $this->exec();
- }
- /**
- * Download Complete
- *
- * @access public
- * @param $fh
- */
- public function downloadComplete($fh)
- {
- if (!$this->error && $this->downloadCompleteFunction) {
- rewind($fh);
- $this->call($this->downloadCompleteFunction, $fh);
- $this->downloadCompleteFunction = null;
- }
- if (is_resource($fh)) {
- fclose($fh);
- }
- // Fix "PHP Notice: Use of undefined constant STDOUT" when reading the
- // PHP script from stdin. Using null causes "Warning: curl_setopt():
- // supplied argument is not a valid File-Handle resource".
- if (!defined('STDOUT')) {
- define('STDOUT', fopen('php://stdout', 'w'));
- }
- // Reset CURLOPT_FILE with STDOUT to avoid: "curl_exec(): CURLOPT_FILE
- // resource has gone away, resetting to default".
- $this->setOpt(CURLOPT_FILE, STDOUT);
- // Reset CURLOPT_RETURNTRANSFER to tell cURL to return subsequent
- // responses as the return value of curl_exec(). Without this,
- // curl_exec() will revert to returning boolean values.
- $this->setOpt(CURLOPT_RETURNTRANSFER, true);
- }
- /**
- * Download
- *
- * @access public
- * @param $url
- * @param $mixed_filename
- *
- * @return boolean
- */
- public function download($url, $mixed_filename)
- {
- if (is_callable($mixed_filename)) {
- $this->downloadCompleteFunction = $mixed_filename;
- $fh = tmpfile();
- } else {
- $filename = $mixed_filename;
- $fh = fopen($filename, 'wb');
- }
- $this->setOpt(CURLOPT_FILE, $fh);
- $this->get($url);
- $this->downloadComplete($fh);
- return ! $this->error;
- }
- /**
- * Error
- *
- * @access public
- * @param $callback
- */
- public function error($callback)
- {
- $this->errorFunction = $callback;
- }
- /**
- * Exec
- *
- * @access public
- * @param $ch
- *
- * @return mixed Returns the value provided by parseResponse.
- */
- public function exec($ch = null)
- {
- $this->responseCookies = array();
- if ($ch === null) {
- $this->call($this->beforeSendFunction);
- $this->rawResponse = curl_exec($this->curl);
- $this->curlErrorCode = curl_errno($this->curl);
- } else {
- $this->rawResponse = curl_multi_getcontent($ch);
- }
- $this->curlErrorMessage = curl_error($this->curl);
- $this->curlError = !($this->curlErrorCode === 0);
- $this->httpStatusCode = $this->getInfo(CURLINFO_HTTP_CODE);
- $this->httpError = in_array(floor($this->httpStatusCode / 100), array(4, 5));
- $this->error = $this->curlError || $this->httpError;
- $this->errorCode = $this->error ? ($this->curlError ? $this->curlErrorCode : $this->httpStatusCode) : 0;
- // NOTE: CURLINFO_HEADER_OUT set to true is required for requestHeaders
- // to not be empty (e.g. $curl->setOpt(CURLINFO_HEADER_OUT, true);).
- if ($this->getOpt(CURLINFO_HEADER_OUT) === true) {
- $this->requestHeaders = $this->parseRequestHeaders($this->getInfo(CURLINFO_HEADER_OUT));
- }
- $this->responseHeaders = $this->parseResponseHeaders($this->rawResponseHeaders);
- $this->response = $this->parseResponse($this->responseHeaders, $this->rawResponse);
- $this->httpErrorMessage = '';
- if ($this->error) {
- if (isset($this->responseHeaders['Status-Line'])) {
- $this->httpErrorMessage = $this->responseHeaders['Status-Line'];
- }
- }
- $this->errorMessage = $this->curlError ? $this->curlErrorMessage : $this->httpErrorMessage;
- if (!$this->error) {
- $this->call($this->successFunction);
- } else {
- $this->call($this->errorFunction);
- }
- $this->call($this->completeFunction);
- return $this->response;
- }
- /**
- * Get
- *
- * @access public
- * @param $url
- * @param $data
- *
- * @return mixed Returns the value provided by exec.
- */
- public function get($url, $data = array())
- {
- if (is_array($url)) {
- $data = $url;
- $url = $this->baseUrl;
- }
- $this->setURL($url, $data);
- $this->setOpt(CURLOPT_CUSTOMREQUEST, 'GET');
- $this->setOpt(CURLOPT_HTTPGET, true);
- return $this->exec();
- }
- /**
- * Get Info
- *
- * @access public
- * @param $opt
- */
- public function getInfo($opt)
- {
- return curl_getinfo($this->curl, $opt);
- }
- /**
- * Get Opt
- *
- * @access public
- * @param $option
- *
- * @return mixed
- */
- public function getOpt($option)
- {
- return $this->options[$option];
- }
- /**
- * Head
- *
- * @access public
- * @param $url
- * @param $data
- *
- * @return string
- */
- public function head($url, $data = array())
- {
- if (is_array($url)) {
- $data = $url;
- $url = $this->baseUrl;
- }
- $this->setURL($url, $data);
- $this->setOpt(CURLOPT_CUSTOMREQUEST, 'HEAD');
- $this->setOpt(CURLOPT_NOBODY, true);
- return $this->exec();
- }
- /**
- * Header Callback
- *
- * @access public
- * @param $ch
- * @param $header
- *
- * @return integer
- */
- public function headerCallback($ch, $header)
- {
- if (preg_match('/^Set-Cookie:\s*([^=]+)=([^;]+)/mi', $header, $cookie) === 1) {
- $this->responseCookies[$cookie[1]] = trim($cookie[2], " \n\r\t\0\x0B");
- }
- $this->rawResponseHeaders .= $header;
- return strlen($header);
- }
- /**
- * Options
- *
- * @access public
- * @param $url
- * @param $data
- *
- * @return string
- */
- public function options($url, $data = array())
- {
- if (is_array($url)) {
- $data = $url;
- $url = $this->baseUrl;
- }
- $this->setURL($url, $data);
- $this->unsetHeader('Content-Length');
- $this->setOpt(CURLOPT_CUSTOMREQUEST, 'OPTIONS');
- return $this->exec();
- }
- /**
- * Patch
- *
- * @access public
- * @param $url
- * @param $data
- *
- * @return string
- */
- public function patch($url, $data = array())
- {
- if (is_array($url)) {
- $data = $url;
- $url = $this->baseUrl;
- }
- if (is_array($data) && empty($data)) {
- $this->unsetHeader('Content-Length');
- }
- $this->setURL($url);
- $this->setOpt(CURLOPT_CUSTOMREQUEST, 'PATCH');
- $this->setOpt(CURLOPT_POSTFIELDS, $this->buildPostData($data));
- return $this->exec();
- }
- /**
- * Post
- *
- * @access public
- * @param $url
- * @param $data
- * @param $follow_303_with_post If true, will cause 303 redirections to be followed using
- * a POST request (default: false).
- * Notes:
- * - Redirections are only followed if the CURLOPT_FOLLOWLOCATION option is set to true.
- * - According to the HTTP specs (see [1]), a 303 redirection should be followed using
- * the GET method. 301 and 302 must not.
- * - In order to force a 303 redirection to be performed using the same method, the
- * underlying cURL object must be set in a special state (the CURLOPT_CURSTOMREQUEST
- * option must be set to the method to use after the redirection). Due to a limitation
- * of the cURL extension of PHP < 5.5.11 ([2], [3]) and of HHVM, it is not possible
- * to reset this option. Using these PHP engines, it is therefore impossible to
- * restore this behavior on an existing php-curl-class Curl object.
- *
- * @return string
- *
- * [1] https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.2
- * [2] https://github.com/php/php-src/pull/531
- * [3] http://php.net/ChangeLog-5.php#5.5.11
- */
- public function post($url, $data = array(), $follow_303_with_post = false)
- {
- if (is_array($url)) {
- $follow_303_with_post = (bool)$data;
- $data = $url;
- $url = $this->baseUrl;
- }
- $this->setURL($url);
- if ($follow_303_with_post) {
- $this->setOpt(CURLOPT_CUSTOMREQUEST, 'POST');
- } else {
- if (isset($this->options[CURLOPT_CUSTOMREQUEST])) {
- if ((version_compare(PHP_VERSION, '5.5.11') < 0) || defined('HHVM_VERSION')) {
- trigger_error('Due to technical limitations of PHP <= 5.5.11 and HHVM, it is not possible to '
- . 'perform a post-redirect-get request using a php-curl-class Curl object that '
- . 'has already been used to perform other types of requests. Either use a new '
- . 'php-curl-class Curl object or upgrade your PHP engine.',
- E_USER_ERROR);
- } else {
- $this->setOpt(CURLOPT_CUSTOMREQUEST, null);
- }
- }
- }
- $this->setOpt(CURLOPT_POST, true);
- $this->setOpt(CURLOPT_POSTFIELDS, $this->buildPostData($data));
- return $this->exec();
- }
- /**
- * Put
- *
- * @access public
- * @param $url
- * @param $data
- *
- * @return string
- */
- public function put($url, $data = array())
- {
- if (is_array($url)) {
- $data = $url;
- $url = $this->baseUrl;
- }
- $this->setURL($url);
- $this->setOpt(CURLOPT_CUSTOMREQUEST, 'PUT');
- $put_data = $this->buildPostData($data);
- if (empty($this->options[CURLOPT_INFILE]) && empty($this->options[CURLOPT_INFILESIZE])) {
- if (is_string($put_data)) {
- $this->setHeader('Content-Length', strlen($put_data));
- }
- }
- if (!empty($put_data)) {
- $this->setOpt(CURLOPT_POSTFIELDS, $put_data);
- }
- return $this->exec();
- }
- /**
- * Search
- *
- * @access public
- * @param $url
- * @param $data
- *
- * @return string
- */
- public function search($url, $data = array())
- {
- if (is_array($url)) {
- $data = $url;
- $url = $this->baseUrl;
- }
- $this->setURL($url);
- $this->setOpt(CURLOPT_CUSTOMREQUEST, 'SEARCH');
- $put_data = $this->buildPostData($data);
- if (empty($this->options[CURLOPT_INFILE]) && empty($this->options[CURLOPT_INFILESIZE])) {
- if (is_string($put_data)) {
- $this->setHeader('Content-Length', strlen($put_data));
- }
- }
- if (!empty($put_data)) {
- $this->setOpt(CURLOPT_POSTFIELDS, $put_data);
- }
- return $this->exec();
- }
- /**
- * Set Basic Authentication
- *
- * @access public
- * @param $username
- * @param $password
- */
- public function setBasicAuthentication($username, $password = '')
- {
- $this->setOpt(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
- $this->setOpt(CURLOPT_USERPWD, $username . ':' . $password);
- }
- /**
- * Set Digest Authentication
- *
- * @access public
- * @param $username
- * @param $password
- */
- public function setDigestAuthentication($username, $password = '')
- {
- $this->setOpt(CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
- $this->setOpt(CURLOPT_USERPWD, $username . ':' . $password);
- }
- /**
- * Set Cookie
- *
- * @access public
- * @param $key
- * @param $value
- */
- public function setCookie($key, $value)
- {
- $name_chars = array();
- foreach (str_split($key) as $name_char) {
- if (!isset($this->rfc2616[$name_char])) {
- $name_chars[] = rawurlencode($name_char);
- } else {
- $name_chars[] = $name_char;
- }
- }
- $value_chars = array();
- foreach (str_split($value) as $value_char) {
- if (!isset($this->rfc6265[$value_char])) {
- $value_chars[] = rawurlencode($value_char);
- } else {
- $value_chars[] = $value_char;
- }
- }
- $this->cookies[implode('', $name_chars)] = implode('', $value_chars);
- $this->setOpt(CURLOPT_COOKIE, implode('; ', array_map(function($k, $v) {
- return $k . '=' . $v;
- }, array_keys($this->cookies), array_values($this->cookies))));
- }
- /**
- * Get cookie.
- *
- * @access public
- * @param $key
- * @return mixed
- */
- public function getCookie($key)
- {
- return $this->getResponseCookie($key);
- }
- /**
- * Get response cookie.
- *
- * @access public
- * @param $key
- * @return mixed
- */
- public function getResponseCookie($key)
- {
- return isset($this->responseCookies[$key]) ? $this->responseCookies[$key] : null;
- }
- /**
- * Get response cookies.
- *
- * @access public
- * @return array
- */
- public function getResponseCookies()
- {
- return $this->responseCookies;
- }
- /**
- * Set Port
- *
- * @access public
- * @param $port
- */
- public function setPort($port)
- {
- $this->setOpt(CURLOPT_PORT, intval($port));
- }
- /**
- * Set Connect Timeout
- *
- * @access public
- * @param $seconds
- */
- public function setConnectTimeout($seconds)
- {
- $this->setOpt(CURLOPT_CONNECTTIMEOUT, $seconds);
- }
- /**
- * Set Cookie String
- *
- * @access public
- * @param $string
- */
- public function setCookieString($string)
- {
- return $this->setOpt(CURLOPT_COOKIE, $string);
- }
- /**
- * Set Cookie File
- *
- * @access public
- * @param $cookie_file
- */
- public function setCookieFile($cookie_file)
- {
- $this->setOpt(CURLOPT_COOKIEFILE, $cookie_file);
- }
- /**
- * Set Cookie Jar
- *
- * @access public
- * @param $cookie_jar
- */
- public function setCookieJar($cookie_jar)
- {
- $this->setOpt(CURLOPT_COOKIEJAR, $cookie_jar);
- }
- /**
- * Set Default JSON Decoder
- *
- * @access public
- * @param $assoc
- * @param $depth
- * @param $options
- */
- public function setDefaultJsonDecoder()
- {
- $args = func_get_args();
- $this->jsonDecoder = function($response) use ($args) {
- array_unshift($args, $response);
- // Call json_decode() without the $options parameter in PHP
- // versions less than 5.4.0 as the $options parameter was added in
- // PHP version 5.4.0.
- if (version_compare(PHP_VERSION, '5.4.0', '<')) {
- $args = array_slice($args, 0, 3);
- }
- $json_obj = call_user_func_array('json_decode', $args);
- if (!($json_obj === null)) {
- $response = $json_obj;
- }
- return $response;
- };
- }
- /**
- * Set Default XML Decoder
- *
- * @access public
- */
- public function setDefaultXmlDecoder()
- {
- $this->xmlDecoder = function($response) {
- $xml_obj = @simplexml_load_string($response);
- if (!($xml_obj === false)) {
- $response = $xml_obj;
- }
- return $response;
- };
- }
- /**
- * Set Default Decoder
- *
- * @access public
- * @param $decoder string|callable
- */
- public function setDefaultDecoder($decoder = 'json')
- {
- if (is_callable($decoder)) {
- $this->defaultDecoder = $decoder;
- } else {
- if ($decoder === 'json') {
- $this->defaultDecoder = $this->jsonDecoder;
- } elseif ($decoder === 'xml') {
- $this->defaultDecoder = $this->xmlDecoder;
- }
- }
- }
- /**
- * Set Default Timeout
- *
- * @access public
- */
- public function setDefaultTimeout()
- {
- $this->setTimeout(self::DEFAULT_TIMEOUT);
- }
- /**
- * Set Default User Agent
- *
- * @access public
- */
- public function setDefaultUserAgent()
- {
- $user_agent = 'PHP-Curl-Class/' . self::VERSION . ' (+https://github.com/php-curl-class/php-curl-class)';
- $user_agent .= ' PHP/' . PHP_VERSION;
- $curl_version = curl_version();
- $user_agent .= ' curl/' . $curl_version['version'];
- $this->setUserAgent($user_agent);
- }
- /**
- * Set Header
- *
- * @access public
- * @param $key
- * @param $value
- */
- public function setHeader($key, $value)
- {
- $this->headers[$key] = $value;
- $headers = array();
- foreach ($this->headers as $key => $value) {
- $headers[] = $key . ': ' . $value;
- }
- $this->setOpt(CURLOPT_HTTPHEADER, $headers);
- }
- /**
- * Set JSON Decoder
- *
- * @access public
- * @param $function
- */
- public function setJsonDecoder($function)
- {
- if (is_callable($function)) {
- $this->jsonDecoder = $function;
- }
- }
- /**
- * Set XML Decoder
- *
- * @access public
- * @param $function
- */
- public function setXmlDecoder($function)
- {
- if (is_callable($function)) {
- $this->xmlDecoder = $function;
- }
- }
- /**
- * Set Opt
- *
- * @access public
- * @param $option
- * @param $value
- *
- * @return boolean
- */
- public function setOpt($option, $value)
- {
- $required_options = array(
- CURLOPT_RETURNTRANSFER => 'CURLOPT_RETURNTRANSFER',
- );
- if (in_array($option, array_keys($required_options), true) && !($value === true)) {
- trigger_error($required_options[$option] . ' is a required option', E_USER_WARNING);
- }
- $success = curl_setopt($this->curl, $option, $value);
- if ($success) {
- $this->options[$option] = $value;
- }
- return $success;
- }
- /**
- * Set Opts
- *
- * @access public
- * @param $options
- *
- * @return boolean
- * Returns true if all options were successfully set. If an option could not be successfully set, false is
- * immediately returned, ignoring any future options in the options array. Similar to curl_setopt_array().
- */
- public function setOpts($options)
- {
- foreach ($options as $option => $value) {
- if (!$this->setOpt($option, $value)) {
- return false;
- }
- }
- }
- /**
- * Set Referer
- *
- * @access public
- * @param $referer
- */
- public function setReferer($referer)
- {
- $this->setReferrer($referer);
- }
- /**
- * Set Referrer
- *
- * @access public
- * @param $referrer
- */
- public function setReferrer($referrer)
- {
- $this->setOpt(CURLOPT_REFERER, $referrer);
- }
- /**
- * Set Timeout
- *
- * @access public
- * @param $seconds
- */
- public function setTimeout($seconds)
- {
- $this->setOpt(CURLOPT_TIMEOUT, $seconds);
- }
- /**
- * Set Url
- *
- * @access public
- * @param $url
- * @param $data
- */
- public function setURL($url, $data = array())
- {
- $this->baseUrl = $url;
- $this->url = $this->buildURL($url, $data);
- $this->setOpt(CURLOPT_URL, $this->url);
- }
- /**
- * Set User Agent
- *
- * @access public
- * @param $user_agent
- */
- public function setUserAgent($user_agent)
- {
- $this->setOpt(CURLOPT_USERAGENT, $user_agent);
- }
- /**
- * Success
- *
- * @access public
- * @param $callback
- */
- public function success($callback)
- {
- $this->successFunction = $callback;
- }
- /**
- * Unset Header
- *
- * @access public
- * @param $key
- */
- public function unsetHeader($key)
- {
- $this->setHeader($key, '');
- unset($this->headers[$key]);
- }
- /**
- * Verbose
- *
- * @access public
- * @param bool $on
- * @param resource $output
- */
- public function verbose($on = true, $output = STDERR)
- {
- // Turn off CURLINFO_HEADER_OUT for verbose to work. This has the side
- // effect of causing Curl::requestHeaders to be empty.
- if ($on) {
- $this->setOpt(CURLINFO_HEADER_OUT, false);
- }
- $this->setOpt(CURLOPT_VERBOSE, $on);
- $this->setOpt(CURLOPT_STDERR, $output);
- }
- /**
- * Destruct
- *
- * @access public
- */
- public function __destruct()
- {
- $this->close();
- }
- public function __get($name)
- {
- $return = null;
- if (in_array($name, self::$deferredProperties) && is_callable(array($this, $getter = '__get_' . $name))) {
- $return = $this->$name = $this->$getter();
- }
- return $return;
- }
- /**
- * Get Effective Url
- *
- * @access private
- */
- private function __get_effectiveUrl() {
- return $this->getInfo(CURLINFO_EFFECTIVE_URL);
- }
- /**
- * Get Total Time
- *
- * @access private
- */
- private function __get_totalTime() {
- return $this->getInfo(CURLINFO_TOTAL_TIME);
- }
- /**
- * Build Url
- *
- * @access private
- * @param $url
- * @param $data
- *
- * @return string
- */
- private function buildURL($url, $data = array())
- {
- return $url . (empty($data) ? '' : '?' . http_build_query($data, '', '&'));
- }
- /**
- * Parse Headers
- *
- * @access private
- * @param $raw_headers
- *
- * @return array
- */
- private function parseHeaders($raw_headers)
- {
- $raw_headers = preg_split('/\r\n/', $raw_headers, null, PREG_SPLIT_NO_EMPTY);
- $http_headers = new CaseInsensitiveArrayService();
- $raw_headers_count = count($raw_headers);
- for ($i = 1; $i < $raw_headers_count; $i++) {
- list($key, $value) = explode(':', $raw_headers[$i], 2);
- $key = trim($key);
- $value = trim($value);
- // Use isset() as array_key_exists() and ArrayAccess are not compatible.
- if (isset($http_headers[$key])) {
- $http_headers[$key] .= ',' . $value;
- } else {
- $http_headers[$key] = $value;
- }
- }
- return array(isset($raw_headers['0']) ? $raw_headers['0'] : '', $http_headers);
- }
- /**
- * Parse Request Headers
- *
- * @access private
- * @param $raw_headers
- *
- * @return array
- */
- private function parseRequestHeaders($raw_headers)
- {
- $request_headers = new CaseInsensitiveArrayService();
- list($first_line, $headers) = $this->parseHeaders($raw_headers);
- $request_headers['Request-Line'] = $first_line;
- foreach ($headers as $key => $value) {
- $request_headers[$key] = $value;
- }
- return $request_headers;
- }
- /**
- * Parse Response
- *
- * @access private
- * @param $response_headers
- * @param $raw_response
- *
- * @return mixed
- * Provided the content-type is determined to be json or xml:
- * Returns stdClass object when the default json decoder is used and the content-type is json.
- * Returns SimpleXMLElement object when the default xml decoder is used and the content-type is xml.
- */
- private function parseResponse($response_headers, $raw_response)
- {
- $response = $raw_response;
- if (isset($response_headers['Content-Type'])) {
- if (preg_match($this->jsonPattern, $response_headers['Content-Type'])) {
- $json_decoder = $this->jsonDecoder;
- if (is_callable($json_decoder)) {
- $response = $json_decoder($response);
- }
- } elseif (preg_match($this->xmlPattern, $response_headers['Content-Type'])) {
- $xml_decoder = $this->xmlDecoder;
- if (is_callable($xml_decoder)) {
- $response = $xml_decoder($response);
- }
- } else {
- $decoder = $this->defaultDecoder;
- if (is_callable($decoder)) {
- $response = $decoder($response);
- }
- }
- }
- return $response;
- }
- /**
- * Parse Response Headers
- *
- * @access private
- * @param $raw_response_headers
- *
- * @return array
- */
- private function parseResponseHeaders($raw_response_headers)
- {
- $response_header_array = explode("\r\n\r\n", $raw_response_headers);
- $response_header = '';
- for ($i = count($response_header_array) - 1; $i >= 0; $i--) {
- if (stripos($response_header_array[$i], 'HTTP/') === 0) {
- $response_header = $response_header_array[$i];
- break;
- }
- }
- $response_headers = new CaseInsensitiveArrayService();
- list($first_line, $headers) = $this->parseHeaders($response_header);
- $response_headers['Status-Line'] = $first_line;
- foreach ($headers as $key => $value) {
- $response_headers[$key] = $value;
- }
- return $response_headers;
- }
- /**
- * Is Array Assoc
- *
- * @access public
- * @param $array
- *
- * @return boolean
- */
- public static function is_array_assoc($array)
- {
- return (bool)count(array_filter(array_keys($array), 'is_string'));
- }
- /**
- * Is Array Multidim
- *
- * @access public
- * @param $array
- *
- * @return boolean
- */
- public static function is_array_multidim($array)
- {
- if (!is_array($array)) {
- return false;
- }
- return (bool)count(array_filter($array, 'is_array'));
- }
- /**
- * Array Flatten Multidim
- *
- * @access public
- * @param $array
- * @param $prefix
- *
- * @return array
- */
- public static function array_flatten_multidim($array, $prefix = false)
- {
- $return = array();
- if (is_array($array) || is_object($array)) {
- if (empty($array)) {
- $return[$prefix] = '';
- } else {
- foreach ($array as $key => $value) {
- if (is_scalar($value)) {
- if ($prefix) {
- $return[$prefix . '[' . $key . ']'] = $value;
- } else {
- $return[$key] = $value;
- }
- } else {
- if ($value instanceof \CURLFile) {
- $return[$key] = $value;
- } else {
- $return = array_merge(
- $return, self::array_flatten_multidim(
- $value, $prefix ? $prefix . '[' . $key . ']' : $key));
- }
- }
- }
- }
- } elseif ($array === null) {
- $return[$prefix] = $array;
- }
- return $return;
- }
- }
|