وسيطات الوظائف الديناميكية واستخدام __call
سؤال
ها هي الفرضية:
لدي العديد من الفئات التي أحتاج فيها إلى إجراء إجراء قبل أي طريقة من أي من الفئات ، وكان الحل الخاص بي هو جعل جميع الفئات تمد فئة الوالدين التي ستحدد وظيفة الاتصال () التي ستبدو:
public function call($method){
//do the something I need to do before method calls
$params = func_get_args();
//remove the $method param from the $params array
unset($params[0]);
return $this->__call($method,$params);
}
ثم ببساطة استدعاء طريقة المكالمات وحدد الطريقة الفعلية التي أردت الاتصال بها ، وبهذه الطريقة ، سيتم استدعاء الطريقة ، ولكن داخل طريقة الاتصال (التي يرثها الفصل من فئة الأم) ، يمكنني تنفيذ الإجراء الذي أحتاجه لحمله خارج قبل أن يتم استدعاء الطريقة المحددة.
يجب أن يكون هذا قادرًا على دعم الحجج التي يمكن أن تكون المصفوفات أو السلاسل ، لذا فإن أي شيء يتضمن تفجير مجموعة من الحجج لن يعمل (لأن هذا قد يفترض أن جميع الحجج هي سلاسل).
لست متأكدًا مما إذا كان ما لدي أعلاه منطقيًا ، وأردت التحقق من ذلك إذا كنت سأجري هذا بطريقة خاطئة أم لا.
أي أفكار/أفكار ستكون موضع تقدير كبير.
شكرًا!
ملاحظة: يجب أن أشير إلى أن وصفتي للموقف أعلاه يجعل الأمر يبدو كما لو أن فئات الطفل تمد الوالد هو ببساطة لهذا الغرض ، في الواقع هناك المزيد من الأسباب (تمتد فئة الوالد الخاصة بي .
المحلول
__call
يُطلق عليه تلقائيًا ، إذا تم تعريفه ، كلما حاولت استدعاء وظيفة غير موجودة. لهذا السبب هي طريقة "سحرية". يبدو من الغريب بالنسبة لي استخدامه مباشرة ، وليس في السياق المقصود من أجله. هنا ، قد تسميها أي شيء.
أنت استطاع بالتأكيد استخدم قوة __call
لصالحك هنا. حاول تسمية جميع وظائف الأعضاء مع السطح السفلي قبلها. لذلك ، إذا كنت قد كنت $this->print()
سيكون لديك الآن $this->_print()
. ثم في الخاص بك __call
الوظيفة ، أضف السطح السفلي واتصل بالوظيفة باستخدام call_user_func_array(array($this,"_$name"), $params)
. الآن يمكنك الاتصال بوظائفك بشكل طبيعي (حسنًا ، بدون السطح السفلي).
ومع ذلك ، لن أقترح استخدام __call
باستثناء الراحة. على المدى الطويل ، من الأفضل فقط استدعاء أي رمز تريد تشغيله مباشرة.
نصائح أخرى
قد يكون بديل أفضل/أنظف هو إعداد حدث ونظام استماع ، مثل نظام أحداث العقيدة. (هذا الرمز هو في الواقع من المكتبة المشتركة ، وليس جزء ORM.) لكنك ستحتاج إلى جميع أساليبك لإرسال الأحداث.
أحاول تجنب استخدام __call قدر الإمكان لأنه يجعل الكود الخاص بك أكثر صعوبة في فهمه وصيانته ، على الرغم من أنني أعتقد أنه من الجيد استخدامه في أنظمة البرنامج المساعد.
شكرًا لك على الاقتراحات ، كنت نوعًا من النباح الشجرة الخاطئة ، ولكن هنا هو الحل الذي توصلت إليه:
public function call($method){
//do the something I need to do before method calls
$params = func_get_args();
//remove the $method param from the $params array
unset($params[0]);
return call_user_func_array(array($this,$method),$params);
}
شكرا مرة أخرى يا رفاق!
يمكنك الحصول على معلمات الطريقة مباشرة من معلمات __call:
function __call($method, $args) {
return call_user_func_array(array($this,$method),$args);
}