PHP:如何自动加载接口和摘要(PHP: how to autoload interfaces an

2019-08-18 02:19发布

我有这样的自动加载类的自动加载classes开始,但现在我想自动载入interfacesabstracts ,以及。

所以,我提出以下这个变化的答案 ,

$reflection = new ReflectionClass($class_name);

# Return boolean if it is an interface.
if ($reflection->isInterface())
{
    $file_name = 'interface_'.strtolower(array_pop($file_pieces)).'.php';
}
else
{
    $file_name = 'class_'.strtolower(array_pop($file_pieces)).'.php';

}

我测试了它,但这自动加载类没有加载所有的接口。 任何想法我错过了什么?

举例来说,这是我的接口文件,

interface_methods.php

和它的内容,

interface methods 
{
    public function delete();
}

下面是我的整个这个自动加载类。

class autoloader
{
    /**
     * Set the property.
     */
    public $directory;
    public $recursive;

    public function __construct($directory, $recursive = array('search' => 'models') ) 
    {
        # Store the data into the property.
        $this->directory = $directory;
        $this->recursive = $recursive;

        # When using spl_autoload_register() with class methods, it might seem that it can use only public methods, though it can use private/protected methods as well, if registered from inside the class:
        spl_autoload_register(array($this,'get_class'));
    }

    private function get_class($class_name)
    {
        # List all the class directories in the array.
        if ($this->recursive)
        {
            $array_directories =  self::get_recursive_directory($this->directory);
        }
        else
        {
            if (is_array($this->directory)) $array_directories =  $this->directory;
            else $array_directories =  array($this->directory);
        }

        # Determine the class is an interface.
        $reflection = new ReflectionClass($class_name);

        $file_pieces = explode('\\', $class_name);

        # Return boolean if it is an interface.
        if ($reflection->isInterface())
        {
            $file_name = 'interface_'.strtolower(array_pop($file_pieces)).'.php';
        }
        else
        {
            $file_name = 'class_'.strtolower(array_pop($file_pieces)).'.php';

        }

        # Loop the array.
        foreach($array_directories as $path_directory)
        {
            if(file_exists($path_directory.$file_name)) 
            {
                include $path_directory.$file_name;
            } 
        }

    }

    public function get_recursive_directory($directory)
    {
        $iterator = new RecursiveIteratorIterator
                    (
                        new RecursiveDirectoryIterator($directory),
                        RecursiveIteratorIterator::CHILD_FIRST
                    );

        # This will hold the result.
        $result = array();

        # Loop the directory contents.
        foreach ($iterator as $path) 
        {

            # If object is a directory and matches the search term ('models')...
            if ($path->isDir() && $path->getBasename() === $this->recursive['search']) 
            {

                # Add it to the result array.
                # Must replace the slash in the class - dunno why!
                $result[] = str_replace('\\', '/', $path).'/';
                //$result[] = (string) $path . '/';

            }

        }

        # Return the result in an array.
        return $result;
    }
}

Answer 1:

PHP使任何类或接口或抽象类之间没有什么区别。 你总是定义的自动加载功能得到的东西自动加载的名字,也没有那种暗示这是其中之一。

所以,你的命名策略不能自动载入,因为你前面加上“interface_”类的接口,并与“class_”。 我个人认为,这样的命名约定相当恼人。

在另一方面,磁带自动加载机是完全unperformant。 它会扫描整个目录树递归只是为了找到一个班! 而接下来的类必须再次完成所有的工作,没有之前已经做它的好处!

请不要实施PSR-0自动加载如果你真的想这样做你自己(而不是使用之类的作曲家来为你做它),并坚持为类和接口这一命名方案。

并且请选择一个区别类名前缀或命名空间,并作为磁带自动加载机中的第一步检查,如果要加载的类有这个前缀。 返回立即若没有。 这使你不必旋转的硬盘,看看是否为类文件存在。

如果前缀不匹配,这是不是“你的”类要被加载,所以磁带自动加载机无法知道该怎么做,不应该去尝试,但被注册的不同自动加载机就知道了。



文章来源: PHP: how to autoload interfaces and abstracts