As far as I know PHP does not support asynchronous events natively, precisely because it is synchronous, ie it is a layer of requisition and reply and I don’t see so much need to run two events at the same time.
About your problem maybe it’s the lack of wait();
, The Guzzle documentation says that the use is with PSR-7 thus:
$request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org/get');
$promise = $client->sendAsync($request)->then(function ($response) {
echo 'I completed! ' . $response->getBody();
});
$promise->wait();
anyway for the front-end this will be imperceptible and for the server I do not see the "advantage" of using this, because the larger layer of the script will still have to wait for the events to end (when to use wait();
).
I do not know what means they use, but if you want to study on the subject there is:
https://stackoverflow.com/a/13872965/1518921
Also has reactPHP as said here Run PHP function asynchronously
Async hack (hhvm)
In the hack language (hhvm) there are asynchronous methods:
However for the answer you will not feel changes (I believe), but in the back-end it is as if it were more than one Thread and so can perform more than one task without expecting another, example (only works with <?hh
):
<?hh
namespace Hack\UserDocumentation\Async\Intro\Examples\Limtations;
async function do_cpu_work(): Awaitable<void> {
print("Start CPU work\n");
$a = 0;
$b = 1;
$list = [$a, $b];
for ($i = 0; $i < 1000; ++$i) {
$c = $a + $b;
$list[] = $c;
$a = $b;
$b = $c;
}
print("End CPU work\n");
}
async function do_sleep(): Awaitable<void> {
print("Start sleep\n");
sleep(1);
print("End sleep\n");
}
async function main(): Awaitable<void> {
print("Start of main()\n");
await \HH\Asio\v([
do_cpu_work(),
do_sleep(),
]);
print("End of main()\n");
}
\HH\Asio\join(main());
PHP CLI
An alternative would be to execute a command as if it were in the terminal and wait or not the answer remembering the async
, I did this for a very specific case, where there was a script that when processing consumed a lot of Apache, so using exec
I did something like this:
Windows, one should run something like:
set QUERY_STRING="foo=1&bar=2"
start /B cmd /S /C php -c php.ini c:/wamp/www/arquivo.php
The start /B cmd /S /C
is to wait for the command to end.
Like-Unix, one should run something like:
export QUERY_STRING="foo=1&bar=2";
php -c php.ini "/etc/www/arquivo.php";
The whole script looked like this (note that I did this script some time ago, if it fails let me know):
function async($phpScript, $query_string='') {
$php_exe = 'php';
$iniFile = php_ini_loaded_file();
if (false === $iniFile) {
echo 'Erro ao carregar php.ini not loaded (php_ini_loaded_file = false)';
exit;
} else if (false === file_exists($phpScript)) {
echo 'Script não econtrado: ' . $phpScript;
exit;
}
$output = array();
$exec = '';
if (stripos(PHP_OS, 'WIN') !== false) {
foreach ($_SERVER as $key => $value) {
if ($key !== 'HTTP_ACCEPT_ENCODING' && $key !== 'QUERY_STRING') {
$exec .= 'set ' . $key . '=' . escapeshellcmd($value) . '& ';
}
}
$exec .= 'set QUERY_STRING=' . escapeshellcmd($query_string) . '& ';
$exec .= 'start /B cmd /S /C php ' . escapeshellcmd(' -c ' . $iniFile . ' ' . $phpScript);
} else {
foreach ($_SERVER as $key => $value) {
if ($key !== 'HTTP_ACCEPT_ENCODING' && $key !== 'QUERY_STRING') {
$exec .= 'export ' . $key . '=' . escapeshellarg($value) . '; ';
}
}
$exec .= 'export QUERY_STRING=' . escapeshellarg($query_string) . '; ';
$exec .= 'php -c ' . escapeshellarg($iniFile) . ' ' .
escapeshellarg($phpScript);// . ' >/dev/null 2>&1 &';
}
exec($exec, $output, $status);
return array(
'status' => $status,
'command' => $exec,
'output' => $output
);
}
I commented on the >/dev/null 2>&1 &
because in Debian6 (at the time) I had some problem, but you can use it in the terminal like this:
export QUERY_STRING="foo=1&bar=2";
php -c php.ini "/etc/www/arquivo.php" >/dev/null 2>&1 &
This is not quite "asynchronous" for the script, but it is possible to run files that consume more memory without affecting Apache and Ngnix for example, because it runs separately, I know it’s not quite what you asked for, but I’m not sure what your need really is.
Usually the technique used is to execute a shell command. In your case, it may be that the library has some bug or is not able to detect the operating system properly to apply a proper command. The command varies between Linux distributions and also Windows. Make sure that’s not the problem.
– Daniel Omine