【问题标题】:read files in folder读取文件夹中的文件
【发布时间】:2010-08-25 07:52:22
【问题描述】:

在我的应用程序中有一个文件夹名称视频。我只想读取这个文件夹的所有文件,我几乎完成了它在文件夹视频中不显示任何文件夹,除了 .DS_Store 目前我已经应用了 if 条件来隐藏它,但我想要一个完美的解决方案,任何人都可以帮助:- 我的代码是:----

$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);

【问题讨论】:

    标签: php file


    【解决方案1】:

    快速简便的解决方案

    您可以让您的生活更轻松,并使用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>';
    

    改进:从 SelectBox 构建中解耦目录过滤

    如果您想将过滤逻辑与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,则当前元素将在迭代中被过滤掉。

    然后像这样创建 SelectBox:

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

    子类化 FilterIterator 的替代方法

    如果你懒得写一个单独的FilterIterator 或者认为它对于特定情况不值得,或者已经在某个地方有验证器并且不想复制他们的代码,但仍然想解耦过滤和选择框的创建,你也可以使用这个自定义的FilterChainIterator 并为其添加回调:

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

    SelectBox 的创建与上图相同。


    改进:使 SelectBox 创建可重用

    另外,如果你想让 SelectBox 创建可重用,为什么不为它创建一个 Helper。下面是一个非常简单的,它使用 DOM 创建实际的 HTML。您传入任何迭代器,当您调用它的 render() 方法或在字符串上下文中使用它时,它将为您创建 HTML:

    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();
        }
    }
    

    然后从 Iterator 打印 SelectBox 就像

    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>
    

    【讨论】:

    • 为什么$file-&gt;isFile() === TRUE 中的运算符相同(===)?我想只有$file-&gt;isFile() 也可以工作。
    【解决方案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 等)

    【讨论】:

      【解决方案3】:

      这是一个与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;
      

      【讨论】:

        【解决方案4】:

        只是 if ($file[0] == ".") continue; 而不是这 2 个 if 可能是您正在寻找的。
        虽然我会稍微不同,但分为两部分。
        获取数据部分:

        <?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>
        

        对我来说似乎更干净

        【讨论】:

          猜你喜欢
          • 2013-04-15
          • 1970-01-01
          • 2011-08-27
          • 2011-10-24
          • 2013-05-30
          • 1970-01-01
          • 2011-07-04
          • 1970-01-01
          • 2011-10-11
          相关资源
          最近更新 更多