我正在开始一个新的应用程序,并最终决定使用命名空间加入新时代。我发现自己经常写这样的代码:
$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的形式出现。是因为Router类位于不同的命名空间中吗?我错过了什么?
TL;博士; 在 MVC 模式中,如何动态实例化一个类实例,而不必每次都键入完全限定的命名空间?
PS 我正在使用 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 是否正在识别名称空间。