PHP неблокирующий http запрос - PullRequest
0 голосов
/ 10 января 2019

В PHP я создаю систему хуков для проекта, над которым я сейчас работаю. Система проверит в базе данных наличие внешних файлов, которые должны быть выполнены при срабатывании ловушки.

Чтобы достичь этого, я думал об использовании curl, единственная проблема состоит в том, что curl блокирует остальную часть кода для выполнения. То, что я хочу, это просто отправить HTTP-запрос на указанный URL-адрес и не ждать ответа вообще. Мы не заботимся о статусе. Заказчик должен убедиться, что код работает.

Большая проблема заключается в том, что мы все еще используем PHP 5.5.9 :( Таким образом, решение должно работать с этим, пока мы не сможем перейти на PHP 7.2

Какие-нибудь идеи или побуждения для достижения этого?

1 Ответ

0 голосов
/ 10 января 2019

Запустите отдельный процесс в фоновом режиме, чтобы отправить запрос. Даже если вы используете асинхронный http-запрос (независимо от используемого языка), вы все равно должны дождаться завершения запроса, прежде чем выйти из скрипта / программы.

PHP - это не Java, каждый раз, когда скрипт PHP завершается, все ресурсы будут уничтожаться, если асинхронный http-запрос не завершится, он будет отменен.

Вы можете вызвать "nohup / path / your_script" для выполнения некоторых фоновых задач.

Подсказка: открытые файлы PHP не помечаются как FD_CLOEXEC, поэтому, если у вас есть долгосрочная фоновая задача, вы должны сначала закрыть унаследованные файловые дескрипторы, иначе произойдет утечка ресурсов.

Вот несколько кодов C, которые я использовал, чтобы помочь запускать фоновые задачи в PHP: сначала он закрывает все унаследованные файловые дескрипторы, перенаправляет stdout / stderr в / dev / null, затем входит в фоновый режим (как nohup)

/*
gcc -m32 bgexec.c  -o bgexec
*/
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void close_fds()
{
    char buf[256];
    struct dirent *dp;
    snprintf(buf, 255, "/proc/%i/fd/", getpid());
    DIR *dir = opendir(buf);
    while ((dp = readdir(dir)) != NULL) {
        if(dp->d_name[0] && dp->d_name[0] != '.') {
            //printf("fd: %s\n", dp->d_name);
            close(atoi(dp->d_name));
        }
    }
    closedir(dir);
}

int main(int argc, char *argv[])
{
    int pid;
    signal(SIGCLD, SIG_IGN);   // no defunct when no wait();
    if (argc < 2)
        return fprintf(stderr, "No arguments given\n"), 1;

    /* Fork it */
    pid = fork();
    if(pid < 0)
        return fprintf(stderr, "Couldn't fork\n"), 127;

    if (pid == 0) {
        /* Child */
        setsid();
        umask ( 0 ); /* clear file mode creation mask */
        close_fds();

        int fd = open("/dev/null", O_RDWR);
        dup2(0, 1);
        dup2(0, 2);
        signal(SIGHUP, SIG_IGN);   // no hup
        signal(SIGCLD, SIG_DFL);   // keep away from 'exec' returns ECHILD
        /* Execute it */
        execv(argv[1], &argv[1]);
        exit(127);
    }
    return 0;
}
...