【问题标题】:How do I replicate a webserver's directory listing functionality?如何复制网络服务器的目录列表功能?
【发布时间】:2011-04-20 22:21:36
【问题描述】:

我经常负责为我所在大学的教授制作专业网站。最近一位教授让我创建一个除了文件链接之外什么都没有的网站。我告诉他这很容易,因为只要网站不包含索引,所有文件链接都会自动显示(是的,我做到了)。令我沮丧的是,大学的服务器并没有按照我的预期去做,虽然我知道可以为相关网站实施此文件列表,但我无权这样做。

我正在制作一个简单的 PHP 脚本,其中列出了文件和目录(以及它们相关的下载链接),但我想知道这样的东西是否已经存在,可能已经全部完善并准备好了。有谁知道这样一个我可以直接到位的应用程序?闪光不是必需的,但我会考虑一个简单的或漂亮的。

哦,是的,它需要在 PHP 或 ColdFusion 中

我的服务器正在运行 ColdFusion 7,0,2,142559 和 PHP 4.3.9

【问题讨论】:

    标签: php html coldfusion indexing


    【解决方案1】:

    我知道您说您无权为教授的目录启用虚拟目录列表,但我的建议是与可以拨打电话的管理员交谈并要求他们启用它。如果他们拒绝,很可能会因为同样的原因(无论发生什么)而拒绝复制该功能。

    无论哪种方式,它都会为您节省时间,因为您可以让 Apache(或任何网络服务器)做它可以轻松完成的事情,或者您不会浪费时间构建您必须删除的东西。

    【讨论】:

    • 通常可以基于每个目录启用或禁用目录列表。
    • @Daniel Vandersluis 我什至都懒得问,因为我 99% 肯定我会被击落,不是因为任何真正的安全问题,而是因为他们不想改变任何东西.我仍然会问,看看会发生什么。如果我被击落,我可能会完成我开始编写的 PHP 脚本,我认为他们不会介意(我在做这项工作)。
    • @typoknig 如果他们不介意你做这项工作,那么从逻辑上讲,他们不应该介意花 5 秒钟来更改 httpd.conf(或任何适用的文件)......然后再说一次,在我们这个行业里有权威的人通常不合逻辑;)
    • @Daniel Vandersluis 不确定,但我讨厌这样(问题也被否决了,没有任何解释)。
    • @Daniel Vandersluis 在等待我在我的网站上启用目录列表的请求数周后被击落。我将继续使用我制作的 PHP 脚本来模拟目录列表功能。
    【解决方案2】:

    您可以将它放在所需文件夹中的 index.php 中。

    function outputRow($relPath, $isDir = false){
            // you could do something special for directories //
            echo '<a href="'.$relPath.'">'.$relPath.'</a>';
    }
    
    $dirPath = dirname(__FILE__);
    $fileList = scandir( $dirPath );
    
    foreach($fileList as $file){
        if($file == '.' || $file == 'index.php')
            continue 1;
    
        outputRow($file, is_dir($dirPath.'/'.$file));
    }
    

    想不出比这更简单的事情了。

    问候, 阿林

    【讨论】:

    • 继续 1;相当于继续;
    • 你可以使用 preg_match('/\.([^\.]+)$/', $relPath, $extension);检测扩展名并为其显示不同的图标并使用 $isDir 显示文件夹的目录图标;如果你喜欢它们,你可以免费使用来自 famfamfam 的图标
    • @Alin Purcaru:或使用pathinfo() 获取信息。或者甚至更好地使用 FileInfo 对象和finfo_file() 来获取 MIME 类型并根据它显示图标。
    • 还有更简单的吗?给你:&lt;? foreach (glob("*") as $file): ?&gt;&lt;li&gt;&lt;a href="&lt;?=$file?&gt;"&gt;&lt;?=$file?&gt;&lt;/a&gt;&lt;? endforeach ?&gt;
    • 简单和简短是有区别的
    【解决方案3】:

    网上有很多例子。就我个人而言,我不会费心寻找库等,因为代码实现起来非常小。试试这个(我搜索过的一个例子,但我过去用过)。

    // open this directory 
    $myDirectory = opendir(".");
    
    // get each entry
    while($entryName = readdir($myDirectory)) {
        $dirArray[] = $entryName;
    }
    
    // close directory
    closedir($myDirectory);
    
    //  count elements in array
    $indexCount = count($dirArray);
    Print ("$indexCount files<br>\n");
    
    // sort 'em
    sort($dirArray);
    
    // print 'em
    print("<TABLE border=1 cellpadding=5 cellspacing=0 class=whitelinks>\n");
    print("<TR><TH>Filename</TH><th>Filetype</th><th>Filesize</th></TR>\n");
    // loop through the array of files and print them all
    for($index=0; $index < $indexCount; $index++) {
            if (substr("$dirArray[$index]", 0, 1) != "."){ // don't list hidden files
            print("<TR><TD><a href=\"$dirArray[$index]\">$dirArray[$index]</a></td>");
            print("<td>");
            print(filetype($dirArray[$index]));
            print("</td>");
            print("<td>");
            print(filesize($dirArray[$index]));
            print("</td>");
            print("</TR>\n");
        }
    }
    print("</TABLE>\n");
    

    【讨论】:

    • 是的。这种肮脏的编码风格有很多例子
    • @Col。弹片为什么这么“脏”?我问是因为我为自己制作的脚本非常相似。但它确实有效。
    • @Col。弹片是的,我知道,我只是问你为什么认为它“脏”,同时还说它确实有效:)
    【解决方案4】:

    你还没有提到你的网络服务器是什么。如果是 Apache,您可以将 .htaccess 文件与 Options +Indexes 放在一起,然后就完成了。

    无论如何,非常快速且非常简单(之前我称之为脏,这不是真的 :) CFML 中的解决方案(假设这是index.cfm 文件):

    <!--- read all files recursively --->
    <cfdirectory action="list" directory="#ExpandPath('.')#" name="qListDirectory" recurse="true" sort="directory ASC, name ASC" type="file" />
    
    <!--- these paths used for building clean related-path links --->
    <cfset baseURL = GetDirectoryFromPath(cgi.SCRIPT_NAME) />
    <cfset basePath = GetDirectoryFromPath(cgi.PATH_TRANSLATED) />
    
    <!--- list all files with directories except special and hidden --->
    <cfoutput>
    <ul>
    <cfloop query="qListDirectory">
        <cfif NOT ListFind("index.cfm,Application.cfm,Application.cfc", qListDirectory.name) AND Left(qListDirectory.name,1) NEQ ".">
            <cfset thisPath = ReplaceNoCase(qListDirectory.directory, basePath, "") />
            <li><a href="#baseURL##thisPath#/#HTMLEditFormat(qListDirectory.name)#">#thisPath#/#HTMLEditFormat(qListDirectory.name)#</a></li>
        </cfif>
    </cfloop>
    </ul>
    </cfoutput>
    

    您可以轻松地将其修改为按目录(嵌套列表)对文件进行分组。

    如果您希望 true 复制网络服务器列表功能 -- 可以使用 Application.cfc 捕获嵌套文件夹中的请求,而无需复制 index.cfm

    请发表评论,我会试试这个。

    【讨论】:

    • .htaccess 中的“选项+索引”只有在 Apache 设置为允许 .htaccess 文件并允许该特定选项时才有效。尽管如此,还是值得一试。
    • 我在我的问题中说我无权自己进行更改,但我们使用的是 Apache。我无权访问htaccess
    • @typoknig 您不必有权访问此文件。你必须创造它。
    • @Col。弹片我的意思是我无权启用/禁用目录列表,也无法使用htaccess,它们的使用已被禁用。
    • @typoknig 抱歉,从您的问题来看,这并不是很明显。无论如何,现在您应该坚持使用 CFML/PHP 解决方案。请更新您的帖子以包含您拥有的网络服务器详细信息和 ColdFusion 版本——这将有助于找到更好的解决方案。
    【解决方案5】:

    <?
    $dirArray = glob("*");
    ?>
    <table border=1 cellpadding=5 cellspacing=0 class=whitelinks>
     <tr>
      <th>Filename</TH><th>Filetype</th><th>Filesize</th>
     </tr>
    <? foreach ($dirArray as $file): ?>
     <tr>
      <td><a href="<?=$file?>"><?=$file?></a></td>
      <td><?=filetype($file)?></td>
      <td><?=filesize($file)?></td>
     </tr>
    <? endforeach ?>
    </table>
    

    【讨论】:

    • 这不起作用(它说第 11 行有错误),但我知道您对模板建议的看法。
    【解决方案6】:

    另一个 ColdFusion 版本,这个列出了大小和修改日期(就像目录索引一样):

    <!--- index.cfm, put into directory --->
    <cffunction name="PrettySize" output="false">
        <cfargument name="size" type="Numeric">
        <cfif arguments.size GT 1048576>
            <cfreturn Fix(arguments.size/104857.6)/10 & ' MB'>
        <cfelseif arguments.size GT 1024>
            <cfreturn Fix(arguments.size/10.24)/100 & ' KB'>
        <cfelse>
            <cfreturn arguments.size & ' bytes'>
        </cfif>
    </cffunction>
    <cfdirectory action="list" directory="#GetDirectoryFromPath(ExpandPath("./"))#" name="Files">
    <table>
        <thead>
            <tr>
            <td>Name</td>
            <td>Last Modified</td>
            <td>Size</td>
            </tr>
        </thead>
        <tbody>
            <cfoutput query="Files"><cfif Files.Name NEQ 'index.cfm'>
            <tr>
            <td><a href="./#Files.Name#">#Files.Name#</a></td>
            <td>#DateFormat(Files.DateLastModified)# #TimeFormat(Files.DateLastModified)#</td>
            <td>#PrettySize(Files.Size)#</td>
            </tr>
            </cfif></cfoutput>
        </tbody>
    </table>
    

    理论上,我认为您可以将此代码放入要添加的任何目录的根目录下的 Application.cfm 文件中。然后,只需确保在您需要索引的每个目录中都有一个空的 index.cfm 文件,并且它应该为您创建它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      • 2012-10-17
      • 2015-08-07
      • 1970-01-01
      相关资源
      最近更新 更多