2009-10-08 19 views
9

Benim durumum iyi kod biraz tarif edilir sınıfım, ancak benim amaçlarım için, __call işlevinin bunlarla ilgilenmesi güzel olurdu. Sadece lot daha hassas ve daha yönetilebilir şeyler yapar.PHP'nin sihirli yöntem __call

PHP'de bu mümkün mü?

cevap

13

__call() yalnızca işlev başka bir şekilde bulunmadığında çağrılır, böylece örnek olarak, yazılı olarak, mümkün değildir.

2

doğrudan yapılamaz, ama bu mümkün alternatiftir:

class SubFoo { // does not extend 
    function __construct() { 
     $this->__foo = new Foo; // sub-object instead 
    } 
    function __call($func, $args) { 
     echo "intercepted $func()!\n"; 
     call_user_func_array(array($this->__foo, $func), $args); 
    } 
} 

Bu tür şeyler hata ayıklama ve test için iyidir, ama mümkün olduğunca __call() ve arkadaşları kaçınmak istiyorum Üretim kodu çok verimli olmadığından.

+0

This. Cephe modelini takip etmelisiniz. Tüm bu işlevleri geçersiz kılmak istediğiniz nesneyi "sahibi" olan bir sarmalayıcı sınıfınız olsun. Gerektiğinde herhangi bir ek iş yapmak için gerektiği gibi yöntemleri geçmek için __call() kullanın. Kodunuz sürekli olarak adlandırılmadıkça performansınızı artırmayın ve uygulamanız CPU sınırlı (neredeyse hiç bir zaman) - programcı zaman bu tür bir alışverişe karar verirken neredeyse her zaman performanstan daha önemlidir. –

0

Ebeveyn çubuğuna fazladan bir şey eklemeniz gerekiyorsa(), bu yapılabilir?

class SubFoo extends Foo { 
    function bar() { 
     // Do something else first 
     parent::bar(); 
    } 
} 

veya bu sadece meraktan mı bir soru? Eğer aynı etkiyi yapabileceğini ne

+1

sorunu, ana sınıfın işlevler yığını olabileceğinden kaynaklanıyor ve alt sınıfa bunları kopyalamak zorunda kalmak istemiyorum, sadece aynı davranışı uygulamak ('// önce başka bir şey yapmak '' kısımda '' hepsi için – nickf

+0

@nickf Kesinlikle, bu bana öyle bir şey gibi geliyor ki, PHP'de neden olmadığını anlamıyorum. –

0

şudur: deneyebileceğiniz

<?php 

class hooked{ 

    public $value; 

    function __construct(){ 
     $this->value = "your function"; 
    } 

    // Only called when function does not exist. 
    function __call($name, $arguments){ 

     $reroute = array(
      "rerouted" => "hooked_function" 
     ); 

     // Set the prefix to whatever you like available in function names. 
     $prefix = "_"; 

     // Remove the prefix and check wether the function exists. 
     $function_name = substr($name, strlen($prefix)); 

     if(method_exists($this, $function_name)){ 

      // Handle prefix methods. 
      call_user_func_array(array($this, $function_name), $arguments); 

     }elseif(array_key_exists($name, $reroute)){ 

      if(method_exists($this, $reroute[$name])){ 

       call_user_func_array(array($this, $reroute[$name]), $arguments); 

      }else{ 
       throw new Exception("Function <strong>{$reroute[$name]}</strong> does not exist.\n"); 
      } 

     }else{ 
      throw new Exception("Function <strong>$name</strong> does not exist.\n"); 
     } 

    } 

    function hooked_function($one = "", $two = ""){ 

     echo "{$this->value} $one $two"; 

    } 

} 

$hooked = new hooked(); 

$hooked->_hooked_function("is", "hooked. "); 
// Echo's: "your function is hooked." 
$hooked->rerouted("is", "rerouted."); 
// Echo's: "our function is rerouted." 

?> 
1

Bir şey özel veya korunan senin fonksiyonları kapsamını ayarlamaktır. Bir özel işlev, sınıfın dışından çağrıldığında, __call sihirli yöntemini çağırır ve onu kullanabilirsiniz.

İlgili konular