Я не уверен, что именно Gmail делает для индикатора выполнения, но вы можете добиться чего-то похожего в PHP, хотя это может быть немного сложно.
Сначала объясним, почему ваши примеры не работают:
Если вы эхом и спите, как в первом примере, это никогда не сработает. Ajax выполняет полный запрос, то есть если ответ не завершится, он будет ждать. Когда вы зацикливаетесь и спите, запрос не «закрывается» до тех пор, пока не завершится выполнение сценария PHP.
Если вы используете сеанс, как в другом примере, проблема становится хранилищем сеансов. Хранилище, как правило, блокируется во время выполнения скрипта, и оно не будет обновляться, чтобы учесть тот тип проверки прогресса, который вы хотите.
Что вы можете сделать, это записать прогресс в файл (или в базу данных) вручную. Например:
file_put_contents('progress.txt', 1);
Затем попросите другой скрипт прочитать файл и вывести его содержимое.
Это должно работать, потому что file_put_contents открывает, записывает и закрывает файл.
Использование какого-либо другого языка, кроме PHP, облегчит его. Многопоточность, возможно, облегчит, но не является обязательным требованием. Тем не менее, наличие непрерывно запущенного процесса сделает его проще (PHP запускает процесс только в течение вашего запроса и затем завершается)