Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
460 views
in Technique[技术] by (71.8m points)

php - read files in folder

In my application there is a folder name videos. i want to raed all file only of this folder I have done almostly it does not show any folder in folder videos except .DS_Store currently i have applied if condition to hide this but i want a perfect solution can any one help:- my code is :----

$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);
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The quick and easy solution

You could make your life easier and use a DirectoryIterator to go over the directory.

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>
", htmlentities($file->getBasename()));
    }
}
echo '</select>';

Improvement: Decoupling Directory Filtering from SelectBox building

If you want to decouple the filtering logic from the foreach loop, you can subclass a FilterIterator to capsule that logic into it's accept() method. The DirectoryIterator has to be wrapped into the FilterIterator then. The main point is reusability of course:

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

When you use foreach on a filtered iterator, it will trigger accept() automatically. If accept() returns FALSE, the current element will be filtered out in the iteration.

You create the SelectBox like this then:

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

Alternative to subclassing FilterIterator

If you are too lazy to write a separate FilterIterator or think it's just not worth it for a specific case or already have validators somewhere and dont want to duplicate their code, but still want to decouple Filtering and SelectBox creation, you can also use this custom FilterChainIterator and add callbacks to it:

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

The SelectBox creation would be the same as shown above.


Improvement: Making SelectBox creation reusable

In addition, if you want to make the SelectBox creation reusable, why not create a Helper for it. Below is a very simple one that uses DOM to create the actual HTML. You pass in any Iterator and it will create the HTML for you when you call it's render() method or use it in a string context:

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

And then printing a SelectBox from an Iterator is as simple as

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

That's pretty flexible then, given that there is Iterators for everything. For instance

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

would give a neatly formatted

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...