У меня есть сайт социальной сети, использующий инфраструктуру Elgg, и я должен сделать повторный вызов внешнего API для каждого поста в блоге, который указан на моей странице активности.
Моя страница зависит от ответа, чтобы определить, какой тип значка отображать в меню для каждого сообщения в блоге. Когда в блоге большое количество постов, страница отрисовывается вечно, так как она ожидает завершения всех ответов перед отображением.
Есть ли способ для PHP немедленно отобразить страницу и затем выполнить вызовы конечной точке в фоновом режиме, а затем обновить значки для каждого сообщения в блоге по мере возврата ответов? Приведенный ниже код должен пролить некоторый свет на то, что я пытаюсь сделать:
// Each blog entity has a menu that is attached, this function is called as we iterate through a collection of blog posts
function river_menu_handler($hook, $type, $items, $params) {
// Setup environment vars
$docroot = $_SERVER["DOCUMENT_ROOT"];
$Dotenv = new Loader($docroot . 'mod/fc-plugin/views/default/resources/.env');
$Dotenv->parse()->putenv(true);
$signature_verified = false;
$address = '';
$secret = getenv('APP_SECRET');
$app_id = getenv('APP_ID');
if (elgg_in_context('widgets')) {
return $items;
}
$item = $params['item'];
$entity = $item->getObjectEntity();
if (elgg_instanceof($entity, 'object', 'blog')){
// call out to api to validate blog post
$authString = $app_id . ':' . $secret;
$auth_id = urlencode($entity->auth_id);
$content_hash = urlencode($entity->content_hash);
$envelope_id = urlencode($entity->envelope_id);
$response = validateSignature($auth_id, $content_hash, $envelope_id, $authString);
$response_json = json_decode($response, true);
if (isset($response_json['errorCode'])) {
$errorCode = $response_json['errorCode'];
if ($errorCode == 0) {
$signature_verified = $response_json['signatureVerified'];
$address = $response_json['address'];
if ($signature_verified) {
$items[] = \ElggMenuItem::factory([
'name' => 'verify',
'href' => 'https://ropsten.etherscan.io/address/' . $address,
'text' => elgg_view_icon('round-checkmark'),
'title' => 'This post has been Verified',
'priority' => 200,
]);
return $items;
} else {
$items[] = \ElggMenuItem::factory([
'name' => 'verify',
//'href' => 'action/verify_post',
'text' => elgg_view_icon('ban'),
'title' => 'This post is not Verified',
'priority' => 200,
]);
return $items;
}
} elseif ($errorCode == 1) {
$items[] = \ElggMenuItem::factory([
'name' => 'verify',
'text' => elgg_view_icon('clock'),
'title' => 'This post is pending Verification',
'priority' => 200,
]);
return $items;
} else {
$items[] = \ElggMenuItem::factory([
'name' => 'verify',
'text' => elgg_view_icon('ban'),
'title' => 'This post is not Verified',
'priority' => 200,
]);
return $items;
}
} else {
// no error code returned here from FactChain but got an exception
$items[] = \ElggMenuItem::factory([
'name' => 'verify',
//'href' => 'action/verify_post',
'text' => elgg_view_icon('ban'),
'title' => 'This post is not Verified',
'priority' => 200,
]);
return $items;
}
}
else {
return;
}
И служба выполняет запрос cUrl:
function validateSignature($auth_id, $content_hash, $envelope_id, $authString) {
$ch = curl_init();
$authorization = 'Authorization: Basic ' . base64_encode($authString);
$validate_url = 'https://api.myfcapi.com/api/envelopes/validate/' . $auth_id .'/' . $content_hash . '/' . $envelope_id;
curl_setopt($ch, CURLOPT_URL, $validate_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array($authorization ));
curl_setopt($ch, CURLINFO_HEADER_OUT, 1);
$response = curl_exec($ch);
$json = json_decode($response, true);
$err = curl_error($ch);
if($err) {
echo "cURL Error: " . $err;
}
// Check HTTP status code
if (!curl_errno($ch)) {
switch ($http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE)) {
case 200: # OK
break;
case 502: # server error
system_message('Received 500 Error from Server');
break;
case 400: # bad request
$jsonResponse = json_decode($response, true);
$message = $jsonResponse['message'];
break;
default:
echo 'Unexpected HTTP code: ', $validate_url, "\n";
}
}
curl_close($ch);
return $response;
}