2016-06-30 15 views
0

Ich habe eine messageService Klasse, die ich wie folgt instanziieren:Wie kann ich eine andere Klasse in meiner PHP 5.6 __autoload() Deklaration verwenden?

require_once("./classes/messageService.class.php"); 
$messageService = new messageService(); 

DANN

Ich möchte in meiner __autoload Methode, um das $messageService Objekt verwenden, die wie folgt aussieht:

function __autoload($className) { 
    $fileName = "./classes/" . $className . ".class.php"; 
    require_once($fileName); 
    $messageService->logNotice("Loaded File: " . $filename); 
} 

Aber

Wenn ich den Code ausführen, bekomme ich:

Notice: Undefined variable: messageService iin /var/www/html/beta.gmtools/api/index.php on line 17

Fatal error: Call to a member function logNotice() on null in /var/www/html/beta.gmtools/api/index.php on line 17

Was ich nehme ist, weil $messageService nicht im Geltungsbereich ist?

Wie kann ich dieses Problem lösen?

+0

Wenn ich '$ messageService = new messageService() ändern;' zu 'global $ messageService = new messageService();' Der Server löst einen Fehler von 500 aus. –

+0

Der Fehler bedeutet, dass Ihr '$ messageService' nicht mehr als Objekt definiert ist. Wahrscheinlich haben Sie mit Ihrem variablen Bereich etwas falsch gemacht.Einige Dokumentation: [Variablenbereich] (http://php.net/manual/en/language.variables.scope.php) – Nytrix

Antwort

2

Ihr Problem ist, dass $messageService nicht lokal für die Autoload-Funktion ist. Zwar ist dies nicht der beste Weg ist, um es zu behandeln, können Sie ein $GLOBALS zu bekommen, um es

function __autoload($className) { 
    $fileName = "./classes/" . $className . ".class.php"; 
    require_once($fileName); 
    $GLOBALS['messageService']->logNotice("Loaded File: " . $filename); 
} 

Ein anderen Weg, dies zu tun, ist eine Klasse mit der __invoke magischen Methode zu verwenden. Es ist bevorzugt, Sie dies tun mit spl_autoload_register aber es sollte hier mit __autoload

class Loader { 
     /** @var messageService */ 
     protected $message; 

     public function __construct() { 
      require_once("./classes/messageService.class.php"); 
      $this->message = new messageService(); 
     } 

     public function __invoke($className) { 
      $fileName = "./classes/" . $className . ".class.php"; 
      require_once($fileName); 
      $this->message->logNotice("Loaded File: " . $filename); 
     } 
} 

$autoload = new Loader(); 
spl_autoload_register($autoload); 

Der Vorteil Arbeit ist, dass

  1. Sie sind nicht alles globalisiert
  2. Sie die gleiche Instanz Ihrer messageClass halten
2

Wie ich es sehe, haben Sie zwei Möglichkeiten:

  • Verwenden global in Ihrer Autoload-Funktion sicher zu sein, es richtig
  • ändern $messageService::logNotice Methode scoped ist zu sein static

ein global zu verwenden $messageService:

require_once("./classes/messageService.class.php"); 
$messageService = new messageService(); 

function __autoload($className) { 
    // This is where you tell the current scope you want to reference 
    // the global variable 
    global $messageService; 
    $fileName = "./classes/" . $className . ".class.php"; 
    require_once($fileName); 
    $messageService->logNotice("Loaded File: " . $filename); 
} 

Ihre Methode ändern statisch sein:

class messageService 
{ 
    public static function logNotice($msg) { /** **/ } 
} 

// Be sure the class is manually included first 
require_once '/path/to/messageService.php'; 
function __autoload($className) { 
    $fileName = "./classes/" . $className . ".class.php"; 
    require_once($fileName); 
    // Note you're not using a variable here, you're calling the class 
    messageService::logNotice("Loaded File: " . $filename); 
} 

Ich würde für den zweiten Ansatz argumentieren, einfach weil es die Verwendung einer globalen Variable vermeidet. Der Nachteil ist, dass Sie die Möglichkeit verlieren, einen kontinuierlichen Status zu haben, wie er von Instanzvariablen innerhalb Ihrer logNotice Methode in der gesamten Prozedur Ihres Skripts dargestellt wird, da Sie keine messageService Instanz haben.