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

  • 类/
    • 开发/
      • 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

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

4回复

在PHP中自动加载为“模拟”类

假设我要自动加载类,到目前为止,这很正常。 现在,假设我们处于“测试”环境中。 我想加载其他类,但这些类的行为与其他类相同,但进行了一些修改。 所以,原来 和我想要的是: 因此应该使用某种“重新命名”方法,而不是重构代码。
1回复

PHP自动加载类

这是我第一次使用自动加载,但我一直收到错误,说我的课程无法找到: 编辑:第52行是我使用DB类中的静态方法的地方。 出于某种原因,PHP说它无法找到DB类。 我的结构: 文件init.php包含我的自动加载器,并包含在文件ordersetup.php中,而orderset
2回复

PHP类自动加载

我有一个“简单框架”,其主要实例是$ app。 现在,实现自动加载器的最佳方法是什么(不使用Composer)。 我需要的是有一个处理所有自动加载的类(支持各种命名空间)。 我有一些方法/困境。 起初我以为我应该创建一个处理一切的“静态”类。 但后来我想到了一些事情。 如果我在实
2回复

正确的类加载PHP

我正在用PHP学习OOP,并且遇到了正确加载类的问题。 我在HTML文件中有一个注册表,其中的数据由PHP脚本处理。 我有一个父类和几个子类,每一个都在不同的文件中。 我想将每个子类自动加载到父类中。 这是我的父类,在其中初始化子对象。 这是儿童班 如您所见,子类的对
4回复

如何自动加载扩展类?

我打算使用PHP的自动加载功能动态加载所需的类文件。 现在,如果每个函数都有一个单独的文件,这可能会造成巨大的混乱,所以我希望有一种方法可以将相关的类保留在1个类文件中,并且仍然可以自动加载 假设有一个类名动物,然后是另一个名为dog的类。 狗类扩展了动物类,现在如果我打电话给狗类而
1回复

如何从PHP中加载自动加载的类中捕获异常?

以下代码运行良好: 但如果我这样做: 在第一个代码中,我得到“无法连接到数据库!” 错误(异常捕获),但在第二次我通过连接失败得到致命错误? (例外未被捕获),我该如何解决这个问题? (注意:第二个代码中的D类位于目录\\ core \\ system \\中,原样如下
4回复

如何自动加载PHP类?

我在Wordpress中使用类,并且尝试在我的functions.php文件中自动加载它们: 这是我的classes目录的样子: 班级/ 项目/ Application.php Core.php Sit
1回复

如何自动加载PHP 5.3类?

我正在尝试自动加载我的PHP 5.3命名空间类。 我做了 问题是有时我得到类名是User有时是KM\\User如何解决此问题?
1回复

我可以在没有PHP的类中自动加载函数文件吗?

我的网站非常大,我不使用PHP类,我不太了解OO还没有重新编写我的网站使用它们但是我真的想使用类使用的__autoload($ class_name)功能。 我非常依赖函数,我有不同的函数文件, forums.inc.php blogs.inc.php user.inc.php
1回复

自动加载PHP中的类图[重复]

这个问题已经在这里有了答案: 如果类映射实际上更快,为什么在作曲家中使用PSR-0或PSR-4自动加载? 6个答案 我在某处读到,类映射自动加载比PSR-0 / PSR-4快。 当然对于开发过程来说最好使用PSR-0 / PSR-4。 我们可以使用PSR-0