我目前正在使用 HMVC 设计模式编写自己的 PHP 框架作为学习练习。一切正常:),但我读过很多次,在 PHP 代码中引用静态类是一个坏习惯,这正是我在自动加载函数中所做的:
function __autoload($className) {
$path = SERVER_ROOT . DS . 'applications' . DS . Dispatcher::getApplicationName() . DS . 'models' . DS . 'class.' . strtolower($className) . '.php';
if (file_exists($path)) {
require_once($path);
} else {
throw new Exception('Can\'t find a model at "' . $path . '".');
}
}
如您所见,我使用 static call 获取当前应用程序Dispatcher::getApplicationName()
,这在许多人看来很糟糕,因为它引入了依赖关系。我也可以使用 获取 applicationName debug_backtrace()
,因为启动模型的类包含 ApplicationName 作为属性。那更好,还是我没有想到其他选择?
谢谢!
编辑:忘了提到上面的代码还有另一个问题:控制器的应用程序并不总是等于调度程序的应用程序,因为我使用的是 HMVC 设计模式(所以控制器在控制器内部被调用)。这只能使用debug_backtrace
.
编辑:而不是Dispatcher::getApplicationName()
我现在使用Request::getCurrentApplicationName()
. 它现在又可以工作了,因为我的请求类保存了所有应用程序。这是更好,还是有更好的方法?
<?php
class Request {
private static $_controllers = array();
private static $_applicationsNames = array();
public static function _getCurrentApplicationName() {
return end(self::$_applicationsNames);
}
public static function _load($applicationName, $controllerName, $methodName) {
// Add the application the the array (for autoloading).
self::$_applicationsNames[] = $applicationName;
// Check if the controller has already been instantiated.
if (!isset(self::$_controllers[$applicationName . DS . $controllerName])) {
require_once(APPLICATIONS_ROOT . DS . $applicationName . DS . 'controllers' . DS . 'class.' . $controllerName . '.php');
self::$_controllers[$applicationName . DS . $controllerName] = new $controllerName($applicationName);
}
// Get the user arguments.
$arguments = array_slice(func_get_args(), 3);
// Call the method.
$result = call_user_func_array(array(self::$_controllers[$applicationName . DS . $controllerName], $methodName), $arguments);
// Remove the last value from the applications array.
array_pop(self::$_applicationsNames);
}
}