2009-04-27 21 views
36

最近、ほとんどのWeb開発者のように、私はWebアプリケーションやサイトのための強固なMVCアーキテクチャの恩恵を享受しています。 PHPでMVCを行うとき、オートローディングは明らかに非常に便利です。効率的なPHPの自動ロードと命名の戦略

__autoload()という機能を定義するだけで、私はspl_autoload_registerのファンになりました。これは、独自のオートローディングを使用する異なるベースモジュールを組み込んでいる場合は明らかです。しかし、私が書いたローディング関数については、決して素晴らしいことはありませんでした。可能なクラスをロードするために、多くの文字列チェックとディレクトリスキャンが必要です。

たとえば、のは、私がPATH_APPとして定義された基本パスを持っているアプリ、およびmodelsviewscontrollersを指定されたディレクトリを持つ単純な構造を有しているとしましょう。私はしばしばファイル名がIndexView.phpIndexController.phpという適切なディレクトリ内にあり、モデルには一般的にはデフォルトで特別なスキームはないという命名構造を採用しています。それはその後に発見されていない場合、私はモデルのディレクトリにサブディレクトリをスキャンするために別の機能を持っているかもしれません

public function MVCLoader($class) 
{ 
    if (file_exists(PATH_APP.'/models/'.$class.'.php')) { 
     require_once(PATH_APP.'/models/'.$class.'.php'); 
     return true; 
    } 
    else if (strpos($class,'View') !== false) { 
     if (file_exists(PATH_APP.'/views/'.$class.'.php')) { 
      require_once(PATH_APP.'/views/'.$class.'.php'); 
      return true; 
     } 
    } 
    else if (strpos($class,'Controller') !== false) { 
     if (file_exists(PATH_APP.'/controllers/'.$class.'.php')) { 
      require_once(PATH_APP.'/controllers/'.$class.'.php'); 
      return true; 
     } 
    } 
    return false; 
} 

:私はspl_autoload_registerに登録されます。このように、この構造のためのローダ機能を持っているかもしれません。しかし、if/elseing、文字列のチェックとディレクトリスキャンはすべて私にとっては非効率的だと思うので、私はそれを改善したいと思います。

他の開発者が採用している可能性のあるファイル命名方法とオートロード方法は非常に不思議です。私は、効率的なオートローディングのための優れたテクニックを特に探しています。オートローディングの代替方法ではありません。

答えて

28

これは私が(最後の1のソースからまっすぐに持ち上げた)私のプロジェクトのすべてで使用されているものです:私はSomeClass_SeperatedWith_Underscoresを探している場合、それは工ass続いSomeClass_SeperatedWith_Underscores.php探します

public static function loadClass($class) 
{ 
    $files = array(
     $class . '.php', 
     str_replace('_', '/', $class) . '.php', 
    ); 
    foreach (explode(PATH_SEPARATOR, ini_get('include_path')) as $base_path) 
    { 
     foreach ($files as $file) 
     { 
      $path = "$base_path/$file"; 
      if (file_exists($path) && is_readable($path)) 
      { 
       include_once $path; 
       return; 
      } 
     } 
    } 
} 

/SeperatedWith/Underscores.phpは、現在のインクルードパスの各ディレクトリをルートにしています。

編集:私は、これを開発の効率化のために使用し、必ずしも処理時間ではないことを言いたいと思います。パスにPEARがある場合は、これを使用するだけでクラスを使用でき、必要なときにクラスを含める必要はありません。

名前空間を分割するアンダースコアを使用してクラスをディレクトリ階層に保つ傾向があります。このコードを使用すると、ファイル構造をきれいに保つことができ、必要に応じてきちんと整えられます。私は(それは私が現在働いているプロジェクトの一部の被告ではなく、ライブラリに、単一のクラスまたは2を追加する。)したい

+3

寒さのためのポンド+1 – Louis

+0

確かにアンダースコアアプローチが好きです。これは、クラスツーファイル変換をより効率的にします。 – zombat

+3

'$ files'配列の周りに' array_unique() 'をラップします。クラス名にアンダースコアがない場合は、各ファイルを2回試してみます。 – mpen

13

私はこのソリューションに上陸した:

私はシングルを作成しましたクラスライブラリフォルダ(別のモジュール/システム用のサブフォルダを含む)を走査し、クラス定義を探すファイルの内容を解析するスクリプト。それはPHPファイル(非常に単純な正規表現パターン)でのクラス定義を見つけた場合、それは、シンボリックリンクを作成します。

class_name.php -> actual/source/file.php 

これは私が唯一のクラス名とパスを必要とする1つの単純なオートロード機能を使用することができますメインのsymlinkフォルダにあり、パス/文字列の操作は必要ありません。

私のソースコードを完全に並べ替えることも、新しいサブシステムを追加して、リンクを生成するスクリプトを実行してすべてを自動ロードすることもできます。

+0

これはおそらく私が今までに見つけた最も創造的な解決策です。いい物。好奇心から、クロスプラットフォームはどのようなアプローチになるでしょうか? – zombat

+4

私はLinuxで作業を始めて以来、Windowsの主な苦境の一つはシンボリックリンクの欠如です。私の知る限り、この解決法はunixでしか動作しません。 – grossvogel

+5

参考にして、Windowsでは 'mklink'を使ってシンボリックリンクを作成することができます:http://www.howtogeek.com/howto/windows-vista/using-symlinks-in-windows-vista/ –

7

効率を上げるには、自動読み込み機能を使用しないでください。自動読み込み機能は、怠け者のためのものです。インクルードファイルをインクルードするときにインクルードファイルへの明示的なパスを提供する必要があります。あなたのオートロード機能がこれらのファイルを見つけることができれば、コードを明示的に見つけることができます。コードのビュー部分で作業しているときに、新しいビュークラスをロードするときに、オートロード関数で処理するようにすると、まずクラスがモデルクラスであるとみなされますか?それは非効率的です。代わりにあなたのコードは、単に次のようになります。

include_once $this->views_path . $class . '.php'; 

あなたは複数の「ビュー」のパスが必要な場合は、ビューをロードする機能作る:インクルードが発生含ま時点では、いずれの場合も

public function load_view($class) { 
    // perhaps there's a mapping here instead.... 
    foreach ($this->views_paths as $path) { 
     $filename = $path . $class . '.php'; 
     if (file_exists($filename)) { 
      include_once $filename; 
     } 
    } 
    throw .... 
} 

を、あなたはロードしたいクラスについて、最も正確な情報があります。その情報を使用してクラスを完全にロードするだけで効率的なクラスローディング戦略です。はい、あなたはより多くのクラス変数またはいくつかのグローバル変数(天国禁止)で終わるかもしれません。しかし、これはあなたのクラスのファイルシステムの一部を怠ったりスキャンしたりするよりも、より良いトレードオフです。

+10

ダイレクトローディングが最も効率的ですが、コードを維持するのが難しくなります。クラスやファイルの名前を変更するとどうなりますか?または、コントローラによって読み込まれる動的なビューセグメントがあり、プロジェクトが進行するにつれて、より多くのビュークラスが作成されることになります。私がビュークラスを作成するたびに、私は戻ってコントローラを使用して手動でそれを含めるように変更する必要はありません。 私はオートロードがダイレクトロードよりも効率的ではないことに同意しますが、私は最も効率的なオートローディングを探しています。 – zombat

+1

私はzombatに同意します。怠惰は良いことかもしれません - 効率的に働くこととしても知られています。パフォーマンスに関しては、ハードウェアは安価です。 – rick

+2

クラスをプロダクションに慣れた後にクラスの名前を変更する必要がある場合は、コードを書く前に十分な時間を費やしていません。効率が重要な場合は、自動ロードのような怠惰な、考えたくないことよりもずっと時間を費やすことで、メンテナンスに要する時間が無限に短縮されます。 – jmucchiello

関連する問題