我正在开始一个新的应用程序,并最终决定使用命名空间加入新时代。我发现自己经常写这样的代码:
$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是否正在识别命名空间。