1

異なる名前空間の親/子クラスで問題が発生しました。これは私の不適切な使用なのか、それとも PHP 名前空間の癖なのか疑問に思っています。

<?php
namespace myVendorName;
class MyParentClass {
  protected $args = array();
  function factory($class) {
    return new $class($this->args);
  }
}
?>

<?php
namespace myVendorName\subPackage;
class foo {
}
class bar extends \myVendorName\MyParentClass {
  function myFunc() {
    var_dump(new foo()); // Works (we're in the same namespace)
    var_dump($this->factory('foo')); // Doesn't work (no such class as myVendorName\foo)
    var_dump($this->factory('subPackage\foo')); // Works
  }
}
?>

上記のコードは、期待どおりに機能しません。メソッドで、クラス\myVendorName\subPackage\bar->myFunc()を取得したいと思います。\myVendorName\subPackage\fooそこだけ作成すれば、名前空間が同じなのでクラス名だけで作成できます。ただし、実際にはこれらのクラスはより複雑であり、それらを作成するファクトリ メソッドがあります。ファクトリ メソッドはユニバーサルであり、ルート ベンダー名前空間で定義されています。また、barクラスはそのファクトリ メソッドを上書きしません。それは単にそれを継承します。ただし、クラス オブジェクトを名前で参照すると、メソッドが実際に子に継承されて子の名前空間で動作するのではなく、親の名前空間で動作しているように見えます。

直接継承される親クラスのメソッドが子の名前空間を使用する方法、または少なくともそれが何であるかを確認する方法はありますか? または、各子クラスはファクトリ メソッドを上書きして名前空間を修正し、その中で親メソッドを呼び出す必要がありますか?

4

1 に答える 1

1

答えは、通行人が示したように、PHP__NAMESPACE__には現在の名前空間で埋められた定数があるということです (ただし、先頭のスラッシュはありません)。したがって、ファクトリ関数を次のように変更します。

function factory($class) {
  if ($class[0] != '\\') {
    $class = '\\'.__NAMESPACE__.$class; // If not a fully-qualified classname, prepend namespace
  }
  return new $class($args);
}

期待どおりに動作します ( PHP ドキュメントにこの例があります)。

于 2012-09-18T19:21:36.720 に答える