Асинхронный вызов PHP, который запускает метод контроллера

Я хочу выполнить событие с нажатием кнопки:

localhost/codeigniter/controller/method

Метод будет извлекать ключевые слова из веб-страницы (ов) и хранить их в БД. В нем есть несколько под-методов, которые также должны выполняться в фоновом режиме. Я не хочу, чтобы пользователь ждал в течение этой продолжительности. Я прочитал это . Будет ли это работать для меня? Любые другие предложения по спасению жизни приветствуются.

1

2 ответы

Основываясь на этой теме, я сделал это для моего проекта codeigniter. Он работает отлично. Вы можете использовать любую функцию в фоновом режиме.

Контроллер, который принимает асинхронные вызовы.

class Daemon extends CI_Controller
{
   //Remember to disable CI's csrf-checks for this controller

    function index( )
    {
        ignore_user_abort( 1 );
        try
        {
            if ( strcmp( $_SERVER['REMOTE_ADDR'], $_SERVER['SERVER_ADDR'] ) != 0 && !in_array( $_SERVER['REMOTE_ADDR'], $this->config->item( 'proxy_ips' ) ) )
            {
                log_message( "error", "Daemon called from untrusted IP-address: " . $_SERVER['REMOTE_ADDR'] );
                show_404( '/daemon' );
                return;
            }

            $this->load->library( 'encrypt' );
            $params = unserialize( urldecode( $this->encrypt->decode( $_POST['data'] ) ) );
            unset( $_POST );
            $model = array_shift( $params );
            $method = array_shift( $params );
            $this->load->model( $model );
            if ( call_user_func_array( array( $this->$model, $method ), $params ) === FALSE )
            {
                log_message( "error", "Daemon could not call: " . $model . "::" . $method . "()" );
            }
        }
        catch(Exception $e)
        {
            log_message( "error", "Daemon has error: " . $e->getMessage( ) . $e->getFile( ) . $e->getLine( ) );
        }
    }
}

И библиотека, которая выполняет асинхронные вызовы

class Daemon
{
    public function execute_background( /* model, method, params */ )
    {
        $ci = &get_instance( );
       //The callback URL (its ourselves)
        $parts = parse_url( $ci->config->item( 'base_url' ) . "/daemon" );
        if ( strcmp( $parts['scheme'], 'https' ) == 0 )
        {
            $port = 443;
            $host = "ssl://" . $parts['host'];
        }
        else 
        {
            $port = 80;
            $host = $parts['host'];
        }
        if ( ( $fp = fsockopen( $host, isset( $parts['port'] ) ? $parts['port'] : $port, $errno, $errstr, 30 ) ) === FALSE )
        {
            throw new Exception( "Internal server error: background process could not be started" );
        }
        $ci->load->library( 'encrypt' );
        $post_string = "data=" . urlencode( $ci->encrypt->encode( serialize( func_get_args( ) ) ) );
        $out = "POST " . $parts['path'] . " HTTP/1.1\r\n";
        $out .= "Host: " . $host . "\r\n";
        $out .= "Content-Type: application/x-www-form-urlencoded\r\n";
        $out .= "Content-Length: " . strlen( $post_string ) . "\r\n";
        $out .= "Connection: Close\r\n\r\n";
        $out .= $post_string;
        fwrite( $fp, $out );
        fclose( $fp );
    }
}

Этот метод можно вызвать для обработки любой модели :: method() в «background». Он использует переменные аргументы.

$this->load->library('daemon');
$this->daemon->execute_background( 'model', 'method', $arg1, $arg2, ... );
1
добавлено
Его нельзя использовать для метода контроллера? И у меня нет данных POST, поэтому $ params не требуется. Будет ли это работать тогда?
добавлено автор SilentAssassin, источник
И вы попытались дать ссылку на поток, на основе которого вы создали это, но его там нет.
добавлено автор SilentAssassin, источник
Я попробовал перевести два моих метода в модель. Я их запускал, но результат первого метода требуется для повторного выполнения второго метода в фоновом режиме. И его недоступно, так что неопределенная ошибка возвращается. Это не работает в моем сценарии.
добавлено автор SilentAssassin, источник
Он будет работать без $ _POST, просто измените его :) Это общий фоновый процессор. Вы не можете поместить оба в модель. Контроллер вызывается из Apache, который был вызван из вашего собственного процесса PHP.
добавлено автор Patrick Savalle, источник

Вы можете написать в сокете:

$fp = fsockopen($_SERVER['HTTP_HOST'], 80, $errno, $errstr, 30);
$data = http_build_query($params, '', '&'); //$params - array with POST data
fwrite($fp, "POST " . ('/controller/action') . " HTTP/1.1\r\n");
fwrite($fp, "Host: ".$_SERVER['HTTP_HOST']."\r\n");
fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fwrite($fp, "Content-Length: " . strlen($data) . "\r\n");
fwrite($fp, "Connection: Close\r\n\r\n");
fwrite($fp, $data);
fclose($fp);
0
добавлено
Где будет указан URL, который я упомянул в вопросе?
добавлено автор SilentAssassin, источник
Для метода контроллера нет данных POST. Все данные уже доступны для него из базы данных. Я просто хочу вызвать метод. $ params не требуется. Как я могу просто вызвать метод?
добавлено автор SilentAssassin, источник
добавлено автор Vlad, источник
phpGeeks
phpGeeks
3 620 участник(ов)

Best PHP chat Еще: @dbGeeks - базы данных @phpGeeksJunior - новичкам @moscowProgers - IT Москва @ebanoePhp - весёлый канал о PHP @laravel_pro - Laravel @jobGeeks - вакансии @jsChat - JS Правила: https://t.me/phpGeeks/764859 ДР - 28.03.2016

PHP
PHP
1 309 участник(ов)

Группа про современный PHP. Обсуждаем ООП, TDD, BDD, DDD, SOLID, GRASP и прочие крутые базворды Для ознакомления: https://gist.github.com/mkusher/711bd46f0b62fbae851182e6fb3b1839 Группа PHP для новичков @phpGeeksJunior Вакансии: https://t.me/fordev

PHP — вакансии, поиск работы и аналитика
PHP — вакансии, поиск работы и аналитика
1 251 участник(ов)

Публикуем вакансии и запросы на поиск работы по направлению PHP, Laravel, Symfony, Yii и т.д. Здесь всё: full-time, part-time, remote и разовые подработки. См. также: @qa_jobs, @devops_jobs, @javascript_jobs, @nodejs_jobs, @uiux_jobs, @products_jobs

phpGeeksJunior
phpGeeksJunior
980 участник(ов)

Группа для новичков. Не стесняйтесь задавать вопросы по php. Не флудить!!!! Правила и полезные ссылки https://gist.github.com/exileed/a53dd0617b35a705ff44b38c8028e6a5 Бест от пхпгикс https://t.me/best_of_phpgeeks

phpclub.ru
phpclub.ru
872 участник(ов)

Официальный чат phpclub.ru - остерегайтесь подделок #rules Правила группы - уважайте друг друга. Скриншоты -> ссылками. Код -> pastebin.com. Вакансии строго -> https://goo.gl/4bNxym, в чат ссылку. За рекламу и мат - БАН!

Devall | PHP
Devall | PHP
272 участник(ов)

Пристанище для восходящих звёзд разработки, которые перейдут на более адекватные языки. http://combot.org/chat/-1001014863761 Инвайт: j.mp/devallphp