1

私は現在、単一のファイル セット/ホスティング環境から複数のサイトのコンテンツを強化するために使用されるアプリケーションを開発しているプロジェクトに取り組んでいます。

model_accountやなどの名前を持つ PHP クラスが多数あり、model_vehicleそれらはクラス名として save という名前の別のファイルで定義されています。以下のようにクラスファイルをロードするために使用spl_autoload_registerしています(簡略化):

function my_autoloader($class_name) {
    if(substr($class_name, 0, 6)=='model_') {
        require_once('models/'.$class_name.'.php');
    }
}

私たちがやりたいことは、訪問者がサイト xxx にアクセスしていて、クラスのインスタンスを作成する場合です。たとえば、ファイルが存在する場合$account = new model_account();は実際にクラスのインスタンスを作成model_xxx_accountし ( models/model_xxx_account.php)、存在しない場合は、models/model_account.phpファイルを含めて、のインスタンスを作成しますmodel_account

同様に、訪問者がサイト yyy から来た場合、存在する場合は使用し、存在しない場合はmodel_yyy_account完全に戻ります。model_account

基本的に、条件が満たされた場合に別のクラスのインスタンスを作成したいのですが、同じインスタンス化呼び出しから作成します。

CI や Cake のような市販のフレームワークは使用していません。また、この投稿の命名規則を少し簡略化しました。オブジェクト指向の用語が適切でない場合は申し訳ありません。

4

4 に答える 4

5

クラスのロードを処理するには、ある種のファクトリ パターンを使用する必要があるようです。

もしそうなら$account = new SomeClass()、実際に のオブジェクトになってしまうのは意味がありませんclass Bumblebee

技術的には、どのクラスを提供するかを決定する何らかのアカウント ファクトリが必要です。

コードは最終的に のよう$account = AccountFactory::retrieveModel()になり、オートローダーに委譲せずにロードするモデルを決定できます。

オートローダーの要点は、本質的に「私はこの正確なクラスが欲しい」と言うことであり、ぐらついたり、特にそのような決定を下したりすることではありません。ファクトリは実際にファイル構造を調べて、関数呼び出しで返すクラスを決定できます。コードでは、new必要なモデルを取得するために依存していません。理論的にはすべてのアカウント モデルが同じインターフェースを共有するか、少なくとも拡張しmodel_accountます。

AccountFactory は基本的に、「model_yyy_account存在するため、return new model().

于 2012-10-16T21:48:27.290 に答える
2

できないと思います。オートローダーは、含めるファイルの選択にのみ役立ち、クラスの変更はできません。

しかし、それは問題ではないはずです。各Webサイトのクラスに名前を付けることができますmodel_account。サイトは、どのファイルが含まれるか、したがってどのバージョンmodel_accountがインスタンス化されるかを決定します。model_xxx_account両方と1つのリクエストで両方が必要になることは決してないので(仮定)model_yyy_account、同じ名前であっても、お互いに干渉することはありません。

PS:ファイルにも同じ名前を付け、サイトごとに個別のフォルダーとデフォルトのフォルダーを作成します。これにより、サイトごとに上書きされたファイルを見つけやすくなり、名前の衝突のリスクが軽減されます。

于 2012-10-16T21:34:55.020 に答える
1
$SiteID = 'xxx'; // Modify as you wish from your subdomain or whatever
// class_exists triggers the autoloader
if(!class_exists($ClassName =  "model_{$SiteID}_account")){
    // If class is missing, fall back to default
    $ClassName =  "model_account"; // This should exist
}
$Model = new $ClassName(); // Instantiate your Account Model

$SiteIDに _ と英数字が含まれていることを確認してください。したがって、クラス名に適しています。

また、絶対に相対パスからrequire_onceを実行しないでください。常に行う:

require_once __DIR__.'/models/'.$class_name.'.php'; // PHP 5.3+
// or
require_once dirname(__FILE__).'/models/'.$class_name.'.php'; // PHP 5.2-

安全を保つために。このようにして、Account Model クラスを探している場所を正確に知ることができます。

于 2012-10-16T21:42:51.037 に答える
-1

あなたは確かにこれを行うことができます:

$className = "MyClassName";
$myObject = new $className();

条件に基づいて$classNameを動的に定義できる場所。

于 2012-10-16T21:35:09.627 に答える