When the child process created by pcntl_fork()
runs exit(0)
also the parent process ends.
I say end and not exist, because I see a strange behavior: the request ends with an empty output (with HTTP code 200), but when I make a new request the previous ones appear in the Xdebug call stack in VSC that are still running.
In this image I made 2 requests:
Am I doing somthing wrong?
<?php
class Register extends Auth
{
public function sendInvite(string $email, bool $isRegistred = false, string $token = ''): bool
{
if (!$isRegistred) {
$this->db->insert('users', ["email" => $email]);
}
if (!$token) {
$code = $this->generateInvite($email);
} else {
$code = $token;
}
include_once __DIR__ . "/../send-email.php";
$comapny = COMPANY_NAME;
$lang = $this->lang;
$temaplates = $this->db->get('settings', ['value [JSON]'], ['name' => 'templates']);
$template = $temaplates['value']['invitation_mail'];
$map = ['email' => $email, 'link' => WEBSITE_URL . '/register/verify/?token=' . $code, 'company' => $comapny];
$templateParserd = ShortcodeReplacer($template, $map);
$html = "<!DOCTYPE html><html lang=\"%s\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><title>Invito</title></head><body>%s</body></html>";
$html = sprintf($html, $lang, $templateParserd);
$smtp = new SendEmail([$email], "Verify your email", $html);
$result = $smtp->send();
if ($result['status'] == 'error') {
eje($result['message'], EJE_ERROR);
} else {
eje("Email inviata con successo", EJE_SUCCESS);
}
return false;
}
public function generateInvite(string $email)
{
// pipe creation
if (!function_exists('pcntl_fork')) {
eje('PCNTL functions not available on this PHP installation', EJE_ERROR);
die;
}
$pipe = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP);
if ($pipe === false) {
eje('Failed to create pipe', EJE_ERROR);
exit();
}
$pid = pcntl_fork();
if ($pid == -1) {
die('Failed to fork');
} elseif ($pid) {
// Parent process
fclose($pipe[0]); // Closes the reading side of the pipe
$data_received = fread($pipe[1], 1024);
do {
$data_received = fread($pipe[1], 1024);
usleep(100);
} while (!$data_received);
$code = $data_received;
fclose($pipe[1]); // Closes the writing side of the pipe
pcntl_waitpid($pid, $status); // Wait for the specific child process to exit
return $code;
} else {
// Child process
fclose($pipe[1]); // Closes the writing side of the pipe
$code = $this->generateInvitationCode($email);
fwrite($pipe[0], $code);
fclose($pipe[0]); // Closes the reading side of the pipe
// return $code;
exit(0); // Terminate the child process
}
}
}
The expected behavior I after the child process exits, the parent process in the method generateInvite()
will return $code
to sendInvite()
, where was called in the first place.