モダンPHP - 名前空間に関する注意点

昨日行われたモダンPHPの懇親会で id:Fivestar さんにもお話したのですが、

__autoload に渡ってくる名前は完全修飾されたクラス名となり、基本的には 先頭にバッスラがつかない、グローバルからの名前空間+クラス名 が渡されます。

<?php
namespace {
  function __autoload($class) {
    var_dump($class);
  }

  new \Hoge\Fuga(); // $class = 'Hoge\Fuga'
  new \Hoge\Fuga(); // $class = 'Hoge\Fuga'
}

namespace Hoge {
  new Fuga();       // $class = 'Hoge\Fuga'
  new \Hoge\Fuga(); // $class = 'Hoge\Fuga'
}

※実際には動かないので注意。 new するクラスが無いのでこけます。


ところが、文字列を利用したクラス生成や、 class_exists / interface_exists を呼んだ場合、
先頭にバッスラがつくことがあります

<?php
namespace {
  function __autoload($class) {
    var_dump($class);
  }

  class_exists('Hoge\Fuga');   // $class = 'Hoge\Fuga'
  class_exists('\Hoge\Fuga');  // $class = '\Hoge\Fuga'

  $cls = 'Hoge\Fuga';  
  new $cls();                // $class = 'Hoge\Fuga'

  $cls = '\Hoge\Fuga';
  new $cls();                // $class = '\Hoge\Fuga'
}

※実際には動かないので注意。 new するクラスが無いのでこけます。



挙動を見る限り、文字列でクラスが指定されるケースにおいては、指定されたクラス名が、そのままオートローディングメソッドに渡されているようです。

とはいえ、これ、マニュアルにも書かれていないので、この事実に依存するコードは書かない方が賢明かもしれません。


http://gist.github.com/221634 のオートローダも、これに対応した記述が無いのですよ。。。

#modernphp