PHP:如何自动加载接口和抽象



我有这个自动加载器类自动加载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();
}

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

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

PHP对任何类、接口或抽象类都没有区别。你定义的自动加载器函数总是获取要自动加载的东西的名称,并且没有提示它是哪个。

所以你的命名策略不能被自动加载,因为你用"interface_"作为接口的前缀,用"class_"作为类的前缀。我个人觉得这样的命名约定很烦人。

另一方面,你的自动加载器完全没有性能。它递归地扫描整个目录树,只是为了找到一个类!下节课又得做一遍所有的作业,没有以前做过的好处!

如果你真的想自己做这件事(而不是使用像composer这样的东西为你做),请实现PSR-0自动加载器,并坚持这个类和接口的命名方案。

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

如果前缀不匹配,它不是"你的"类想要被加载,所以你的自动加载器不知道怎么做,甚至不应该尝试,但是另一个注册的自动加载器会知道。

相关内容

  • 没有找到相关文章

最新更新