Last active
December 25, 2021 00:55
-
-
Save jkoop/a3c0e6bb7572f58b70fd5f7511b70e8f to your computer and use it in GitHub Desktop.
php7.4 - helper function for curl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// https://gist.github.com/jkoop/a3c0e6bb7572f58b70fd5f7511b70e8f | |
/** | |
* `return->body->json` => `json_decode(return->body->dump)` | |
* | |
* @param string $url URL will not be url-encoded | |
* @param array $fields | |
* @param string $method HTTP method to use; defaults to GET | |
* @param array $headers associative array of HTTP headers to send with request; bad characters will be silently filtered out | |
* @param callable $beforeExec function to give curl object to before executing curl object | |
* @return object full response as object properties: status, headers, body | |
*/ | |
function curl(string $url, array $fields = [], string $method = 'GET', array $headers = [], ?callable $beforeExec = null): object { | |
$curl = curl_init(); | |
if ($method == 'POST') { | |
curl_setopt($curl, CURLOPT_URL, $url); | |
curl_setopt($curl, CURLOPT_POSTFIELDS, $fields); | |
} else if (!empty($fields)) { | |
curl_setopt($curl, CURLOPT_URL, $url . '?' . http_build_query($fields)); | |
} else { | |
curl_setopt($curl, CURLOPT_URL, $url); | |
} | |
$headerStrings = []; | |
array_map(function ($k, $v) use (&$headerStrings) { | |
$k = str_replace(' ', '_', $k); | |
$k = str_replace(':', '_', $k); | |
$v = str_replace("\n", '_', $v); | |
$v = str_replace("\r", '_', $v); | |
$headerStrings[] = $k . ': ' . $v; | |
}, array_keys($headers), array_values($headers)); | |
curl_setopt_array($curl, [ | |
CURLOPT_CUSTOMREQUEST => $method, | |
CURLOPT_HTTPHEADER => $headerStrings, | |
CURLOPT_HEADER => true, | |
CURLOPT_RETURNTRANSFER => true, | |
]); | |
$data = curl_exec($curl); | |
if (curl_errno($curl)) { | |
die('Error: ' . curl_error($curl)); | |
} | |
if (is_callable($beforeExec)) $beforeExec($curl); | |
curl_close($curl); | |
$lengthOfStatus = strpos($data, "\r\n"); | |
$startOfHeaders = $lengthOfStatus + 2; | |
$lengthOfHeaders = strpos($data, "\r\n\r\n") - $startOfHeaders; | |
$startOfBody = strpos($data, "\r\n\r\n") + 4; | |
$status = [ | |
'dump' => substr($data, 0, $lengthOfStatus), | |
]; | |
$headers = [ | |
'dump' => substr($data, $startOfHeaders, $lengthOfHeaders), | |
]; | |
$body = [ | |
'dump' => substr($data, $startOfBody), | |
]; | |
$status['number'] = (int)explode(' ', $status['dump'])[1]; | |
$status['text'] = substr($status['dump'], strpos($status['dump'], (string)$status['number']) + 4); | |
array_map( | |
function ($line) use (&$headers) { | |
$num = strpos($line, ': '); | |
if (!$num) return; | |
$key = substr($line, 0, $num); | |
$val = substr($line, $num + 2); | |
$headers[$key] = $val; | |
$headers[str_replace('-', '_', $key)] = $val; | |
}, | |
explode("\r\n", $headers['dump']) | |
); | |
$body['json'] = json_decode($body['dump']); // returns null on error | |
return (object)[ | |
'status' => (object)$status, | |
'headers' => (object)$headers, | |
'body' => (object)$body, | |
]; | |
} | |
/* | |
example: | |
curl('https://youtube.googleapis.com/youtube/v3/channels', [ | |
'part' => 'snippet', | |
'id' => 'dQw4w9WgXcQ', | |
]) => { | |
"status": { | |
"dump": "HTTP\/2 403 Forbidden", | |
"number": 403, | |
"text": "Forbidden" // is taken from ->dump | |
}, | |
"headers": { | |
"dump": "vary: X-Origin\r ... 000; v=\"46,43\"", | |
"vary": "Origin,Accept-Encoding", | |
"content-type": "application\/json; charset=UTF-8", | |
"content_type": "application\/json; charset=UTF-8", | |
"date": "Sun, 22 Aug 2021 20:18:37 GMT", | |
"server": "scaffolding on HTTPServer2", | |
"cache-control": "private", | |
"cache_control": "private", | |
... | |
}, | |
"body": { | |
"dump": "{\n \"error\": ... NIED\"\n }\n}\n", | |
"json": { | |
"error": { | |
"code": 403, | |
"message": "The request is missing a valid API key.", | |
"errors": [{ | |
"message": "The request is missing a valid API key.", | |
"domain": "global", | |
"reason": "forbidden" | |
}], | |
"status": "PERMISSION_DENIED" | |
} | |
} | |
} | |
} | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment