如何在PHP 5.6 __autoload()声明中使用另一个类?

时间:2016-06-30 00:25:01

标签: php class oop constructor

我有一个messageService课程,我可以像这样实例化:

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

THEN

我想在我的$messageService方法中使用__autoload对象,如下所示:

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

BUT

当我运行代码时,我得到了:

  

注意:第17行的未定义变量:messageService iin /var/www/html/beta.gmtools/api/index.php

     

致命错误:在第17行的/var/www/html/beta.gmtools/api/index.php中调用null上的成员函数logNotice()

我假设是因为$messageService不在范围内?

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

您的问题是$messageService不是自动加载功能的本地。虽然这不是处理它的最佳方式,但您可以使用$GLOBALS来获取它

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

另一种方法是使用具有__invoke魔术方法的类。您首选使用spl_autoload_register执行此操作,但它应与__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);

这里的优点是

  1. 您没有全球化任何事情
  2. 您保留messageClass
  3. 的相同实例

答案 1 :(得分:2)

我认为你有两种选择:

  • 在自动加载功能中使用global以确保其范围正确
  • 将您的$messageService::logNotice方法更改为static

使用全局$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);
}

要将您的方法更改为静态:

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);
}

我支持第二种方法,仅仅是因为它避免使用全局变量。缺点是您在整个脚本中失去了由logNotice方法中的实例变量表示的连续状态的能力,因为您将没有messageService实例。

相关问题