Skip to content

Instantly share code, notes, and snippets.

@lyoshenka
Last active January 19, 2019 18:34
Show Gist options
  • Save lyoshenka/a6f69465fada9deabaf1129b111ecb89 to your computer and use it in GitHub Desktop.
Save lyoshenka/a6f69465fada9deabaf1129b111ecb89 to your computer and use it in GitHub Desktop.
Very simple wrapper around php's curl
<?php
class Curl
{
const GET = 'GET';
const POST = 'POST';
const PUT = 'PUT';
public static function get($url, $params = [], $options = [])
{
list ($status, $headers, $body) = static::doCurl(static::GET, $url, $params, $options);
return $body;
}
public static function post($url, $params = [], $options = [])
{
list ($status, $headers, $body) = static::doCurl(static::POST, $url, $params, $options);
return $body;
}
public static function put($url, $params = [], $options = [])
{
list ($status, $headers, $body) = static::doCurl(static::PUT, $url, $params, $options);
return $body;
}
public static function doCurl($method, $url, $params = [], $options = [])
{
$defaults = [
'headers' => [],
'verify' => true,
'timeout' => 5,
'follow_redirects' => true,
'user_agent' => null,
'proxy' => null,
'password' => null,
'cookie' => null,
'json_post' => false,
];
$invalid = array_diff_key($options, $defaults);
if ($invalid)
{
throw new DomainException('Invalid curl options: ' . join(', ', array_keys($invalid)));
}
$options = array_merge($defaults, $options);
if (!in_array($method, [static::GET, static::POST, static::PUT]))
{
throw new DomainException('Invalid method: ' . $method);
}
if ($options['headers'] && $options['headers'] !== array_values($options['headers'])) // associative array
{
throw new DomainException('Headers must not be an associative array. Its a simple array with values of the form "Header: value"');
}
$ch = curl_init();
if ($method == static::GET && $params)
{
$url .= (strpos($url, '?') === false ? '?' : '&') . http_build_query($params);
}
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $options['headers'],
CURLOPT_RETURNTRANSFER => true,
// CURLOPT_FAILONERROR => true,
CURLOPT_FOLLOWLOCATION => $options['follow_redirects'],
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => $options['timeout'],
CURLOPT_SSL_VERIFYPEER => $options['verify'],
// CURLOPT_SSL_VERIFYHOST => $options['verify'] ? 2 : 0, // php doc says to always keep this at 2 in production environments
CURLOPT_USERAGENT => $options['user_agent'],
]);
$postFields = '';
if ($method === static::POST || $method === static::PUT)
{
$postFields = $options['json_post'] ? json_encode($params) : http_build_query($params);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
if ($method === static::POST)
{
curl_setopt($ch, CURLOPT_POST, true);
}
else
{
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
}
}
if ($options['proxy'])
{
curl_setopt($ch, CURLOPT_PROXY, $options['proxy']);
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
}
if ($options['password'])
{
curl_setopt($ch, CURLOPT_USERPWD, $options['password']);
}
if ($options['cookie'])
{
curl_setopt($ch, CURLOPT_COOKIE, $options['cookie']);
}
$startingResponse = false;
$responseHeaders = [];
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $h) use (&$responseHeaders, &$startingResponse)
{
$value = trim($h);
if ($value === '')
{
$startingResponse = true;
}
elseif ($startingResponse)
{
$startingResponse = false;
$responseHeaders = [$value];
}
else
{
$responseHeaders[] = $value;
}
return strlen($h);
});
$responseContent = curl_exec($ch);
$statusCode = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch))
{
throw new CurlException($ch);
}
curl_close($ch);
// DEBUGGING
$curlString = 'curl ' . escapeshellarg($url) . ' --compressed ';
foreach ($options['headers'] as $header)
{
$curlString .= '-H ' . escapeshellarg($header) . ' ';
}
if ($method === static::POST || $method === static::PUT)
{
$curlString .= '--request ' . $method . ' --data ' . escapeshellarg($postFields) . ' ';
}
return [$statusCode, $responseHeaders, $responseContent, trim($curlString)];
}
}
class CurlException extends Exception
{
protected $errno, $error, $info, $handle;
public function __construct($curlHandle, Exception $previous = null)
{
$this->handle = $curlHandle;
$this->errno = curl_errno($curlHandle);
$this->error = curl_error($curlHandle);
$this->info = curl_getinfo($curlHandle);
parent::__construct($this->error, $this->errno, $previous);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment