我试图找到类似的问题或情况,但没有找到。 我有以下结构:

  • 类/
    • 开发/
      • class1.php
      • class2.php
    • class1.php
    • class2.php
    • class3.php

然后,代码调用:

$class1 = new class1();
$class2 = new class2();
$class3 = new class3();

'dev'文件夹包含应覆盖根类的类。 在“ dev”文件夹中有一个扩展的class1,也有class2,但没有class3。 当前,我正在尝试在自动加载功能内加载此扩展类,该功能可以正常工作,但不是我期望的方式:D

它不是从根文件夹中加载class1,而是从“ dev”文件夹中加载class1,而是仅在离开自动加载功能后才加载根类。 简化代码,我有类似:

function $autoloader($class) {
    if (!file_exists($class)) {
        echo 'failed - fallback or do something else';
        return false;
    }
    require_once($class);

    // Instantiates extended class from 'dev'
    if (file_exists($classFromDevFolder)) {
        require_once($classFromDevFolder);
        $newClass = new $classFromDevFolder();
        unset($newClass);
    }            
}

它可以工作,从“ dev”文件夹中加载类,并很好地扩展了class1。 但是,如上所述,它会在根类之前实例化dev类。 我认为是因为即使在调用根类之后,它也会在autoload函数内部加载dev类。

你们对实现它有任何想法吗? 我还考虑过创建另一个函数来加载'dev'类,但是我不知道在哪里放置它才能使该函数在任何类上工作。


我添加了这个非常简化的代码示例,以更好地说明和阐明我想要实现的目标。

根文件夹:

class Class1() {
    ...
    public function __construct() {
        $this->x = 1;
    }
    ...
}

开发文件夹:

class Class1_Dev extends Class1() {
    ...
    public function __construct() {
        $this->x = 2;
    }
    ...
}

自动加载磁带机:

function autoloader($class) {
    if (!file_exists($class)) {
        echo 'failed - fallback or something else';
        return false;
    }
    require_once($class);
    ...
    $devClass = 'dev/' . $class;
    if (file_exists($devClass)) {
        require_once($devClass);
        $newClassName = $class . '_Dev';

        // Here is the issue: it instantiates Class1_Dev before Class1,
        // and ultimately, Class1 keeps 'x' as 1, not 2
        $newClass = new $newClassName();
    }
}

码:

$class1 = new Class1();
var_dump($class1->x);

预期$ class-> x为2,而不是1。

===============>>#1 票数:0 已采纳

如果我正确理解了您的问题,则要先从dev文件夹中加载类,或者从根文件夹中不存在类。 您可以通过spl_autolaod_register轻松实现此目的:

// Please be aware that anonymous function are first available for spl_autoload_register as of PHP 5.3.0
spl_autoload_register(function ($class) {

    include 'classes/dev/' . $class . '.php';

    if (! class_exists($class)) {
        include 'classes/' . $class . '.php';
    }

}); 

然后,您应该可以调用您的课程

$class1 = new class1();
$class2 = new class2();
$class3 = new class3();

理想情况下,它将从dev文件夹中加载class1和class 2,并从根文件夹中加载class3。


更新:

如评论中已发布的,如果您加载两个具有相同名称的类,则第一个加载的类将是持久类,并且如果您尝试加载具有相同类名称的另一个类,则将失败。

我不太确定为什么要尝试这样做?

但是看一下您的代码,当我使用之前发布的autoload方法时,我可能会想到几种实现上述目标的方法。

对于一个使用实现共享逻辑的基类的示例,然后将其扩展到不同文件夹中的类:

根文件夹

class BaseClass1 {
   protected $devMode;
   protected $x;

   public function __construct() {
        $this->devMode = false;
        $this->x = 0;
   }

   public function isDevClass() {
        return $this->devMode;
   }

   public function getX() {
        return $this->x;
    }
}

开发文件夹:

class Class1 extends BaseClass1 {

    public function __construct() {
        $this->devMode = true;
        $this->x = 2;
    }
    ...
}

根文件夹:

class Class1 extends BaseClass1 {

    public function __construct() {
        parent::__construct();
        $this->x = 1;
    }
    ...
}

现在根据情况,如果在dev文件夹中有一个class1类,其构造函数将覆盖基类,则可以确定从何处加载了该类:

$class1 = new class1();

// Check if devMode is set (false by default)
if ($class1->isDevClass()) {
    // Class1 was loaded from dev, do bla; 
} else {
   // Class1 was loaded from root, do bla; 
}

// or
echo $class1->getX(); // will return 1 or 2 depending on the folder the class was loaded from

不确定这是否是您要找的东西。 严格来说,还有其他方法可以做到这一点。 您应该尽可能减少冗余。 最终,您宁愿定义一个站点范围的常量,然后将其作为标识符传递给您的类的构造方法。 然后,您可以根据构造类时设置的内容在类内部进行细微的差别。

例如,完全删除冗余的dev文件夹:

define("DEV", true);
...

class Class1 {
    protected $devMode;
    protected $x;

    public function __construct($mode = false) {
        $this->devMode = $mode;

        if ($this->devMode) {
            $this->x = 2;
        } else {
            $this->x = 1;
        }
    }

    public function doSomething() {
        if ($this->devMode) {
            // Do only devMode specific stuff
        }
    }
    ...
}
...
$class1 = new class1(DEV);

希望这可以帮助。

  ask by Julian Davi translate from so

未解决问题?本站智能推荐: