Правильный способ установки пользовательского класса FileInfo для Итератора - PullRequest
6 голосов
/ 04 апреля 2010

Я пытаюсь установить пользовательский класс для Итератора с помощью метода setInfoClass:

Используйте этот метод для установки пользовательского класса, который будет использоваться при вызове getFileInfo и getPathInfo. Имя класса, переданное этому методу, должно быть получено из SplFileInfo.

Мой класс такой (упрощенный пример):

class MyFileInfo extends SplFileInfo
{
    public $props = array(
        'foo' => '1',
        'bar' => '2'
    );
}

Код итератора такой:

$rit = new RecursiveIteratorIterator(
           new RecursiveDirectoryIterator('/some/file/path/'),
           RecursiveIteratorIterator::SELF_FIRST);

Поскольку RecursiveDirectoryIterator наследуется через DirectoryIterator, а также объект SplFileInfo, он обеспечивает метод setInfoClass. Его нет в руководстве, но его отражение показывает, что оно есть:

shell$ php --rc RecursiveDirectoryIterator
// ...
Method [ <internal:SPL, inherits SplFileInfo> public method setInfoClass ] {  
  - Parameters [1] {
    Parameter #0 [ <optional> $class_name ]
  }
}

Все хорошо до сих пор, но при переборе по каталогу с

$rit->getInnerIterator()->setInfoClass('MyFileInfo');
foreach($rit as $file) {
    var_dump( $file );
}

Я получаю следующий странный результат

object(MyFileInfo)#4 (3) {
  ["props"]=>UNKNOWN:0
  ["pathName":"SplFileInfo":private]=>string(49) "/some/file/path/someFile.txt"
  ["fileName":"SplFileInfo":private]=>string(25) "someFile.txt"
}

Так что, пока MyFileInfo выбрано, я не могу получить доступ к его свойствам. Если я добавлю пользовательские методы, я могу их нормально вызывать, но любые свойства НЕИЗВЕСТНЫ.

Если я не установлю информационный класс для итератора, а для объекта SplFileInfo (как показано в примере в руководстве), он даст тот же НЕИЗВЕСТНЫЙ результат:

foreach($rit as $file) {
    // $file is a SplFileInfo instance
    $file->setInfoClass('MyFileInfo');
    var_dump( $file->getFileInfo() );
}

Тем не менее, это будет работать, когда я

foreach($rit as $file) {
    $file = new MyFileInfo($file);
    var_dump( $file );
}

К сожалению, код, в котором я хочу использовать это, несколько сложнее и включает в себя еще несколько итераторов. Создание класса MyFileInfo, как это, не вариант.

Итак, кто-нибудь знает, как это работает или почему PHP ведет себя так странно?

Спасибо.

1 Ответ

2 голосов
/ 04 апреля 2010

Не могу точно сказать, почему, но он работает с

class MyFileInfo extends SplFileInfo
{
  public $props;

  public function __construct($filename) {
    $this->props = array(
      'foo' => '1',
      'bar' => '2'
    );

    parent::__construct($filename);
  }
}
...