1) Ваш вариант на аяксе, проблема в том что сессия заблокируется, и вы не перейдете на другие страницы пока скрипт не завершит выполнение, тут можно вызвать session_write_close(); но все же это костыльный вариант, но рабочий.
2) Если у вас апач стоит, то вы можете сделать так:
echo 'ok';
set_time_limit(0);
ignore_user_abort(true);
header("Connection: close");
ob_flush();
flush();
sleep(10);
file_put_contents('test.txt', 'success');
Но на хостинге у меня так не прокатило, т.к там apache+nginx, а он заголовок Connection не пропускает, ставит свой "keep-alive"
3) Вариант который мне подошел. Мне нужно было при оформлении заказа делать тяжелые операции (рассылка почты, отправка в CRM, логи и .п), но при этом результат этих операции не важен.
public function isWin(){
return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
}
public function backgroundProcess($command){
if(!$this->isWin()){
$command = $command.' > /dev/null &';
}
$result = exec($command);
return $result;
}
Работает на linux, суть в том что к команде в конце добавляется "&" в конце, что запускает новый процесс.
$obj->backgroundProcess('php /path../bg.php');
P.S Вообще это все исключительные ситуации, PHP не должен работать в асинхронном режиме. Может вам лучше при каждом заходе на страницу делать записи в БД. А затем настроить планировщик задач CRON который будет выполнять ваш скрипт по этим записям.