在PHP中获取扩展类的当前工作目录

7
我有一个抽象类“Class”。子类Subclass扩展了Class。抽象类Class具有以下调用:
is_readable('some_file.ext')

如何强制抽象类的子类在它们所在的文件夹中查找文件,而不是父抽象类的文件夹,而不覆盖子类中的方法?
例如,如果抽象类在classes/abstracts/Class.php中,而子类在classes/children/Subclass.php中,如何使Subclass.php在classes/children/中查找some_file.ext,而不是在classes/abstracts中,而不在Subclass中显式定义它?

2
这个问题可能有你需要的答案。https://dev59.com/mF3Va4cB1Zd3GeqPEuX4 - CLo
3个回答

16

您可以使用ReflectionClass::getFileName()来检索定义子类的文件名。

// In Superclass
public function isReadableFileInClassDir($file='somefile.ext') {
    $reflection = new ReflectionClass($this);
    $directory = dirname($reflection->getFileName()) . PATH_SEPARATOR;

    return is_readable($directory . $filename);
}

这能正常工作是因为 $this 无论在哪里定义,都将始终引用已实例化的类(而不是父类,即使 $this 出现在父类中)。


0
你可以尝试使用类似以下的代码:
is_readable(dirname(__FILE__).DIRECTORY_SEPARATOR.'some_file.ext');

dirname 方法返回您传递给它的文件的目录。

查看魔术常量以获取有关__FILE__的更多信息。

编辑

在子类中包含一个成员变量设置为__FILE__并在抽象类中引用该变量。

子类

var $source_location = __FILE__;

抽象类

is_readable($this->source_location.DIRECTORY_SEPARATOR.'some_file.ext');

不行,那仍然抓取了摘要的位置。 - Swader
是的。但正如我在原帖中所说 - 我想保持文件加载调用在抽象中,而不必在子类文件中重复它。 - Swader
感谢您的努力,但我认为您并没有完全理解 - 我不想在这个调用方面编辑子类。我希望它在抽象中定义,并且永远不会再次被触及。这样,当创建另一个子类时,开发人员甚至不会考虑这一点。 - Swader
好的,我认为PhpMyCoder已经为您提供了解决方案,他的比我的好多了。 - acqu13sce

0

我相信您在文件系统中将类和子类保存在不同的文件夹中有充分的理由,但请考虑使用Zend自动加载或基于命名空间的类加载 - 在您的情况下它将失败...

与其采用这种架构:

classes
   | - abstracts
          | - AbstractClass1.php
          | - AbstractClass2.php
   | - children
          | - ChildClass1.php
          | - ChildClass2.php

考虑一下:

classes
   | - AbstractClass1.php
   | - AbstractClass2.php
   | - AnotherClass.php
   | - AbstractClass1
          | - ChildClass1.php
          | - ChildClass12.php
   | - AbstractClass2
          | - ChildClass2.php
          | - ChildClass22.php
   | - AnotherClass
          | - ClassA.php
          | - ClassB.php
          | - ClassB
                | - ClassBA.php

通过这个架构,很清楚ClassBA在路径classes/AnotherClass/ClassB中扩展了ClassB,而ClassB又扩展了AnotherClass。现在您可以使用命名空间(当使用PHP 5.3 <时)或者像class AnotherClass_ClassB_ClassBA { ... }这样命名您的类(Zend类命名约定),您可以使用Zend自动加载程序(例如)...


我所使用的系统符合PSR-0标准,因此所有PSR-0自动加载器都能正常工作——命名空间加载已经就位,没有任何问题。我只遇到了这一个问题,但已经得到解答,不再有任何担忧 :) - Swader

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接