Емуляція многопоточности в php, застосовуємо stream-функції

Функції stream_socket є частиною streams і використовуючи їх, ми можемо встановлювати з'єднання і писати / читати дані, які не чекаючи виконання попередньої операції.

Далі в циклі застосовуємо функцію stream_socket_client відкриваючи для кожного URL сокет. Прапор STREAM_CLIENT_ASYNC_CONNECT вказує, що наступне з'єднання треба відкривати асинхронно (Не чекаючи завершення відкриття попереднього), а прапор STREAM_CLIENT_CONNECT потрібен для створення клієнтського з'єднання. У масиві $ write_tasks зберігаються дескриптори сокетів.

Потім, в головному циклі масивів $ read_tasks_ і $ write_tasks_, які передаються функції stream_select, присвоюються масиви, які зберігають сокети для читання і запису. stream_select функція стежить за існуванням даних в потоці, а також приймає такі параметри:
  1. Масив дескрипторів, які очікують завершення операції читання;
  2. Масив дескрипторів, які очікують завершення операції запису;
  3. Для ситуації надходження позасмугових даних - "out-of-band data";
  4. Таймаут.

Масиви за вказівниками відправляються в функцію, і після повернення функцією числа> 0, в них будуть збережені сокети, готові до подальших маніпуляцій.

Далі шукаємо, які сокети доступні для запису даних. Якщо потрібно ще щось відправити перед остаточною відповіддю - видаляємо поточний дескриптор з масиву для запису і записуємо його в масив для читання. Потім, відправляємо потрібні http-заголовки для отримання вмісту.

Далі, в foreach-циклі дивимося сокети доступні для читання, зберігаємо вміст в рядок $ result, видаляємо дескриптор з масиву для читання і закриваємо сокет. Вміст рядка $ result зберігаємо в масив $ results. Виконуємо ці операції, поки у нас є відкриті сокети.

Після виконання скрипта отриманий контент розташовується в масиві $ results.

Отже, ми розглянули рішення нашої задачі із застосуванням функцій stream_socket, в наступній статті розглянемо асинхронні сокети для емуляції многопоточности в PHP.