继承和组合中的自动加载和命名空间

时间:2014-08-01 22:39:13

标签: php inheritance namespaces autoload

我写了一个Autoload:

<?php
function autoload($class)
{
    try
    {   
        global $path;
        $elements = explode("\\", $class); 
        $name_class = end($elements); 

        foreach ($elements as $element)
            {   
                if($element != $name_class)
                    {
                        $path .= $element."/"; 
                        echo "path:".$path."<br/>";
                    }
            }

        $file = strtolower(($path).$name_class.".php");  
        if(file_exists($file))
        {
              include($file);
              return;
        }
         throw new Exception($class." not founded");
    }
    catch(Exception $e)
    {
        echo $e->getMessage();
        return;
    }
}

class Autoloader
{
    public static function autoload($class)
    {
        autoload($class);
    }
}

spl_autoload_register('autoload');
spl_autoload_register(array('autoloader', 'autoload'));
?>

Autoload找到相对路径并在绝对路径中更改它。

现在,当我从具有不同命名空间的另一个文件调用一个类时,我遇到了问题。

例如,如果我在directorynamed框架中有这个文件Base.php:

namespace Framework;

use Framework\Inspector as Inspector;

 class Base
    {
        private $_inspector;

        public function __construct($options = array())
        {
            $this->_inspector = new Inspector($this);
...

现在,我将文件Inspector.php放在同一目录中,并使用相同的命名空间:

<?php
namespace Framework;

    use Framework\ArrayMethods as ArrayMethods;
    use Framework\StringMethods as StringMethods;
    use \Exception as Exception;

    class Inspector
    {
...
?>

当我尝试实例化Base类时,我收到有关缺少Inspector类的异常消息。

同样的想法,如果我尝试在其他目录中扩展Base类。我尝试在自动加载功能中添加一些回声,并打印出他使用子类的本地命名空间或者通过另一个类的组合使用实例来创建用于查找php文件的字符串的类。

例如,当我尝试使用echo时,在Base中加载Inspector:

path:Framework/
file:::C:\LightTPD\htdocs\mvc\framework\framework\Base.php (I add some ::: to make more readable)
framework/base.php


path:Framework/Framework/
file:::
framework/framework/inspector.php (trying to use the namespace of inspector after using the one of Base)


Framework\Inspector not foundedpath:Framework/Framework/Framework/
file:::
framework/framework/framework/inspector.php

Framework\Inspector not founded

当我尝试按类驱动程序扩展类Base时,我得到了这个:

path:Framework/
path:Framework/Configuration/
file:::C:\LightTPD\htdocs\mvc\framework\framework\configuration\Driver.php
framework/configuration/driver.php (everything ok)


path:Framework/Configuration/Framework/ (Framework is from Base; Configuration/Framework is from driver)
file:::
framework/configuration/framework/base.php 


Framework\Base not foundedpath:Framework/Configuration/Framework/Framework/
file:::
framework/configuration/framework/framework/base.php


Framework\Base not founded

- ############################################## ################# 目录树是:

这是:

-framework: ArrayMethods.php, Base.php,Configuration.php, Inspector.php, StingMethods.php
           -configuration: Driver.php
                -exception
           -core
                -exception

我该如何解决?

1 个答案:

答案 0 :(得分:0)

抱歉,我注意到问题是全局$ path。

现在我用这种方式写了autoload.php:

<?php
function autoload($class)
{
    try
    {   $path = NULL;
        $elements = explode("\\", $class); 
        $name_class = end($elements); 

        foreach ($elements as $element)
            {   
                if($element != $name_class)
                    {
                        $path .= $element."/"; 
                        $file = realpath(strtolower(($path).$name_class.".php"));  //realpath is optional 
                        if(file_exists($file))
                                {
                                      include($file);                       
                                      //echo $file."<br><br>"; testing in for debugging
                                      return;
                                }
                    }
            }   
       throw new Exception($class." not founded");
    }
    catch(Exception $e)
    {
        echo $e->getMessage();
        return;
    }
}

class Autoloader
{
    public static function autoload($class)
    {
        autoload($class);
    }
}

spl_autoload_register('autoload');
spl_autoload_register(array('autoloader', 'autoload'));
?>

现在,即使它的性能较差,一切都没问题,无论是什么类调用另一个类,它都只是基于类的命名空间。