2017-06-01 1 views
1

Ich habe dieses wirklich seltsame Verhalten von PHP erlebt und bin etwas verloren.Die statische Klassenmethode gibt ein Objekt zurück, wenn es außerhalb von Klassen aufgerufen wird, gibt aber ein leeres Objekt zurück, wenn es innerhalb verschiedener Klassen aufgerufen wird

Die Zusammenfassung: Ich habe Doctrine ORM Setup mit meiner eigenen Abstraktions-Klasse, um es ein bisschen einfacher zu machen, mit Entitäten zu interagieren, während Sie die Vorteile von Doctrine haben. Ich weiß, dass ich die Abhängigkeitsinjektion hinzufügen muss, aber das ist ein Anfang.

Ich habe Entity ORM Anrufe funktioniert gut mit den Tests, die ich von einem Controller-Skript gemacht habe, die eine einfache Datei außerhalb jeder Klasse ist.

Sobald ich versuche, irgendeine Entity ORM Aufrufe innerhalb einer anderen Klasse zu tun, gibt es ein leeres Objekt zurück. Ich habe die Dinge auf eine statische Methode zurückgeführt, die den EntityManager für Doctrine erstellt. Es ist wirklich komisch; innerhalb der statischen Methode kann ich das Objekt verfolgen, das ich erstelle/zurückgebe und es ist in Ordnung. Wenn ich die statische Methode tatsächlich aufruft, ist der zurückgegebene Wert ein leeres Objekt. Hier ist eine vereinfachte Struktur:

namespace MyApp\Core; 

use MyApp\Core\System; 
use Doctrine\ORM\Tools\Setup; 
use Doctrine\ORM\EntityManager; 

class SystemDBA { 

public static function entityManager() 
{ 
    $paths = array(PLATFORM_ROOT."/classes/entities"); 
    $isDevMode = false; 

    $db_settings = System::getSystemSettings(); 

    $dbParams = array(
     'driver' => 'pdo_mysql', 
     'user'  => $db_settings['username'], 
     'password' => $db_settings['password'], 
     'dbname' => $db_settings['database'], 
    ); 

    $config = Setup::createAnnotationMetadataConfiguration($paths, $isDevMode); 

    $em = EntityManager::create($dbParams, $config); 

    // this will always return the right kind of EntityManager object no matter where an entity is called from. 
    error_log(json_encode($em)); 

    // this however is sending back an empty object when an entity is called inside of a class. 
    return $em; 
} 

Die $em Rückkehr vs error_log ist, wo das Problem oben ist. Egal, wo das System von error_log aufgerufen wird, ist immer korrekt, aber die Rückgabe ist nicht korrekt. Hier ist der Rest der Kette:

namespace MyApp\Entities; 

use MyApp\Core\System; 
use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\ORM\Mapping as ORM; 

use MyApp\Core\SystemDBA; 

class EntityBase 
{ 

    public static function find($id) 
    { 
     $db = SystemDBA::entityManager(); 
     // if it's an array of ids we can try to get multiples 
     $object = $db->getRepository(get_called_class())->findOneBy(['id'=>$id]); 

     if ($object) return $object; 

     return false; 
    } 

Die erste Zeile des Verfahrens find() ist, wo $db ist ein leeres Objekt anstelle einer Lehre EntityManager Objekt wie ich erwarte.

EDIT Ich habe bestätigt, dass get_called_class()MyApp\\Entities\\People in EntityBase unabhängig davon zurückkehrt, ob ich das Unternehmen von einer anderen Klasse aufrufen, oder von einem eigenständigen PHP-Datei. Es scheint also kein Problem des Repository-Klassennamens zu sein.

namespace MyApp\Entities; 

/** 
* @Entity 
* @Table(name="people") 
*/ 

class People extends EntityBase { 

Einfache ORM Entity-Klasse, die EntityBase

So erstreckt sich schließlich, wenn ich ein Unternehmen von einem Standalone-Controller wie folgt aufrufen:

namespace MyApp\Controllers; 
use MyApp\Entities\People; 

$user = People::find(123); 

Es funktioniert gut, SystemDBA::entityManager() sowohl nach außen kehrt und auch verfolgt intern das richtige Objekt.

Wenn ich jedoch versuche, dies aus einer anderen Klasse heraus auszuführen, verfolgt SystemDBA::entityManager() intern das richtige Objekt, gibt aber extern ein leeres Objekt zurück.

namespace MyApp\SomeStuff; 

use MyApp\Entities\People; 

class myClass { 
    protected function getUser($user_id) { 
     $user = People::find(123); 
     } 

Ich dachte anfangs war dies Lehre verwandt, aber es scheint, mit PHP im Allgemeinen irgendeine Art von Problem zu sein. Ich habe versucht, die Klassenmethode im letzten Beispiel zu ändern, um nicht geschützt zu sein, aber scheint keine Bedeutung zu haben. Jeder Einblick würde sehr geschätzt werden!

Antwort

1

http://php.net/manual/en/function.get-called-class.php

Ruft den Namen der Klasse die statische Methode in genannt wird.

Und Sie rufen statische Methode innerhalb myClass, so kann es nicht funktionieren.

Übrigens würde ich nicht empfehlen, so zu gehen, nach einiger Zeit werden Sie es wirklich bereuen statisch zu sein, Abhängigkeiten wie diese einzuführen. Und Sie erstellen neue EntityManager Instanz bei jedem Aufruf (also eine neue Verbindung), das ist ineffizient und wird Lehrverhalten brechen (Sie können über Arbeitseinheit lesen).

Abhängigkeit Injektion mit Container ist der richtige Weg.

+0

Sie sind zu 100% korrekt, sollte ich Dependency-Injektion verwenden –

+0

Sie wissen, soweit die Klassennamen-Lookup geht, habe ich versucht, Fehlerprotokollierung, dass es denken könnte das Problem, aber ich habe immer die gleiche Entity-Klasse Name unabhängig davon, woher es aufgerufen wurde. Ich werde die Abhängigkeitsinjektion versuchen und dies und von dort aus gehen. –

+0

Ich habe gerade bestätigt, dass 'get_called_class() ''' MyApp \\ Entities \\ People' in EntityBase zurückgibt, unabhängig davon, ob ich es von einer anderen Klasse oder von einer eigenständigen PHP-Datei aus anrufe. Das scheint also nicht das direkte Problem zu sein. Hinzufügen dieses Punktes als Bearbeitung –

Verwandte Themen