كيفية التقاط أي استدعاء الأسلوب على كائن في PHP؟

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

  •  15-09-2020
  •  | 
  •  

سؤال

أحاول معرفة كيفية التقاط أي طريقة يتم استدعاؤها على كائن في PHP.أنا أعرف عن الوظيفة السحرية __call, ، ولكن يتم تشغيله فقط للطرق غير الموجودة في الكائن المطلوب.

على سبيل المثال لدي شيء مثل هذا:

class Foo
{
  public function bar()
  {
    echo 'foobar';
  }

  public function override($method_name,$method_args)
  {
    echo 'Calling method ',$method_name,'<br />';
    $this->$method_name($method_args); //dirty, but working
  }
}

وعندما أفعل هذا:

$foo = new Foo();
$foo->bar();

أريد هذا الإخراج:

Calling method bar
foobar

بدلا من هذا:

foobar

هل هناك أي طريقة للقيام بذلك؟ساعدنى من فضلك :)

هل كانت مفيدة؟

المحلول

أخذ الأصلي الخاص بك Foo التنفيذ الذي يمكنك التفافه decorator حوله هكذا:

class Foo 
{
    public function bar() {
        echo 'foobar';
    }
}

class Decorator 
{
    protected $foo;

    public function __construct(Foo $foo) {
       $this->foo = $foo;
    }

    public function __call($method_name, $args) {
       echo 'Calling method ',$method_name,'<br />';
       return call_user_func_array(array($this->foo, $method_name), $args);
    }
}

$foo = new Decorator(new Foo());
$foo->bar();

نصائح أخرى

يمكنك لف كائن حول الكائن، واعتراض أي استدعاءات ثم إعادة توجيهها على الكائن الأصلي وإرجاع النتيجة.

ما عليك سوى تخزين الكائن كمتغير في فئة الغلاف الخاصة بك واستخدام أساليب التحميل الزائد في فئة الغلاف الخاصة بك للاتصال/التعيين/الحصول على/التحقق من الكائن.

$object = new AnyObject;
$object = new Wrapper($object);

$object->anyMethod();
$object->anyVar = 'test';
echo $object->anyVar;
echo $object['array form'];

من المحتمل أن يكون تكرار فئة المجمع في foreach أصعب.لم تحاول ذلك.

إذا قمت بضبط الوظيفة على خاصة، فإن الاتصال سوف يحجز أي اتصال إليها من الخارج سيتم احتجازه في __call، ولكن يمكنك الاتصال بها من الداخل

class Foo
{
   private function bar()
   {
      echo 'foobar';
   }

   public function __call($method_name,$method_args)
   {
      echo 'Calling method ',$method_name,'<br />';
      $this->$method_name(); //dirty, but working
   }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top