現在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はその2番目のインスタンスに対してPollDbModelをロードします。 –
あなたの答えをありがとう。それはまさに私が数時間前に思ったことです。 HMVCパターンを使用するので、すべてのコントローラは私の 'Request'クラスを通してインスタンス化されます。そこで、私のコントローラのメソッドをオートローダーとして追加し、リクエストが完了したらそれを削除します。これは本当にうまくいく。ご協力いただきありがとうございます! – Frog