MVC中的PHP动态命名空间

时间:2013-05-31 20:05:05

标签: php namespaces autoloader

我正在开始一个新的应用程序,并最终决定使用命名空间加入新时代。我发现自己经常写这样的代码:

 $dynamicControllerName = "MyController";
 $controllerName = "System\\App\\Controllers\\" . $dynamicControllerName;
 $controller = new $controller;

无论何时我尝试使用use关键字,它似乎都不起作用(或者我理解不正确):

 use System\App\Controllers as Controller

然后

 $dynamicControllerName = "MyController";
 $controllerName = "Controller\\" . $dynamicControllerName;
 $controller = new $controller;

这使我的自动加载器认为路径是我的基本路径加上“/ Controller / MyController”而不是所需的“/ System / App / Controllers / MyController”。我尝试了的不同组合,而没有前缀斜杠。

我正在尝试的一个真实世界的例子看起来像这样(试图获取MyController):

 namespace System\App\Lib;

 use System\App\Controllers as Controller;

 class Router
 {
    public function dispatch(Request $request)
    {
        //...some dispatch code here

        // Instantiate Controller (THIS DOESNT WORK)
        $controllerName = "Controller\\" . $request->controller;
        $controller = new $controllerName($param1, $param2);

        //...some dispatch code here
    }
 }

我认为以上会从我的自动加载器中请求一个名为 System \ App \ Controllers \ MyController 的类,然后我可以翻转斜杠并添加文件扩展名和瞧。相反,它来自 Controller \ MyController ,它不存在。是因为路由器类位于不同的命名空间中?我错过了什么?

TL; DR;在MVC模式中,如何动态实例化类实例而无需每次都键入完全限定的命名空间?

P.S。我正在使用PHP 5.4.15

修改

自动加载设置为:

// Define AutoLoading
spl_autoload_register(array('System\App', 'autoload'));

自动加载功能:

/**
* Autoloading via PSR-0 Namespacing
*/
protected static function autoload($className = false)
{
    var_dump($className);
    if($className)
    {
        $className = ltrim($className, '\\');
        $fileName  = '';
        $namespace = '';
        if ($lastNsPos = strripos($className, '\\')) {
            $namespace = substr($className, 0, $lastNsPos);
            $className = substr($className, $lastNsPos + 1);
            $fileName  = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
        }
        $fileName .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
        $fileName = App::$SYS_PATH . DIRECTORY_SEPARATOR . $fileName;
        include_once $fileName;
    }
}

当我转储$className时,我可以看到PHP是否正在识别命名空间。

0 个答案:

没有答案