현재 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()
을 사용하여 현재 응용 프로그램을 얻는 것을 볼 수 있습니다. 종속성을 도입 한 이후로 많은 사람들에게 나쁜 것입니다. 또한 모델을 시작하는 클래스에 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);
}
}
즉, 요청 클래스의 모든 요청마다 값을 변경해야한다는 의미입니다. 처음 시작 게시물에서 수정 한 코드보다 실제로 더 낫습니까? – Frog
각 응용 프로그램에 대해 별도의 오토로더를 작성하여 해결할 수 있다고 생각합니다. MyApplication :: install()과 같은 것을 호출 할 등록 메커니즘을 생성하십시오. 이러한 솔루션은 코드에 더 많은 모듈성을 제공합니다. 다른 장점은 다른 응용 프로그램에서 동시에 클래스를로드 할 수 있다는 것입니다 (성능 문제가 발생하기 때문에 어떤 것이 더 중요한지 결정해야합니다). 예 : PollApp은 폴링의 첫 번째 인스턴스에서 PollTextModel을로드 한 다음 NewsApp에서 일부 클래스를로드하고 마지막에는 PollApp이 두 번째 인스턴스에 대해 PollDbModel을로드합니다. –
답변 해 주셔서 감사합니다. 그게 바로 내가 몇 시간 전에 생각한 것입니다. HMVC 패턴을 사용하기 때문에, 모든 컨트롤러는 나의'Request' 클래스를 통해 인스턴스화됩니다. 그래서 컨트롤러의 메소드를 오토로더로 추가하고 요청이 완료되면 제거합니다. 이것은 정말 잘 작동합니다. 당신의 도움을 주셔서 감사합니다! – Frog