2009-07-07 9 views
6

scusa per quel soggetto strano ma non so come esprimerlo in un altro modo.Classi PHP: accedi all'istanza chiamante dal metodo chiamato

Sto tentando di accedere a un metodo da una classe chiamante. Come in questo esempio:

 
class normalClass { 
    public function someMethod() { 
      [...] 
      //this method shall access the doSomething method from superClass 
    } 
} 

class superClass { 
    public function __construct() { 
      $inst = new normalClass; 
      $inst->someMethod(); 
    } 
    public function doSomething() { 
      //this method shall be be accessed by domeMethod form normalClass 
    } 
} 

Entrambe le classi non sono collegati per via ereditaria e non voglio per impostare la funzione di statica.

Esiste un modo per raggiungerlo?

Grazie per il vostro aiuto!

risposta

5

È possibile passare un riferimento al primo oggetto in questo modo:

class normalClass { 
    protected $superObject; 
    public function __construct(superClass $obj) { 
     $this->superObject = $obj; 
    } 

    public function someMethod() { 
     //this method shall access the doSomething method from superClass 
     $this->superObject->doSomething(); 
    } 
} 

class superClass { 
    public function __construct() { 
      //provide normalClass with a reference to ourself 
      $inst = new normalClass($this); 
      $inst->someMethod(); 
    } 
    public function doSomething() { 
      //this method shall be be accessed by domeMethod form normalClass 
    } 
} 
1

Avete alcune opzioni. È possibile utilizzare l'aggregazione in questo modo

class normalClass 
{ 
    protected $superClass; 

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

    public function someMethod() 
    { 
    $this->superClass->doSomething(); 
    } 
} 

class superClass 
{ 
    public function __construct() 
    { 
    $inst = new normalClass($this); 
    $inst->someMethod(); 
    } 

    public function doSomething() 
    { //this method shall be be accessed by domeMethod form normalClass 
    } 
} 

O solo uno straight-up setter

class normalClass 
{ 
    protected $superClass; 

    public function setSuperClass(superClass $superClass) 
    { 
    $this->superClass = $superClass; 
    } 

    public function someMethod() 
    { 
    if (!isset($this->superClass)) 
    { 
     throw new Exception('you must set a superclass'); 
    } 
    $this->superClass->doSomething(); 
    } 
} 

class superClass 
{ 
    public function __construct() 
    { 
    $inst = new normalClass(); 
    $inst->setSuperClass($this); 
    $inst->someMethod(); 
    } 

    public function doSomething() 
    { //this method shall be be accessed by domeMethod form normalClass 
    } 
} 
0

A seconda del caso d'uso, si potrebbe desiderare di passare l'istanza solo la funzione:

class normalClass { 
    public function someMethod($object) { 
     $object->doSomething(); 
    } 
} 

Se normalClass::someMethod() può essere chiamato da più, distinti $object s, questa potrebbe essere la scelta migliore (invece di fornire il $object al intera istanza normalClass).

Ma indipendentemente da che si potrebbe prendere in considerazione la creazione di un'interfaccia da utilizzare per type hinting:

interface ISomethingDoer { 
    public function doSomething(); 
} 

class normalClass { 
    public function someMethod(ISomethingDoer $object) { 
     # Now PHP will generate an error if an $object is passed 
     # to this function which does not implement the above interface. 
     // ... 

class superClass implements ISomethingDoer { 
    // ... 
0

Si potrebbe utilizzare debug_backtrace() per questo. È un po 'incerto, ma per scopi di debug è utile.

class normalClass { 
public function someMethod() { 
     $trace = debug_backtrace(); 
     $trace[1]->object->doSomething(); 
} 

}

+0

Non è consigliabile utilizzare la funzione di debug nel codice di produzione – DarkNeuron

0

woah Ho avuto lo stesso problema di voi, ma invece di andare con il modo semplice passaggio il riferimento all'oggetto, sono andato con un event manager, In sostanza, quando qualcosa sarebbe accaduto nel normale classe, innescherebbe un evento che è stato ascoltato da una classe e che detta classe (l'ascoltatore) chiamerebbe la super classe per eseguire quella funzionalità e, se necessario, passargli nuovi argomenti.

Ad ogni modo, sia che lo si passi come parametro al proprio oggetto o si passi ad un approccio basato su eventi, entrambe le soluzioni funzionano. Scegli quello che preferisci.

Per ulteriori informazioni sugli eventi, sympony lo spiega abbastanza bene. http://symfony.com/doc/current/components/event_dispatcher/introduction.html

Problemi correlati