وسيطات الوظائف الديناميكية واستخدام __call

StackOverflow https://stackoverflow.com/questions/4093364

  •  28-09-2019
  •  | 
  •  

سؤال

ها هي الفرضية:

لدي العديد من الفئات التي أحتاج فيها إلى إجراء إجراء قبل أي طريقة من أي من الفئات ، وكان الحل الخاص بي هو جعل جميع الفئات تمد فئة الوالدين التي ستحدد وظيفة الاتصال () التي ستبدو:

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);
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top