Этот пакет упрощает одновременный запуск PHP. За кулисами параллелизм достигается путем разделения основного процесса PHP на одну или несколько дочерних задач.
В этом примере, где мы собираемся вызвать воображаемый медленный API, все три замыкания будут выполняться одновременно.
use Spatie Fork Fork ;
$ results = Fork:: new ()
-> run (
fn () => ( new Api )-> fetchData (userId: 1 ),
fn () => ( new Api )-> fetchData (userId: 2 ),
fn () => ( new Api )-> fetchData (userId: 3 ),
);
$ results [ 0 ]; // fetched data of user 1
$ results [ 1 ]; // fetched data of user 2
$ results [ 2 ]; // fetched data of user 3 В этом видео на YouTube мы объясняем, как пакет работает внутри.
Мы вкладываем много ресурсов в создание лучших в своем классе пакетов с открытым исходным кодом. Вы можете поддержать нас, купив один из наших платных продуктов.
Мы очень признательны вам за отправку нам открытки из вашего родного города с указанием того, какой из наших пакетов вы используете. Наш адрес вы найдете на странице контактов. Все полученные открытки мы публикуем на нашей виртуальной стене открыток.
Для этого пакета требуется PHP 8 и расширения pcntl, которые по умолчанию установлены во многих системах Unix и Mac.
pcntl работает только в процессах CLI, а не в веб-контексте. posix необходим для правильной обработки завершения процесса в Alpine Linux.
Вы можете установить пакет через композитор:
composer require spatie/fork Вы можете передать столько замыканий, сколько run . Они будут проводиться одновременно. Функция run вернет массив с возвращаемыми значениями выполненных замыканий.
use Spatie Fork Fork ;
$ results = Fork:: new ()
-> run (
function () {
sleep ( 1 );
return ' result from task 1 ' ;
},
function () {
sleep ( 1 );
return ' result from task 2 ' ;
},
function () {
sleep ( 1 );
return ' result from task 3 ' ;
},
);
// this code will be reached this point after 1 second
$ results [ 0 ]; // contains 'result from task 1'
$ results [ 1 ]; // contains 'result from task 2'
$ results [ 2 ]; // contains 'result from task 3' Если вам нужно выполнить некоторый код до или после каждого вызываемого объекта, переданного в run , вы можете передать вызываемый объект методам before или after . Этот переданный вызываемый объект будет выполнен в дочернем процессе непосредственно до или после выполнения вызываемого объекта, переданного в run .
before и after в дочерней задаче Вот пример, в котором мы собираемся получить значение из базы данных, используя модель Laravel Eloquent. Чтобы дочерняя задача могла использовать БД, необходимо переподключиться к БД. Замыкание, переданное before будет выполняться в обеих дочерних задачах, созданных для замыканий, переданных в run .
use App Models User ;
use Illuminate Support Facades DB ;
use Spatie Fork Fork ;
Fork:: new ()
-> before ( fn () => DB :: connection ( ' mysql ' )-> reconnect ())
-> run (
fn () => User:: find ( 1 )-> someLongRunningFunction (),
fn () => User:: find ( 2 )-> someLongRunningFunction (),
); Если вам нужно выполнить некоторую очистку дочерней задачи после запуска вызываемого объекта, вы можете использовать метод after в экземпляре SpatieForkFork .
before и after в родительской задаче. Если вам нужно передать вызываемый объект before или after запуска родительской задачи, вам необходимо передать этот вызываемый объект в parent аргумент.
use App Models User ;
use Illuminate Support Facades DB ;
use Spatie Fork Fork ;
Fork:: new ()
-> before (
parent: fn () => echo ' this runs in the parent task '
)
-> run (
fn () => User:: find ( 1 )-> someLongRunningFunction (),
fn () => User:: find ( 2 )-> someLongRunningFunction (),
);Вы также можете передавать различные замыкания для запуска в дочерней и родительской задаче.
use Spatie Fork Fork ;
Fork:: new ()
-> before (
child: fn () => echo ' this runs in the child task ' ,
parent: fn () => echo ' this runs in the parent task ' ,
)
-> run (
fn () => User:: find ( 1 )-> someLongRunningFunction (),
fn () => User:: find ( 2 )-> someLongRunningFunction (),
); Все выходные данные собираются в массив и доступны, как только все дочерние элементы будут завершены. В этом примере $results будет содержать три элемента:
$ results = Fork:: new ()
-> run (
fn () => ( new Api )-> fetchData (userId: 1 ),
fn () => ( new Api )-> fetchData (userId: 2 ),
fn () => ( new Api )-> fetchData (userId: 3 ),
); Вывод также доступен в обратных вызовах after , которые вызываются всякий раз, когда дочерний элемент завершает работу, а не в самом конце:
$ results = Fork:: new ()
-> after (
child: fn ( int $ i ) => echo $ i , // 1, 2 and 3
parent: fn ( int $ i ) => echo $ i , // 1, 2 and 3
)
-> run (
fn () => 1 ,
fn () => 2 ,
fn () => 3 ,
); Наконец, возвращаемые значения дочерних задач сериализуются с использованием встроенного в PHP метода serialize . Это означает, что вы можете возвращать все, что обычно можно сериализовать в PHP, включая объекты:
$ result = Fork:: new ()
-> run (
fn () => new DateTime ( ' 2021-01-01 ' ),
fn () => new DateTime ( ' 2021-01-02 ' ),
);По умолчанию все вызываемые объекты будут выполняться параллельно. Однако вы можете настроить максимальное количество одновременных процессов:
$ results = Fork:: new ()
-> concurrent ( 2 )
-> run (
fn () => 1 ,
fn () => 2 ,
fn () => 3 ,
);В этом случае первые две функции будут запущены сразу, а как только одна из них завершится, запустится и последняя.
composer test Пожалуйста, посетите CHANGELOG для получения дополнительной информации о том, что изменилось за последнее время.
Пожалуйста, смотрите ВКЛАД для получения подробной информации.
Пожалуйста, ознакомьтесь с нашей политикой безопасности, чтобы узнать, как сообщать об уязвимостях безопасности.
Лицензия MIT (MIT). Дополнительную информацию см. в файле лицензии.