تسهل هذه الحزمة تشغيل PHP بشكل متزامن. خلف الكواليس، يتم تحقيق التزامن من خلال تحويل عملية PHP الرئيسية إلى مهمة فرعية واحدة أو أكثر.
في هذا المثال، حيث سنقوم باستدعاء واجهة برمجة التطبيقات البطيئة الوهمية، سيتم تشغيل عمليات الإغلاق الثلاثة جميعها في نفس الوقت.
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
وفي هذا الفيديو على اليوتيوب نشرح طريقة عمل الحزمة داخليا.
نحن نستثمر الكثير من الموارد في إنشاء أفضل الحزم مفتوحة المصدر في فئتها. يمكنك دعمنا عن طريق شراء أحد منتجاتنا المدفوعة.
نحن نقدر بشدة إرسالك لنا بطاقة بريدية من مسقط رأسك، مع ذكر الحزمة (الحزم) التي تستخدمها. ستجد عنواننا على صفحة الاتصال لدينا. ننشر جميع البطاقات البريدية المستلمة على جدار البطاقات البريدية الافتراضية لدينا.
تتطلب هذه الحزمة 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 ,
);
أخيرًا، يتم إجراء تسلسل لقيم الإرجاع من المهام الفرعية باستخدام طريقة serialize
المضمنة في PHP. هذا يعني أنه يمكنك إرجاع أي شيء يمكنك إجراء تسلسل له عادةً في 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
الرجاء مراجعة سجل التغيير للحصول على مزيد من المعلومات حول ما تغير مؤخرًا.
يرجى الاطلاع على المساهمة للحصول على التفاصيل.
يرجى مراجعة سياستنا الأمنية حول كيفية الإبلاغ عن الثغرات الأمنية.
رخصة معهد ماساتشوستس للتكنولوجيا (MIT). يرجى الاطلاع على ملف الترخيص لمزيد من المعلومات.