3

spl_autoload、名前空間、および動的クラス名を試しているときに、「奇妙な」ことに遭遇しました。私はPHP 5.3.2を使用し、このようにオートロードを呼び出します

set_include_path(get_include_path().PATH_SEPARATOR."classes".PATH_SEPARATOR."utils");
spl_autoload_extensions(".class.php");
spl_autoload_register();

今、核心に。次のコードを提案します。

new \User\Student;
$name="\User\Student";
new $name();

これは問題なく動作し、ファイル classes/user/student.class.php が正常にロードされ、両方の構成が成功します。ただし、使用方法が少し異なります。

$name="\User\Student";
new $name();
new \User\Student;

「..Class \User\Student could not be loaded...」で失敗します。何らかの形で静的/動的名前空間の解決に関連する必要があることをお勧めします。ただし、これら2つが処理される時間(コンパイルと実行時)を除いて、これら2つに違いはないと思います。

説明をありがとう。

4

1 に答える 1

4

ここでの「問題」は、実際には SPL よりも低いレベルにあり、__autoload(). これは、コードで最もよく示されています。

function __autoload ($class) {
  echo "Loading $class\n";
}

new Test;
// displays "Loading Test"

$var = 'Test';
new $var;
// displays "Loading Test"

// However, when we introduce namespaces...

new \This\Is\A\Test;
// displays "Loading This\Is\A\Test"

$var = '\This\Is\A\Test';
new $var;
// displays "Loading \This\Is\A\Test"

名前空間を導入するときに、先頭のスラッシュが静的に呼び出されたときに関数に渡されず、動的に呼び出されたときにどのように渡されるかに注意してください。

したがって、解決策は、次のかなり単純なことのいずれかを行うことです。

  • 動的クラス名のインスタンス化から先頭のスラッシュを削除します。
  • spl_autoload()デフォルトの関数を次のようにラップします。
set_include_path(get_include_path().PATH_SEPARATOR."classes".PATH_SEPARATOR."utils");
spl_autoload_extensions(".class.php");
spl_autoload_register(function($class) {
  spl_autoload(ltrim($class, '\\'));
});

もちろん、これを行っている場合は、への呼び出しを削除して、文字列を の 2 番目の引数にspl_autoload_extensions()渡すこともできます。".class.php"spl_autoload()

于 2012-08-14T11:17:39.413 に答える