
Сейчас очень много работаю с SPL классами в PHP. Честно говоря, работать с ними не всегда удобно. Сегодня наткнулся на проблему с указателями в DirectoryIterator. Ее суть хорошо отражает следующий код.
$dirTree = new DirectoryIterator("/testDir"); // Допустим в директории файлы a.php и b.php
$items = array();
foreach($dirTree as $item) {
if ($item->isDir()) {
$items[] = $item;
echo $item->getFilename(); // Здесь все ок - сначало выводится a.php, затем b.php
}
}
$firstElement = $items[0];
var_dump($firstElement->getFilename()); // вот здесь выводится пустая строка, а я ожидал что будет ‘a.php’
Проблема состоит в том, что при выполнении foreach у нас в элементе $item находится указатель на указатель (вот такой вот каламбур) текущего элемента в DirectoryIterator. Получить этот указатель можно с помощью функции $dirTree->current(). Таким образом, при изменении этого самого внутреннего указателя изменяется и результат выполнения команды getFilename. А так как после выполнения Foreach указатель смотрит на несуществующий (null) элемент итератора, то getFilename возвращает пустое значение.
Пока я ничего лучше не придумал, чем копировать $item с помощью метода clone:
$dirTree = new DirectoryIterator("/testDir"); // Допустим в директории файлы a.php и b.php
$items = array();
foreach($dirTree as $item) {
if ($item->isDir()) {
$items[] = clone $item;
echo $item->getFilename(); // Здесь все ок - сначало выводится a.php, затем b.php
}
}
$firstElement = $items[0];
var_dump($firstElement->getFilename()); // теперь тоже все ок и на экран выводитя - ‘a.php’
Решение ужасное, поэтому если кто-то подскажет действительно красивый способ выдернуть из DirectoryIterator набор директорий в виде массива директорий, то буду очень признателен.
Комментарии (0)
RSS свернуть / развернутьТолько зарегистрированные и авторизованные пользователи могут оставлять комментарии.