开发者

How do I replicate a webserver's directory listing functionality?

开发者 https://www.devze.com 2023-01-18 21:19 出处:网络
I am often tasked with making specialty websites for the professors at my university.Recently a professor asked me to create a site with nothing except links to files.I told him that would be easy bec

I am often tasked with making specialty websites for the professors at my university. Recently a professor asked me to create a site with nothing except links to files. I told him that would be easy because as long as the site didn't include an index all the file links would display automagically (yeah I did). To my dismay the university servers do not do what I expected them to do, and although I know it is possible to implement this listing of files for the web site in question, I do not have the authority to do it.

I am in the process of making a simple PHP script that lists files and directories (and their associated download links) but I am wondering if something like this already exists that is perhaps already all polished up and ready to go. Does anyone know of such an application that I can just drop into place? Glitter is not required, but I would consider a simple one or a pretty one.

Oh yeah, it needs to be in PHP or ColdFusion

My server's is running ColdFu开发者_如何学JAVAsion 7,0,2,142559 and PHP 4.3.9


I know you said that you don't have the authority to enable virtual directory listing for the professor's directory, but my advice is to speak with the admin who could make that call and ask them to enable it. If they refuse, chances are replicating that functionality would be denied for the same reason (whatever that happens to be).

It'll save you time either way, because either you can just let Apache (or whatever webserver) do what it's easily able to do, or you don't waste time building something that you will have to take down.


see

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


There are lots of examples on the web. Personally I wouldn't bother finding a library etc, as the code is pretty small to implement. Try this (an example I have searched for, but I have used in the past).

// 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");


You could put this in an index.php in the needed folders.

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

Can't think of anything simpler than this.

Regards, Alin


Another ColdFusion version, this one lists size and date-modified (just like a directory index):

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

In theory, I think you could put this code into an Application.cfm file at the root of whatever directories you want to add. Then, just make sure that there's an empty index.cfm file in each directory where you want an index, and it should create it for you.


You haven't mentioned what is your web-server. In case of Apache you can put the .htaccess file with Options +Indexes and you're done.

Any way, very quick and very simple (previously I called it dirty, this is not true :) solution in CFML (let's say this is index.cfm file):

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

You can easily modify this to group files by directory (nested lists).

If you want true replication of web-server listing feature -- it may be possible to use Application.cfc to catch the requests in the nested folders without copying index.cfm

Please comment and I'll try this.

0

精彩评论

暂无评论...
验证码 换一张
取 消