Issue
This Content is from Stack Overflow. Question asked by Mattia Consiglio
I’m creating an app in PHP to create an API and in reactjs for the front-end.
The server-side is responsible for making calls to WHM/cPanel APIs by returning the processed result to the client-side.
This process can take up to a couple of minutes, and from the client-side I receive an update every second of the currently processed data.
Now I start the process by using shell_exec
and for following requests I get the data from the database that I think is slower and more heavy for the server.
There is another way to run a PHP process in background and access the variables of that process (without involving PHP server extensions)?
PHP
class Api
{
public function getInfo(int $id = null)
{
//check for running complete scans if id is not provided by user
$id = $id === null ? $this->db->select('scans', ['id'], ['status' => 'running', 'type' => 'complete', 'ORDER' => ['id' => 'DESC'], 'LIMIT' => 1])[0]['id'] : $id;
if (!$id) {
$this->db->insert('scans', [
'type' => 'complete',
'status' => 'running',
'start' => date('Y-m-d H:i:s.u')
]);
$id = $this->db->id();
/**Start the getting the info in background */
shell_exec("php " . __DIR__ . DS . "load-all-info.php " . $id . " > /dev/null 2>/dev/null &");
return ege(['status' => 'success', 'process_id' => $id, 'proc_status' => 'running']);
}
//get process status and end time
$query = $this->db->select('scans', ['status', 'scan_data'], ['id' => $id])[0];
$procStatus = $query['status'];
$scanData = $query['scan_data'];
if ($scanData) {
$scanData = json_decode($scanData, true);
return ege(['status' => 'success', 'process_id' => $id, 'proc_status' => $procStatus, 'data' => $scanData]);
}
//get disk infos
$cpusers = $this->db->select('cpusers', ['user', 'domain', 'plan', 'disk_total', 'disk_used', 'disk_perc'], ['scan_id' => $id]);
//get emails infos
$emails =
$this->db->select('emails', ['login', 'user', 'email_total', 'email_used', 'email_perc', 'cpuser'], ['scan_id' => $id, 'ORDER' => 'cpuser']);
//define array with disk infos and emails inside them
$data = array();
foreach ($cpusers as $cpuser) {
$arrEmails = [];
if (!empty($emails)) {
foreach ($emails as $email) {
if ($cpuser['user'] !== $email['cpuser']) {
continue;
}
$email += ['status' => $this->setStatus($email['email_perc'], $email['email_total'], $email['email_used'])];
array_push($arrEmails, $email);
}
}
$cpuser += ['status' => $this->setStatus($cpuser['disk_perc'], $cpuser['disk_total'], $cpuser['disk_used'])];
$cpuser += ['emails' => $arrEmails];
array_push($data, $cpuser);
}
if ($procStatus == 'complete' && !$scanData) {
$dbData = ['date' => date('Y-m-d H:i:s.u'), 'data' => $data];
$this->db->update('scans', [
'scan_data[JSON]' => $dbData
], ['id' => $id]);
}
return ege(['status' => 'success', 'process_id' => $id, 'proc_status' => $procStatus, 'data' => $data]);
}
JS
do {
startTime()
//genarate fetch request
await api
.get({ func: 'info', args: { scanId: scanId }, structure: '/{scanId}' })
.then(myJson => {
...
}
})
.catch(err => {})
diffTime()
//sleep for x ms
await new Promise(r => setTimeout(r, timeDiff))
} while (scanCompleted === false)
Solution
This question is not yet answered, be the first one who answer using the comment. Later the confirmed answer will be published as the solution.
This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.