目录中特定文件的 PHP 列表

Posted

技术标签:

【中文标题】目录中特定文件的 PHP 列表【英文标题】:PHP list of specific files in a directory 【发布时间】:2011-03-04 23:29:53 【问题描述】:

下面的代码会列出一个目录下的所有文件

<?php
if ($handle = opendir('.')) 
    while (false !== ($file = readdir($handle)))
    
        if (($file != ".") 
         && ($file != ".."))
        
            $thelist .= '<LI><a href="'.$file.'">'.$file.'</a>';
        
    

    closedir($handle);

?>

<P>List of files:</p>
<UL>
<P><?=$thelist?></p>
</UL>

虽然这是非常简单的代码,但它可以完成这项工作。

我现在正在寻找一种方法来仅列出末尾具有 .xml(或 .XML)的文件,我该怎么做?

【问题讨论】:

【参考方案1】:

你会想要使用glob()

例子:

$files = glob('/path/to/dir/*.xml');

【讨论】:

我不是 PHP 程序员,我是老 C 程序员。如果我在哪里添加代码? @Jessica 你用那一行完全替换了你的代码。它将返回具有 xml 扩展名的所有文件路径的数组。您可以使用 foreach 对其进行迭代,然后构建您的 html 列表。 +1 很棒的答案。我不知道glob(),从现在开始肯定会经常使用它。谢谢! @Jessica 这个答案似乎比选择的要好。换个怎么样?【参考方案2】:
$it = new RegexIterator(new DirectoryIterator("."), "/\\.xml\$/i"));

foreach ($it as $filename) 
    //...

您还可以使用迭代器的递归变体来遍历整个目录层次结构。

【讨论】:

在 PHP >= 5.3 中,您还可以使用 GlobIterator:de3.php.net/manual/en/class.globiterator.php 来自@Gordon 的链接对我不起作用,但这里的内容与示例相同:GlobIterator::__construct。【参考方案3】:

最简单的答案是设置另一个条件'.xml' == strtolower(substr($file, -3))

但我也建议使用glob

【讨论】:

【参考方案4】:
if ($handle = opendir('.')) 
    while (false !== ($file = readdir($handle)))
    
        if ($file != "." && $file != ".." && strtolower(substr($file, strrpos($file, '.') + 1)) == 'xml')
        
            $thelist .= '<li><a href="'.$file.'">'.$file.'</a></li>';
        
    
    closedir($handle);

使用 substr 和 strrpos 查看扩展的简单方法

【讨论】:

检查 $file. 还是 .. 如果您已经尝试查找某个扩展名,则没有用,因为这已经排除了这两种情况。此外,出于安全原因,您可能希望删除路径中的任何..,以便只能访问子目录,而不能访问兄弟目录或父目录。仅当您的目录不是静态的时才考虑这一点。 这回答了最初的问题,但我认为问题应该是“是否有明确的 PHP 语法可以为你做到这一点?”。答案是肯定的,正如你所看到的最高投票的答案。【参考方案5】:

列出目录中的文件和文件夹(完整代码):p.s.如果您只想要特定的扩展名,则必须取消注释第 5 行

<?PHP
# The current directory
$directory = dir("./");

# If you want to turn on Extension Filter, then uncomment this:
### $allowed_ext = array(".sample", ".png", ".jpg", ".jpeg", ".txt", ".doc", ".xls"); 




## Description of the soft: list_dir_files.php  
## Major credits: phpDIRList 2.0 -(c)2005 Ulrich S. Kapp :: Systemberatung ::

$do_link = TRUE; 
$sort_what = 0; //0- by name; 1 - by size; 2 - by date
$sort_how = 0; //0 - ASCENDING; 1 - DESCENDING


# # #
function dir_list($dir) 
    $i=0; 
    $dl = array(); 
    if ($hd = opendir($dir))     
        while ($sz = readdir($hd))   
            if (preg_match("/^\./",$sz)==0) $dl[] = $sz;$i.=1;  
         
    closedir($hd); 
     
    asort($dl); 
    return $dl; 
 
if ($sort_how == 0)  
    function compare0($x, $y)   
        if ( $x[0] == $y[0] ) return 0;  
        else if ( $x[0] < $y[0] ) return -1;  
        else return 1;  
      
    function compare1($x, $y)   
        if ( $x[1] == $y[1] ) return 0;  
        else if ( $x[1] < $y[1] ) return -1;  
        else return 1;  
      
    function compare2($x, $y)   
        if ( $x[2] == $y[2] ) return 0;  
        else if ( $x[2] < $y[2] ) return -1;  
        else return 1;  
      
else 
    function compare0($x, $y)   
        if ( $x[0] == $y[0] ) return 0;  
        else if ( $x[0] < $y[0] ) return 1;  
        else return -1;  
      
    function compare1($x, $y)   
        if ( $x[1] == $y[1] ) return 0;  
        else if ( $x[1] < $y[1] ) return 1;  
        else return -1;  
      
    function compare2($x, $y)   
        if ( $x[2] == $y[2] ) return 0;  
        else if ( $x[2] < $y[2] ) return 1;  
        else return -1;  
      

 

################################################## 
#    We get the information here 
################################################## 

$i = 0; 
while($file=$directory->read())  
    $file = strtolower($file);
    $ext = strrchr($file, '.');
    if (isset($allowed_ext) && (!in_array($ext,$allowed_ext)))
        
            // dump 
        
    else  
        $temp_info = stat($file); 
        $new_array[$i][0] = $file; 
        $new_array[$i][1] = $temp_info[7]; 
        $new_array[$i][2] = $temp_info[9]; 
        $new_array[$i][3] = date("F d, Y", $new_array[$i][2]); 
        $i = $i + 1; 
         
 
$directory->close(); 

################################################## 
# We sort the information here 
################################################# 

switch ($sort_what)  
    case 0: 
            usort($new_array, "compare0"); 
    break; 
    case 1: 
            usort($new_array, "compare1"); 
    break; 
    case 2: 
            usort($new_array, "compare2"); 
    break; 
 

############################################################### 
#    We display the infomation here 
############################################################### 

$i2 = count($new_array); 
$i = 0; 
echo "<table border=1> 
                <tr> 
                    <td width=150> File name</td> 
                    <td width=100> File Size</td> 
                    <td width=100>Last Modified</td> 
                </tr>"; 
for ($i=0;$i<$i2;$i++)  
    if (!$do_link)  
        $line = "<tr><td align=right>" .  
                        $new_array[$i][0] .  
                        "</td><td align=right>" .  
                        number_format(($new_array[$i][1]/1024)) .  
                        "k"; 
        $line = $line  . "</td><td align=right>" . $new_array[$i][3] . "</td></tr>"; 
    else 
        $line = '<tr><td align=right><A HREF="' .   
                        $new_array[$i][0] . '">' .  
                        $new_array[$i][0] .  
                        "</A></td><td align=right>"; 
        $line = $line . number_format(($new_array[$i][1]/1024)) .  
                        "k"  . "</td><td align=right>" .  
                        $new_array[$i][3] . "</td></tr>"; 
     
    echo $line; 
 
echo "</table>"; 


?>

【讨论】:

这是一个“一刀切”的回复,考虑了所有可能的情况和要求。对于某些事情可以被视为理所当然的常见情况,这有点冗长。【参考方案6】:

你应该使用 glob。

glob('*.xml')

更多关于使用 glob 和高级过滤:

http://domexception.blogspot.fi/2013/08/php-using-functional-programming-for.html

【讨论】:

【参考方案7】:

我使用这个代码:

<?php


//foreach (glob("images/*.jpg") as $large) 
foreach (glob("*.xml") as $filename)  

//echo "$filename\n";
//echo str_replace("","","$filename\n");

echo str_replace("","","<a href='$filename'>$filename</a>\n");





?>

【讨论】:

【参考方案8】:

你可以像这样扩展 RecursiveFilterIterator 类:

class ExtensionFilter extends RecursiveFilterIterator

  /**
  * Hold the extensions pass to the class constructor 
  */
  protected $extensions;

  /**
   * ExtensionFilter constructor.
   *  
   * @param RecursiveIterator $iterator
   * @param string|array $extensions Extension to filter as an array ['php'] or
   * as string with commas in between 'php, exe, ini'
   */
  public function __construct(RecursiveIterator $iterator, $extensions)
  
     parent::__construct($iterator);
     $this->extensions = is_array($extensions) ? $extensions :  array_map('trim', explode(',', $extensions));
  

  public function accept()
  
      if ($this->hasChildren()) 
         return true;
      

      return $this->current()->isFile() &&
         in_array(strtolower($this->current()->getExtension()), $this->extensions);
  

  public function getChildren()
  
     return new self($this->getInnerIterator()->getChildren(), $this->extensions);
  

现在您可以使用路径作为参数实例化 RecursiveDirectoryIterator,如下所示:

 $iterator = new RecursiveDirectoryIterator('\path\to\dir');
 $iterator = new ExtensionFilter($iterator, 'xml, php, ini');

 foreach($iterator as $file)
 
   echo $file . '<br />';
 

这将仅列出当前文件夹下的文件。 要获取子目录中的文件, 将 $iterator ( ExtensionFIlter Iterator) 作为参数传递给 RecursiveIteratorIterator:

$iterator = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);

现在在这个迭代器上运行 foreach 循环。您将获得具有指定扩展名的文件

注意:-- 还要确保在 RecursiveIteratorIterator 之前运行 ExtensionFilter,否则会得到所有文件

【讨论】:

【参考方案9】:

$files 数组将获取指定扩展名目录下的所有文件

$directory = 'pathto/directory';
$files = array();
$allowed_ext = array( "xml", "png", "jpg", "jpeg", "txt", "doc", "xls","csv"); 
// Check if the directory exists or not
if (file_exists($directory) && is_dir($directory)) 
    // Get the files in the directory
    $scan_contents = scandir($directory);
    // Filter out the current (.) and parent (..) directories 
    $files_array = array_diff($scan_contents, array('.', '..'));
    // Get each files of our directory with line break
    foreach ($files_array as $file) 
        //Get the file path
        $file_path = "$directory/$file";
        // Get the file extension
        $file_ext = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));        
        if (in_array($file_ext, $allowed_ext) ) 
            $files[] = $file_path;
        
    
 
echo '<pre>$files:-';
print_r($files);
echo '</pre>';

【讨论】:

【参考方案10】:

你可以混合使用 glob() 函数和 pathinfo() 函数,如下所示。

以下代码将显示特定扩展名“pdf”的文件信息

foreach ( glob("*.pdf") as $file ) 

    $file_info = pathinfo( getcwd().'/'.$file );

    echo $file_info['dirname'], "<br>";
    echo $file_info['basename'], "<br>";
    echo $file_info['extension'], "<br>";
    echo $file_info['filename'], "<br>"; 
    echo '<hr>';

【讨论】:

以上是关于目录中特定文件的 PHP 列表的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中使用 os.walk 获取特定文件或目录列表?

Azure Blob 存储从特定目录而不是容器获取文件列表

php函数将目录中的文件名列表拉入php数组

拒绝访问特定目录中的特定文件类型

PHP - 访问 Web 根目录之外的文件的安全性

PHP 获取目录中的文件列表