我正在使用HMVC設計模式編寫我自己的PHP框架作爲學習練習。它所有的工作:),但我看過很多次,這是一個壞習慣,是指靜態類在PHP代碼,而這正是我在自動加載功能正在做:在特定文件夾中自動加載模型類的最佳方法HMVC
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 . '".');
}
}
正如你可以看到我使用靜態調用Dispatcher::getApplicationName()
得到當前應用程序,根據許多人的說法,這是不好的,因爲它引入了依賴關係。我還可以使用debug_backtrace()
來獲取applicationName,因爲啓動模型的類包含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);
}
}
這意味着我必須更改我的Request類中每個請求的值。這真的比我現在在開始文章中編輯的代碼好嗎? – Frog
我相信這可以通過爲每個應用程序創建單獨的自動加載器來解決。創建註冊機制,它將調用類似MyApplication :: install()的東西。這樣的解決方案將爲您的代碼提供更多的模塊化。 這樣做的另一個好處是可以從不同的應用程序同時加載類(儘管它帶來了一些性能問題,因此您需要決定哪一個更重要)。例如。 PollApp在poll的第一個實例中加載PollTextModel,然後NewsApp加載一些類,最後PollApp加載PollDbModel作爲它的第二個實例。 –
感謝您的回答。這正是我幾個小時前想到的。由於我使用HMVC模式,每個控制器都通過我的'Request'類來實例化。所以我添加一個我的控制器作爲自動加載器的方法,並在請求完成時將其刪除。這工作得很好。謝謝你的幫助! – Frog