Skip to content

Instantly share code, notes, and snippets.

@jkoop
Last active December 25, 2021 00:55
Show Gist options
  • Save jkoop/a3c0e6bb7572f58b70fd5f7511b70e8f to your computer and use it in GitHub Desktop.
Save jkoop/a3c0e6bb7572f58b70fd5f7511b70e8f to your computer and use it in GitHub Desktop.
php7.4 - helper function for curl
<?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