Ce package facilite l’exécution simultanée de PHP. En coulisses, la concurrence est obtenue en divisant le processus PHP principal vers une ou plusieurs tâches enfants.
Dans cet exemple, où nous allons appeler une API lente imaginaire, les trois fermetures s'exécuteront en même temps.
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
Dans cette vidéo sur YouTube, nous expliquons le fonctionnement du package en interne.
Nous investissons beaucoup de ressources dans la création des meilleurs packages open source de leur catégorie. Vous pouvez nous soutenir en achetant l'un de nos produits payants.
Nous apprécions grandement que vous nous envoyiez une carte postale de votre ville natale, mentionnant le(s) forfait(s) que vous utilisez. Vous trouverez notre adresse sur notre page contact. Nous publions toutes les cartes postales reçues sur notre mur virtuel de cartes postales.
Ce package nécessite PHP 8 et les extensions pcntl qui sont installées par défaut sur de nombreux systèmes Unix et Mac.
pcntl ne fonctionne que dans les processus CLI, pas dans un contexte Web. posix requis pour une gestion correcte de la terminaison du processus pour Alpine Linux.
Vous pouvez installer le package via composer :
composer require spatie/fork
Vous pouvez passer autant de fermetures que vous run
souhaitez. Ils seront exécutés simultanément. La fonction run
renverra un tableau avec les valeurs de retour des fermetures exécutées.
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'
Si vous devez exécuter du code avant ou après chaque appelable passé à run
, vous pouvez transmettre un appelable aux méthodes before
ou after
. Cet appelable passé sera exécuté dans le processus enfant juste avant ou après l'exécution de l'appelable passé à run
.
before
et after
dans la tâche enfant Voici un exemple où nous allons obtenir une valeur de la base de données en utilisant un modèle Laravel Eloquent. Afin de permettre à la tâche enfant d'utiliser la base de données, il est nécessaire de se reconnecter à la base de données. La fermeture passée before
s'exécutera dans les deux tâches enfants créées pour les fermetures passées à 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 (),
);
Si vous devez effectuer un nettoyage dans la tâche enfant après l'exécution de l'appelable, vous pouvez utiliser la méthode after
sur une instance SpatieForkFork
.
before
et after
dans la tâche parent. Si vous devez laisser l'appelable être transmis before
ou after
l'exécution dans la tâche parent, vous devez alors transmettre cet appelable à l'argument 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 (),
);
Vous pouvez également passer différentes fermetures, à exécuter dans la tâche enfant et la tâche parent
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 (),
);
Toutes les données de sortie sont rassemblées dans un tableau et disponibles dès que tous les enfants ont terminé. Dans cet exemple, $results
contiendra trois éléments :
$ results = Fork:: new ()
-> run (
fn () => ( new Api )-> fetchData (userId: 1 ),
fn () => ( new Api )-> fetchData (userId: 2 ),
fn () => ( new Api )-> fetchData (userId: 3 ),
);
La sortie est également disponible dans les rappels after
, qui sont appelés chaque fois qu'un enfant a terminé et non à la toute fin :
$ 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 ,
);
Enfin, les valeurs de retour des tâches enfants sont sérialisées à l'aide de la méthode serialize
intégrée de PHP. Cela signifie que vous pouvez renvoyer tout ce que vous pouvez normalement sérialiser en PHP, y compris les objets :
$ result = Fork:: new ()
-> run (
fn () => new DateTime ( ' 2021-01-01 ' ),
fn () => new DateTime ( ' 2021-01-02 ' ),
);
Par défaut, tous les callables seront exécutés en parallèle. Vous pouvez cependant configurer un nombre maximum de processus simultanés :
$ results = Fork:: new ()
-> concurrent ( 2 )
-> run (
fn () => 1 ,
fn () => 2 ,
fn () => 3 ,
);
Dans ce cas, les deux premières fonctions seront exécutées immédiatement et dès que l'une d'elles se terminera, la dernière démarrera également.
composer test
Veuillez consulter CHANGELOG pour plus d'informations sur ce qui a changé récemment.
Veuillez consulter CONTRIBUER pour plus de détails.
Veuillez consulter notre politique de sécurité pour savoir comment signaler les vulnérabilités de sécurité.
La licence MIT (MIT). Veuillez consulter le fichier de licence pour plus d'informations.