2013-07-23 7 views
5

私はオートローダークラスのディレクトリマッピング手法を試してきましたが、これは少し苦労しています。私はかなり簡単な解決法(表面上)を考え出すことができましたが、それはまったく動作していないということは完全に謎に包まれていましたが、他の「より明白な」解決策は失敗しました。以下は私の混乱を説明するいくつかのコードスニペットです。ここでphpオートローダー:これはなぜ機能しますか?

は、作業コードです:

<?php 
    spl_autoload_register('my_autoloader'); 

    function my_autoloader($class) { 
     $classMap = array(
      'classes/', 
      'classes/sites/', 
      'classes/data/' 
     ); 
     foreach ($classMap as $location) { 
      if ([email protected]_once($location . $class . '.php')) { // @ SUPPRESSES include_once WARNINGS 
       // CLASS DOESN'T EXIST IN THIS DIRECTORY 
       continue; 
      } else { 
       // CLASS IS AUTO-LOADED 
       break; 
      } 
     } 
    } 
?> 

は、ここで私はべき作業を感じたスニペットですが、しない:これら2しばらくので

<?php 
    spl_autoload_register('my_autoloader'); 

    function my_autoloader($class) { 
     $classMap = array(
      'classes/', 
      'classes/sites/', 
      'classes/data/' 
     ); 
     foreach ($classMap as $location) { 
      if (file_exists($location . $class . '.php')) { 
       require_once ($location . $class . '.php'); 
      } 
     } 
    } 
?> 

後者は私に多くの意味がありますバージョン作業:

<?php 
    spl_autoload_register('my_autoloader'); 

    function my_autoloader($class) { 
     require_once ('classes/sites/' . $class . '.php'); 
    } 
?> 

<?php 
    spl_autoload_register('my_autoloader'); 

    function my_autoloader($class) {     
     $location = 'classes/sites/';     
     require_once ($location . $class . '.php'); 
    } 
?> 

この1つはスローされます"そのようなファイルやディレクトリはありません..."(パスに "sites /"がないことに注意してください。

<?php 
    spl_autoload_register('my_autoloader'); 

    function my_autoloader($class) { 
     require_once ('classes/' . $class . '.php'); 
    } 
?> 

「そのようなファイルやディレクトリ...」というエラーは私が、私は単純にクラスのサポートファイルをチェックすることができると思うし、作られた場合(file_exists()){するrequire_once(); break;} else {continue;}

なぜ機能しないのですか?そして、なぜ最初のスニペットが機能しますか?サポートパス/ファイルは、明示的に含まれたり、必要とされることはありません。

+0

はinclude_pathsのクラスパスの親ディレクトリですか? – Orangepill

+0

サポートファイルは含まれていますが、if文に組み合わされています:if(!@include_once($ location。$ class。 '.php')) –

+0

ええと、私はちょっと考えていましたが、それで、ありがとう。それは私が必要とするものを達成するための非常に控えめな方法のように感じるので、これはソリューションを改善するために私のかゆみを再現するだけです。 Orangepill、私はそれをやる方法がわかりません...私はしばらくの間PHPで作業していませんでした。そして、最後にしたとき、私は今半分プログラミングに熟達していませんでした。基本的に、PHPでJavaとColdFusionのやり方をすでに知っていることをしようとしています。 –

答えて

1

わかりました。私の問題は確かにパスを正しく設定していませんでした。 __DIR__定数を使用して成功への:: ahem ::パスでした。ここで私が今使っている作業コードです:

<?php 
    spl_autoload_register('my_autoloader'); 

    function my_autoloader($class) { 
     $classMap = array(
      'classes/', 
      'classes/sites/', 
      'classes/data/' 
     ); 
     foreach ($classMap as $location) { 
      if (file_exists(__DIR__ . '/' . $location . $class . '.php')) { 
       require_once(__DIR__ . '/' . $location . $class . '.php'); 
       break; 
      } 
     } 
    } 
?> 

それは、それが呼ばれている実際のファイルのディレクトリの場所を返し__DIR__判明は(対照的なに、たとえば、それを含めているファイル)、そのこのファイルがmy/classesディレクトリを持つディレクトリのルートに残っている限り、これが機能することを意味します。そして、それは排他的にこれらの種類の設定を定義するために存在します...

これは、誰かがラインの下に役立つことを願っています!そして、誰もがこのソリューションが最適ではない理由を明らかにすることができたら、私はすべて目を向ける...

EDIT:私が実行する最適化は、$ classMap配列()連想配列(例えば,. $classMap = array('root' => 'classes/', 'sites' => 'classes/sites/');に私は、私は時間をかけて作成したすべてのディレクトリを検索ではなく、ループを行うことができます。しかし、私はそれが別のスレッドのためだと仮定し

EDIT2:。。誰もが興味を持っていた場合は、ここにあります私はこれを連想配列としてやっていましたが、基本的に$ GLOBALSに連想配列を設定し、それを使ってClasses - > Packagesのマップを保存しています。次にインスタンス化されたクラスに必要なファイルを呼び出します。

これは、グローバル設定ファイルです:うまくいけば、これは便利です

<?php 
    // LOAD GLOBAL CONFIG FILE  
    require_once('../config/init.php'); 

    // CREATE LOCAL REFERENCE TO GLOBAL PACKAGE MAP (MOSTLY FOR READABILITY) 
    $packageMap = $GLOBALS['packageMap']; 

    // ADD Class -> Package MAPPINGS 
    $packageMap['DAO'] = 'data'; 
    $packageMap['SomeSite'] = 'sites'; 
    $packageMap['PDOQuery'] = 'data'; 

    // INSTANTIATE SOMETHING IN ONE OF THE PACKAGES 
    $someSite = new SomeSite(); 
?> 

...:

<?php 
    // INITIALIZE GLOBAL Class -> Package map 
    if (!array_key_exists('packageMap',$GLOBALS)) { 
     $GLOBALS['packageMap'] = array(); 
    } 

    spl_autoload_register('my_autoloader'); 

    function my_autoloader($class) { 
     $classMap = array(
      'root'=>'/classes/', 
      'sites'=>'/classes/sites/', 
      'data'=>'/classes/data/' 
     ); 

     // RESOLVE MAPPINGS TO AN ACTUAL LOCATION 
     $classPackage = $GLOBALS['packageMap'][$class]; 
     $location = $classMap[$classPackage]; 
     if (file_exists(__DIR__ . $location . $class . '.php')) { 
      require_once(__DIR__ . $location . $class . '.php'); 
     } 
    } 
?> 

ここでオートローダを使用する特定のサイトの設定ファイルです最終的に、$ GLOBALSの使用をapcに置き換えたいのですが、ホストされているサーバーにインストールされていません:/。私はmemcachedを検討するかもしれませんが、私は混在したレビューを聞いたことがあります...

+0

PHP 5.3以降で['__DIR__'](http://php.net/manual/en/language.constants.predefined.php)を使用することもできます – Raekye

+0

ああ、さらに良い...ありがとう。ソリューションコードが更新されました。 –

関連する問題