在我的应用程序中有一个文件夹名称视频。我想raed只有这个文件夹的所有文件我几乎没有在文件夹视频中显示任何文件夹,除了.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);
答案 0 :(得分: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>';
改进:从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
或认为它对某个特定情况不值得,或者已经有某个地方的验证器并且不想复制它们的代码,但仍想要解耦Filtering和SelectBox创建,您也可以使用此自定义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();
}
}
然后从迭代器打印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>
答案 1 :(得分: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等)
答案 2 :(得分: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;
答案 3 :(得分:0)
只是if ($file[0] == ".") continue;
而不是这两个如果可能是您正在寻找的
虽然我略有不同,分为两部分
获取数据部分:
<?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>
对我来说似乎更干净