2016-06-30 14 views
0

Ich habe eine Elternklasse und mehrere Kinder, die davon erben.Wie verschachtelte Objekterstellung zu verfolgen ist

Einige Kinder werden andere Kinder in sich anrufen. Aber sie werden nicht immer verschachtelt genannt.

class Parent { } 

class Child extends Parent { 
    public function run() { 
     // Kid nested inside Child. Do not open DB transaction 
     $a = (new Kid())->run(); 
    } 
} 

class Kid extends Parent { 
    public function run() { 
     // @todo Open DB transaction if not nested 
    } 
} 

// Kid not nested. Open DB transaction 
(new Kid())->run(); 

Gibt es eine effiziente Möglichkeit für das Kid Objekt zu wissen (ohne von mir manuell erzählt wird), ob er innerhalb oder außerhalb von Child instanziiert wurde?

+0

automatisch? Wahrscheinlich nicht. Vielleicht, wenn Sie erklären, was Sie erreichen wollen, könnten wir auf andere Weise helfen ... – FirstOne

+0

@FirstOne Ich möchte, dass die Top-Level-Kindklasse eine DB-Transaktion innerhalb ihrer 'run'-Methode öffnet und schließt. Aber wie Sie in einigen Fällen sehen können, ist 'Kid' auf der obersten Ebene und in anderen Fällen ist es nicht – andrewtweber

+0

Nun, Sie könnten etwas mit [$ GLOBALS] versuchen (http://php.net/manual/en/reserved). Variablen.globals.php). Wenn das äußere Kind wirklich aus allem heraus ist, kannst du versuchen, es zu vergleichen, um zu sehen, ob das, was du hast, dasselbe ist wie das, was du von Globalen erhalten hast, das draußen erschaffen wurde. ** Bearbeiten: ** Beachten Sie, dass es sich nicht darum handelt, die Variable als global festzulegen. Es geht darum zu überprüfen, ob die Variable da ist ... – FirstOne

Antwort

1

Ohne zu wissen, wie Ihr Code strukturiert ist, kann ich nur zwei untergeordnete Klassen erstellen (wir nennen sie Kid1 und Kid2). Alles, was sie tun würde, ist

class Kid1 extends Kid {} 

Dann würden Sie ja

class Child extends Parent { 
    public function run() { 
     // Kid nested inside Child. Do not open DB transaction 
     $a = (new Kid1())->run(); 
    } 
} 

class Kid extends Parent { 
    public function run() { 
     // @todo Open DB transaction if not nested 
     if($this instanceof Kid2) // Open DB 
    } 
} 

nennen, doch sagen Sie noch Kid was es genannt, aber es passt mit OOP Praktiken

0

Verwenden debug_backtrace Funktion zu verfolgen Die run Methode ruft auf.
Unter allen möglichen zurückgegebenen Elemente von debug_backtrace(), class Artikel sollte in Ihrem Fall verfolgt werden.
Wenn es mehr als ein class Artikel innerhalb Stack-Trace - es ist ein "verschachtelt" Aufruf:

class Parent { } 

class Child extends Parent { 
    public function run() { 
     // Kid nested inside Child. Do not open DB transaction 
     $a = (new Kid())->run(); 
    } 
} 

class Kid extends Parent { 
    public function run() { 
     $trace = debug_backtrace(); 
     // Note that 'array_column' function is available since PHP 5.5   
     if (count(array_column($trace, 'class')) > 1) { 
      // Do not open DB transaction 
      // do another job 
     } else { 
      // Open DB transaction 
     } 
     unset($trace); 
    } 
} 

// Kid not nested. Open DB transaction 
(new Kid())->run(); 

(new Child())->run(); // Kid nested inside Child. Do not open DB transaction 

http://php.net/manual/en/function.debug-backtrace.php

+0

Ablaufverfolgung ist teuer, es ist keine gute Idee, nach etwas anderem als einem außergewöhnlichen Codepfad zu suchen. –

+0

@JoeWatkins, dennoch wird es die genauesten Informationen geben – RomanPerekhrest