Menu
Coddy logo textTech
flag Ar iconالعربيةdown icon

الألياف (PHP 8.1)

جزء من قسم Object Oriented Programming في رحلة PHP على Coddy — الدرس 60 من 91.

تعد Fibers ميزة في PHP 8.1 تتيح تنفيذ التعليمات البرمجية القابلة للمقاطعة. وعلى عكس الدوال العادية التي تعمل من البداية إلى النهاية، يمكن لـ fiber أن يوقف نفسه مؤقتاً في منتصف التنفيذ ويستأنف لاحقاً، مع الحفاظ على حالته بين فترات التوقف.

قم بإنشاء fiber عن طريق تمرير callable إلى فئة Fiber، ثم ابدأه باستخدام start():

<?php
$fiber = new Fiber(function(): void {
    echo "Step 1\n";
    Fiber::suspend();
    echo "Step 2\n";
});

$fiber->start();
echo "Between steps\n";
$fiber->resume();

المخرجات:

Step 1
Between steps
Step 2

يستمر الـ fiber في العمل حتى يصل إلى Fiber::suspend()، ثم يعود التحكم إلى الكود الرئيسي. استدعاء resume() يستأنف التنفيذ من حيث توقف.

يمكن للألياف (Fibers) أيضاً تمرير القيم عند التعليق والاستئناف:

<?php
$fiber = new Fiber(function(): string {
    $value = Fiber::suspend("paused");
    return "Received: $value";
});

$suspended = $fiber->start();
echo "$suspended\n";

$result = $fiber->resume("hello");
echo $result;

المخرجات:

paused
Received: hello

تُعد الـ Fibers هي الأساس لأطر عمل PHP غير المتزامنة. وبينما لن تستخدمها بشكل مباشر في معظم التطبيقات، فإن فهمها يساعد عند العمل مع المكتبات غير المتزامنة التي تتعامل مع العمليات المتزامنة مثل طلبات HTTP أو استعلامات قاعدة البيانات دون حظر (blocking).

challenge icon

التحدي

سهل

لنقم ببناء مجدول مهام يوضح كيف يمكن للألياف (fibers) إيقاف واستئناف التنفيذ مع تمرير البيانات بين الليف والكود الرئيسي. ستقوم بإنشاء نظام حيث يمكن مقاطعة المهام، مما يسمح بإنجاز أعمال أخرى في هذه الأثناء.

ستقوم بتنظيم الكود الخاص بك عبر ملفين:

  • TaskRunner.php — أنشئ فئة TaskRunner تغلف وظائف الألياف لتشغيل المهام. يجب أن تقوم الفئة بما يلي:
    • امتلاك خاصية خاصة (private property) لتخزين مثيل من Fiber
    • قبول اسم المهمة (string) في منشئها (constructor) باستخدام خاصية constructor promotion
    • امتلاك طريقة createTask(callable $task) تقوم بإنشاء Fiber جديد باستخدام الـ callable المعطى وتخزينه
    • امتلاك طريقة start() تبدأ الليف وتعيد أي قيمة يعلقها الليف (أو قيمة الإرجاع النهائية)
    • امتلاك طريقة continue(mixed $value) تستأنف الليف بالقيمة المعطاة وتعيد القيمة المعلقة التالية (أو قيمة الإرجاع النهائية)
    • امتلاك طريقة isFinished(): bool تعيد ما إذا كان الليف قد انتهى
  • main.php — قم بتضمين ملف TaskRunner. ستتلقى مدخلين: اسم المهمة ورسالة لإرسالها إلى الليف.

    أنشئ TaskRunner باسم المهمة المعطى، ثم استخدم createTask() لتعريف مهمة تقوم بما يلي:

    1. تتوقف أولاً مع السلسلة النصية "Waiting for input"
    2. تتلقى قيمة عند استئنافها
    3. تعيد "Completed: [received value]"

    ابدأ المهمة واطبع ما تعيده عند توقفها لأول مرة. ثم اطبع "Processing..." لإظهار العمل الذي يحدث بين فترات توقف الليف. أخيرًا، استأنف الليف عن طريق تمرير مدخل الرسالة، واطبع النتيجة النهائية.

يوضح هذا التحدي كيف تمكن الألياف من تعدد المهام التعاوني (cooperative multitasking) — حيث توقف مهمتك نفسها عند نقطة مناسبة، ويقوم الكود الرئيسي بعمل آخر، ثم يستأنف المهمة ببيانات جديدة. يحافظ الليف على حالته طوال الوقت، مستأنفًا من حيث توقف تمامًا.

ورقة مرجعية

تتيح الألياف (Fibers) تنفيذ التعليمات البرمجية القابلة للمقاطعة في PHP 8.1+. على عكس الدوال العادية، يمكن لليف (fiber) أن يتوقف مؤقتاً في منتصف التنفيذ ويستأنف لاحقاً مع الحفاظ على حالته.

قم بإنشاء ليف (fiber) عن طريق تمرير كائن قابل للاستدعاء (callable) إلى فئة Fiber وابدأ تشغيله باستخدام start():

<?php
$fiber = new Fiber(function(): void {
    echo "Step 1\n";
    Fiber::suspend();
    echo "Step 2\n";
});

$fiber->start();
echo "Between steps\n";
$fiber->resume();

يعمل الليف (fiber) حتى يصل إلى Fiber::suspend()، ثم يعود التحكم إلى الكود الرئيسي. استدعِ resume() لمواصلة التنفيذ من حيث توقف.

يمكن للألياف (Fibers) تمرير القيم عند التعليق والاستئناف:

<?php
$fiber = new Fiber(function(): string {
    $value = Fiber::suspend("paused");
    return "Received: $value";
});

$suspended = $fiber->start();
$result = $fiber->resume("hello");

الأساليب (Methods) الرئيسية:

  • start() — يبدأ تنفيذ الليف (fiber)
  • Fiber::suspend($value) — يوقف التنفيذ مؤقتاً ويعيد قيمة إلى المستدعي
  • resume($value) — يواصل التنفيذ ويمرر قيمة إلى الليف (fiber)
  • isTerminated() — يتحقق مما إذا كان الليف (fiber) قد انتهى

جرّب بنفسك

<?php

require_once 'TaskRunner.php';

// قراءة المدخلات
$taskName = trim(fgets(STDIN));
$message = trim(fgets(STDIN));

// TODO: TaskRunner قم بإنشاء كائن من نوع باسم المهمة المعطى

// TODO: لتعريف مهمة تقوم بما يلي: createTask() استخدم 
// 1. "Waiting for input" أولاً يتم تعليقها مع إرجاع النص
// 2. تستقبل قيمة عند استئنافها
// 3. "Completed: [received value]" تعيد النص

// TODO: ابدأ المهمة واطبع ما تعيده عند تعليقها لأول مرة

// TODO: لإظهار العمل الذي يحدث بين فترات توقف الألياف "Processing..." اطبع

// TODO: استمر في تنفيذ الألياف عن طريق تمرير مدخل الرسالة

// TODO: اطبع النتيجة النهائية

?>
quiz iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس Object Oriented Programming