ردود النداء في PHP

من موسوعة حسوب
< PHP
(بالتحويل من PHP/Types/callable)

يمكن الإشارة إلى رد النداء (Callbacks) باستخدام نوع البيانات (callable) منذ إصدار PHP 5.4، هذا التوثيق يستخدم معلومات نوع callback لنفس الغرض.

بعض الدوال مثل call_user_func()‎ أو usort()‎ تقبل فقط دوال رد النداء المعرّفة من قبل المستخدم (user-defined callback functions) كمعامل.

دوال رد النداء ليست دوالًا بسيطةً فحسب، بل يمكن استخدام الدوال التي تكون أعضاءً في أصناف (object methods)، بما في ذلك الدوال الساكنة (static class methods).

تمرير دوال رد النداء

يتم تمرير أي دالة PHP باستخدام اسمها كسلسلة نصية، ويمكن استخدام أي دالة معرّفة من قبل المستخدم (user-defined)، باستثناء الدوال البنيوية في اللغة مثل: echo أو array()‎ أو empty()‎ أو eval()‎ أو exit()‎ أو isset()‎ أو list()‎ أو print أو unset()‎.

تُمرَّر دالةٌ تابعةٌ لكائنٍ كمصفوفةٍ تحتوي على كائن في الفهرس 0 والدالة في الفهرس 1، ويسمح بالوصول إلى الدوال المحمية (protected) والخاصة (private) من داخل الصنف (class).

يمكن أيضًا تمرير الدوال الساكنة (static methods) دون تهيئة كائن من ذلك الصنف، عبر تمرير اسم الصنف بدلًا من الكائن في الفهرس 0، وأصبح بالإمكان بدءًا من الإصدار 5.2.3 من PHP استعمال الصيغة 'ClassName::methodName' أي "اسم الصنف::اسم الأسلوب".

وبغض النظر عن الدوال الشائعة التي يُعرِّفها المستخدم، يمكن تمرير أيضا الدوال المجهولة كوسيط لرد النداء (callback).

مثال 1: أمثلة عن أنواع دالة رد النداء

<?php

// مثال عن دالة رد النداء
function my_callback_function() {
    echo 'hello world!';
}

// مثال عن دالة رد نداء ساكنة داخل صنف
class MyClass {
    static function myCallbackMethod() {
        echo 'Hello World!';
    }
}

// النوع 1: رد نداء بسيط
call_user_func('my_callback_function');

// النوع 2: رد نداء لدالة ساكنة ضمن صنف
call_user_func(array('MyClass', 'myCallbackMethod'));

// النوع 3: رد نداء لدالة ضمن صنف
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));

// النوع 4: صيغة أخرى لرد نداء لدالة ساكنة ضمن صنف
call_user_func('MyClass::myCallbackMethod');

// النوع 5: صيغة نسبية لرد نداء دالة ساكنة
class {
    public static function who() {
        echo "A\n";
    }
}

class B extends A {
    public static function who() {
        echo "B\n";
    }
}

call_user_func(array('B', 'parent::who')); // A

// النوع 6: الكائنات التي فيها الدالة
// __invoke()
// يمكن أن تستخدم رد النداء
// PHP 5.3
class {
    public function __invoke($name) {
        echo 'Hello ', $name, "\n";
    }
}

$c = new C();
call_user_func($c, 'PHP!');
?>

مثال 2: مثال رد نداء باستخدام تعبير مغلق (closure)

<?php
// التعبير المغلق
$double = function($a) {
    return $a * 2;
};

// مجال الأرقام
$numbers = range(1, 5);

// استخدام التعبير المغلق هنا
// لمضاعفة كل عنصر في 
// المجال
$new_numbers = array_map($double, $numbers);

print implode(' ', $new_numbers);
?>

مخرجات المثال السابق هي:

2 4 6 8 10

ملاحظة: لن تستدعى ردود النداءات المسجلة مع الدوال مثل call_user_func()‎ و call_user_func_array()‎ إذا كان هنالك استثناء غير معالج تم رميه في الاستدعاء السابق.

مصادر