xandeadx.ru Блог музицирующего веб-девелопера

PHP → Как из php скрипта асинхронно выполнить другой скрипт (т.е. не дожидаясь его окончания)

Опубликовано в

Например есть скрипт a.php, в котором нужно вызвать тяжеловесный скрипт b.php и не дожидаясь его окончания продолжить работу. Одно из решений это сокеты:

// a.php
 
function exec_script($url, $params = array())
{
    $parts = parse_url($url);
 
    if (!$fp = fsockopen($parts['host'], isset($parts['port']) ? $parts['port'] : 80))
    {
        return false;
    }
 
    $data = http_build_query($params, '', '&');
 
    fwrite($fp, "POST " . (!empty($parts['path']) ? $parts['path'] : '/') . " HTTP/1.1\r\n");
    fwrite($fp, "Host: " . $parts['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);
 
    return true;
}
 
exec_script('http://example.com/b.php', array('foo' => 'bar'));

В примере, в скрипте b.php будет доступна переменная $_POST['foo'] со значением bar.

Похожие записи

Комментарии RSS

О! Спасибо! То что нужно!

Если в параметрах передать массив из нескольких элементов, то на странице b.php будет доступна только переменная из первого элемента массива.
Т.е. так
exec_script('http://mysite.com/b.php', array('hello' => 'world', 'hello2' => 'world2'));
будет доступна только переменная $_POST['hello'], а $_POST['hello2'] нет.

будут доступны обе переменные. проверено неоднократно

Почему-то по умолчанию http_build_query в качестве разделителя ставит &
Поэтому и имя переменной было своеобразным, что-то типа $_POST['amp;hello2']
Принудительно выставил разделителем & и все стало хорошо
$data = http_build_query($params, '', '&')

Спасибо за скрипт, очень помог.

разделитель прописывается в php.ini, в директиве arg_separator.output, видимо у вас это &

спасибо!

На действительно тяжеловесный скрипт всё-равно вылетает по тайм-ауту. Поэтому в этом с лучае всё-таки придётся использовать shell_exec()

добрый день,
добавил этот скрипт в views php , встретился с такой ошибкой
Fatal error: Cannot redeclare exec_script() (previously declared in /sites/all/modules/views_php/plugins/views/views_php_handler_field.inc(223) : runtime-created function:2) in /sites/all/modules/views_php/plugins/views/views_php_handler_field.inc(223) : runtime-created function on line 2

как с этим бороться.. или подскажите как запустить другой скрипт из views
Спасибо.

переименуйте функцию

переименовать в любое имя ?
переименовал, все то же
Fatal error: Cannot redeclare myfunc() (previously declared in ...

переименовать в любое доступное имя

переименовал в funcxandex , такой занятой не должно быть
и сново та же ошибка
Fatal error: Cannot redeclare funcxandex() (previously declared..

значит пытаетесь создать функцию в цикле. так делать нельзя

Скрипт работает отлично, долго искал решения, спасибо! Но...
Если требуется авторизация, работать перестает :(
добавление
fwrite($fp, "Authorization: Basic ".base64_encode("user:pass")."\r\n");
не помогает.
Может подскажешь что делать? Спасибо!

to Deiww
А если сессии использовать?

А чем они помогут? И как это реализовать...

Отличная заначка!

Поставил пример скрипта на сервер - не работает. Поставил на другой сервер - работает. На том сервере - где не работает в логах nginx нашел вот это:

123.465.798.123 - - [14/Mar/2014:03:53:38 +0400] "GET <strong>/a.php</strong> HTTP/1.1" 200 102 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0"
321.654.654.897 - - [14/Mar/2014:03:53:38 +0400] "POST <strong>/b.php</strong> HTTP/1.1" 400 0 "-" "-"

Получается, скрипт b.php выдает ошибку 400 - Bad Request при вызове из a.php

Подскажите, в чем может быть проблема? Может конфиги сервера нужно подкрутить?
Заранее благодарен!

Хороший скрипт, тока вот с GET не работает. НЕ много доработал:

заменяем строку:

 fwrite($fp, "POST " . (!empty($parts['path']) ? $parts['path'] : '/') . " HTTP/1.1\r\n");

на

if(empty($parts['query']))$q="";
else $q="?".$parts['query'];
 
fwrite($fp, "POST " . (!empty($parts['path']) ? $parts['path'].$q : '/'.$q ) . " HTTP/1.1\r\n");

зачем такие сложности ?

function freelocation($location){
if($location){
        ob_end_clean();
        header("Connection: close\r\n");
        header("Content-Encoding: none\r\n");
        ignore_user_abort(true); ob_start();
		header('location:'.$location);
        $size = ob_get_length();
        header("Content-Length: $size");
        ob_end_flush(); flush(); ob_end_clean();
 }
}

Оставить комментарий

Содержимое этого поля является приватным и не будет отображаться публично. Если у вас есть аккаунт в Gravatar, привязанный к этому e-mail адресу, то он будет использован для отображения аватара.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Доступные HTML теги: <a> <i> <b> <strong> <code> <ul> <ol> <li> <blockquote> <em> <s>
  • Строки и параграфы переносятся автоматически.
  • Подсветка кода осуществляется с помощью тегов: <code>, <css>, <html>, <ini>, <javascript>, <sql>, <php>. Поддерживаемые стили выделения кода: <foo>, [foo].

Подробнее о форматировании