Başka sınıftaki bir yöntemi olarak adlandırılan hangi sınıf öğrenin

7 Cevap

Başka bir nesnenin ne yöntem dediği obje bulmak için PHP bir yolu var mı.

Xmaple:

class Foo
{
  public function __construct()
  {
    $bar = new Bar();
    $bar->test();
  }
}

class Bar
{
  public function test()
  {
  }
}
$foo = new Foo();

Bana test yöntemi foo nesnesi olarak adlandırılan olduğunu öğrenmek için bir yol var olabilir mi?

7 Cevap

Sen kullanabilirsiniz get_called_class()

PHP.net for this function üzerine belgelerine bakın

class WhoCalledMe {
    function WhoCalledMe() {
        $calledMe = get_called_class();
        echo "$calledMe called me\n";
    }
}

class Test {
    function runTest() {
        $_whoCalled = new WhoCalledMe();
        $_whoCalled->WhoCalledMe();
    }
}

$myTest = new Test();
$myTest->runTest();

you could use debug_backtrace, a bit like this :
BTW, take a look at the comments on the manual page : there are some useful functions and advices given ;-)

class Foo
{
  public function __construct()
  {
    $bar = new Bar();
    $bar->test();
  }
}

class Bar
{
  public function test()
  {
      $trace = debug_backtrace();
      if (isset($trace[1])) {
          // $trace[0] is ourself
          // $trace[1] is our caller
          // and so on...
          var_dump($trace[1]);

          echo "called by {$trace[1]['class']} :: {$trace[1]['function']}";

      }
  }
}
$foo = new Foo();

var_dump olur çıkışı:

array
  'file' => string '/home/squale/developpement/tests/temp/temp.php' (length=46)
  'line' => int 29
  'function' => string '__construct' (length=11)
  'class' => string 'Foo' (length=3)
  'object' => 
    object(Foo)[1]
  'type' => string '->' (length=2)
  'args' => 
    array
      empty

ve echo:

called by Foo :: __construct

Ancak, güzel gibi gibi görünebilir gibi, ben bu uygulamada "normal bir şey" olarak kullanılmalıdır emin değilim ... Aslında, garip görünüyor: iyi bir tasarım ile, bir yöntem denilen bilmek gerekmez , bence.

Burada bir liner çözümdür

list(, $caller) = debug_backtrace(false);

Bu tür hackish görünüyor olsa da muhtemelen bir debug backtrace ile bunu başarabilirsiniz.

Sizin alternatif seçenek o sınıf için bir parametre geçmek ve ondan denir ediliyor nereye başka içinde sınıfı örneğini zaman, bunu söylemek için.

En azından, sen debug_backtrace kullanmak ve arama yöntemi bulmak için analiz edebilirsiniz.

Ben de reflection API kullanarak bunu yapmak mümkün olması gerektiğini düşünüyorum, ama çok uzun ben PHP kullandım ve ben tam olarak nasıl hatırlamıyorum yana oldu. Bağlantılar, en azından, ancak başlamak gerekir.

@Pascal MARTIN: Yes, in normal applicacions it's probably not needed. But sometimes it could be useful. Consider an example from my own app:

There's a Controller subclass which can use a Template object to prepare its output. Every template has a name to refer it to. When a Controller needs a Template, it asks the TemplateManager for it by giving that name as a parameter. But there could be many template files with that name for different Controllers. Controlers are used as plugins, and may be written by different users, so the names used by them can't be controlled to no collide with each other. Namespaces for templates are needed. So TemplateManager, which is a factory for Template objects, needs the template name and the namespace name to locate the proper template source file. This namespace is related to the particular Controller's class name.

Ancak, çoğu durumda, her Kontrolör kendi ad gelen ve sadece başka ad gelen nadir durumlarda şablonları kullanarak olacaktır. Yani TemplateManager :: GetTemplate her çağrısı ad belirterek () her zaman bir karmaşa olacak. Namespace için ... the Controller which calls the TemplateManager::getTemplate()! isteğe ve varsayılan Ve burada arayan bilmek için iyi bir yer olduğunu daha iyi olur.

Tabii ki arayan Denetleyicisi kendisini veya bir parametre olarak adını geçebileceği, ama gerçekten ad adı geçen pek farklı değildir. Bu iki şekilde isteğe bağlı olamazdı.

Eğer arayan bilmek eğer Ama, hatta arayan rahatsız etmeden, GetTemplate () içindeki otomatik ad varsayılan için bu bilgileri kullanabilirsiniz. Bu GetTemplate () kendi içinde de bunu işleme nasıl bilmek zorunda değildir ve nasıl uygun varsayılan ad alanını biliyor. O sadece öyle olduğunu bilmek gerekiyor ve gerçekten ihtiyacı varsa, isteğe bağlı olarak herhangi bir başka ad geçebilir.

Ayrıca çağıran nesne argüman olarak kendisini geçmek olabilir

örneğin

class Foo
{
  public function __construct()
  {
    $bar = new Bar();
    $bar->test($this);
  }
}

class Bar
{
  public function test()
  {
  }
}
$foo = new Foo();

Erich Gamma, ve diğerleri, sayfa 278. "Arabulucu" yapısal desen üzerinde tartışma: Ben kitabı "yeniden kullanılabilir nesne yönelimli yazılım unsurları Design Patterns" bu fikrim var.

Desenin nokta nesne / sınıfları bir grup arasında çok-sayıda bağlantı sayısını azaltmaktır. Siz tüm bu sınıfların bir hub olarak tedavi bir arabulucu sınıf oluşturmak. Bu şekilde sınıfları birbirleri hakkında bilmek gerekmez. Arabulucu etkileşimleri yönetir. Bu izler sınıflarında değişikliklerden haberdar olmak için arabulucu, onlar argüman olarak kendilerini geçebilir, ya da arabulucu "Gözlemci" desen kullanılarak uygulanabilir.