2010-08-25 12 views
3

В моем приложении есть видеоролики с именами папок. Я хочу, чтобы raed весь файл только из этой папки, которую я сделал почти, он не показывает какую-либо папку в папке видео, кроме .DS_Store В настоящее время я применил, если условие, чтобы скрыть это, но я хочу идеальное решение, может ли кто-нибудь помочь: - мой код является: ----читать файлы в папке

$dir = "../videos/"; 
$dh = opendir($dir); 

print '<select size="4" name="vidfile">'; 

while (($file = readdir($dh)) !== false) { 

    if (is_file($dir.'/'.$file) && $file != "." && $file != "..") { 

     if ($file!=".DS_Store") { 

      print "<option>{$file}</option>"; 
     } 
    }   
} 

print '</select>'; 

closedir($dh); 

ответ

2
<?php 
$dir = '../videos/'; 
if($dh = opendir($dir)){ 
    echo '<select size="4" name="vidfile">'; 
    while(($file=readdir($dh)) !== FALSE){ 
     $file = $dir . '/' . $file; 
     if(!is_file($file) || substr($file, 0, 1) == '.'){ 
     continue; 
     } 
     printf('<option>%s</option>', htmlentities($file)); 
    } 
    echo '</select>'; 
    closedir($dh); 
} 
?> 

Во-первых, если opendir терпит неудачу, не продолжайте с мусором. Он игнорирует нефайлы (каталоги) и файлы, начинающиеся с точки (включая., .., .htaccess и т. Д.)

1

Вот вариант, который работает с glob() вместо этого, имеет массив исключенных файлов и собирает все элементы option, а затем выводит их как один. Кроме того, glob() позволяет фильтровать определенные расширения файлов через синтаксис привязки, как показано в строке с комментариями.

$dir = "../videos"; 
$mask = "*"; 
// $mask = "*.{wmv,mpeg,mpg}"; // get only files of these types 

$files = glob($dir."/".$mask); 
$excluded_files = array(".DS_store"); 
$html = null;  

if (count($files) > 0) 
foreach ($files as $file) 
{ 
    $filename = basename($file); 
    if (in_array($filename, $excluded_files)) continue; 
    $html.="<option>".htmlentities($filename)."</option>"; 
} 

echo $html; 
0

Просто if ($file[0] == ".") continue; вместо этих 2-х, если вероятно, что вы ищете.
Хотя я бы сделал это несколько иначе, в 2 частях.
получать данные часть:

<?php 
    $dir = "../videos/"; 
    $dh = opendir($dir); 
    $filesarr = array(); 
    while (($file = readdir($dh)) !== false) { 
    if ($file[0] != ".") $filesarr[] = $file; 
    } 
    closedir($dh); 
?> 

и отображения данных часть:

<select size="4" name="vidfile"> 
<?php foreach ($filesarr as $file): ?> 
<option><?php echo $file ?></option> 
<?php endforeach ?> 
</select> 

кажется путь более чистым мне

13

быстрого и простого решения

Вы могли бы сделать ваша жизнь проще и используйте DirectoryIterator, чтобы перейти через каталог.

echo '<select name="vids" size="4">'; 
foreach(new DirectoryIterator('/path/to/videos') as $file) { 
    if($file->isFile() === TRUE && $file->getBasename() !== '.DS_Store') { 
     printf("<option>%s</option>\n", htmlentities($file->getBasename())); 
    } 
} 
echo '</select>'; 

Улучшение: Развязка Каталог Filtering от переключателе здания

Если вы хотите, чтобы отделить логику фильтрации из цикла foreach, вы можете создать подкласс FilterIterator в капсуле, что логика в это accept() метод , Затем DirectoryIterator должен быть завернут в FilterIterator. Основной момент является повторным использованием, конечно:

class MyFilter extends FilterIterator 
{ 
    public function accept() 
    { 
     return $this->current()->isFile() === TRUE && 
       $this->current()->getBasename() !== '.DS_Store'; 
    } 
} 

$iterator = new MyFilter(new DirectoryIterator('/path/to/videos')); 

При использовании foreach на фильтрованный итераторе, это вызовет accept() автоматически. Если accept() возвращает FALSE, текущий элемент будет отфильтрован на итерации.

Вы создаете переключатель, как это тогда:

echo '<select name="vids" size="4">'; 
foreach($iterator as $file) { 
    printf("<option>%s</option>\n", htmlentities($file->getBasename())); 
} 
echo '</select>'; 

Альтернатива подклассы FilterIterator

Если вы слишком ленивы, чтобы написать отдельную FilterIterator или думают, что это просто не стоит для в конкретном случае или уже есть валидаторы где-то и не хотят дублировать их код, но все же хотят отделить фильтрацию и создание SelectBox, вы также можете использовать этот пользовательский FilterChainIterator и добавить к нему обратные вызовы:

$iterator = new FilterChainIterator(new DirectoryIterator('/path/to/videos')); 
$iterator->addCallback(function($file) { 
    return $file->isFile() === TRUE && 
      $file->getBasename() !== '.DS_Store';}); 

Создание SelectBox будет таким же, как показано выше.


Улучшение: Создание создания переключателя многоразового

Кроме того, если вы хотите сделать многоразовое создание переключателя, почему бы не создать помощник для него. Ниже приведено очень простое, которое использует DOM для создания фактического HTML. Вы проходите в любом итераторе, и он будет создавать HTML для вас, когда вы называете это render() метод или использовать его в контексте строки:

class SelectBox 
{ 
    protected $iterator; 
    public function __construct(Iterator $iterator) 
    { 
     $this->iterator = $iterator; 
    } 
    public function render() 
    { 
     $dom = new DOMDocument; 
     $dom->formatOutput = TRUE; 
     $dom->loadXml('<select name="vids"/>'); 
     $dom->documentElement->appendChild(new DOMElement('option', 'Pick One')); 
     foreach($this->iterator as $option) { 
      $dom->documentElement->appendChild(
       new DOMElement('option', $option)); 
     } 
     return $dom->saveXml($dom->documentElement); 
    } 
    public function __toString() 
    { 
     return $this->render(); 
    } 
} 

А потом печать переключателя из итератора так просто, как

echo new SelectBox(new MyFilter(new DirectoryIterator('/path/to/videos'))); 

Это довольно гибкий, тогда, учитывая, что есть Итераторы для всего. Например

echo new SelectBox(new ArrayIterator(array('foo', 'bar', 'baz'))); 

даст аккуратно отформатированный

<select> 
    <option>Pick One</option> 
    <option>foo</option> 
    <option>bar</option> 
    <option>baz</option> 
</select> 
+0

Почему идентичная (===) оператор в '$ файл-> ISFILE() === TRUE,? Я бы предположил, что просто '$ file-> isFile()' будет работать одинаково. –

+0

+1 для DirectoryIterator –

Смежные вопросы