Skip to Content

一个列目录的php程序

labrador 的头像
做目录列表的PHP程序网上太多了,我写的这个也是基于别人的一个程序,外观基本上和原来的一模一样,不过里面的程序基本已经给我改得面目全非了。

这个列目录程序最大的特点是结合apache的.htaccess实现了虚拟目录的功能。这里有一个样例。直观上看,这是主机cnbits.co.cc下的ftp目录的列表,实际上,那个主机ftp目录下只有这个列表程序,真实的目录是_ftp_,可以在这里访问。

这样做的动机是为开放的ftp提供安全性。假设我把_ftp_目录作为一个公共ftp供大家随意上传,如果有人上传了一个恶意的php程序,因为这个主机也同时提供了从web界面访问_ftp_目录的功能,那么恶意程序就通过web界面被执行,整个主机也就陷于危险之中。使用.htaccess限制php的执行也不能解决问题,因为虚拟主机上,子目录的.htaccess可以覆盖上级目录的.htaccess的设置,导致安全性措施失效。

如果用我做的这个目录列表程序,用户可以方便的浏览下载目录中的内容,但却不会知道这个目录的实际地址。当用户访问其中的php文件时,首先会被ftp目录下的.htaccess所过滤。因为这个目录是不公开的,用户也就不可能通过上传.htaccess来覆盖安全性设置。比如,虽然是同一个文件,当在目录ftp中访问的test.php时,它不会被执行,而是作为一个文件下载,当在通过test.php所在的真实目录_ftp_访问时,这个php文件就在主机上被执行了。

将这个程序安装到网站上,需要php和apache中rewrite engine的相关知识。首先配置index.php,其中最重要的是
$basedir = '../_ftp_';
$basedir是_ftp_所要列表的真实在主机操作系统上所在的目录,绝对路径或者相对路径都可以。

apache配置起来稍微有点复杂,需要小心,这里解释一下程序包里带的.htaccess的意义和配置方法
#打开rewrite engine。
RewriteEngine on

#指定虚拟的目录,本程序就放置在这个目录里。
RewriteBase /ftp

#访问index.php和__resource就不用跳转了。
RewriteRule ^index.php$ - [L]
RewriteRule ^__resource/.+$ - [L]

#如果访问的是个目录,但没有以/结尾,则跳转到正确的地址上。这里/www/cnbits.co.cc/_ftp_/是
#真实目录在文件系统内的位置(不是在web上位置)。
RewriteCond /www/cnbits.co.cc/_ftp_/$1 -d
RewriteRule ^(.*[^/])$ $1/ [L,R]

#如果访问的是个目录,则用index.php生成目录列表。这里判断目录的方法和上面一样,RewriteCond
#语句必须和上面配置的一样。
RewriteCond /www/cnbits.co.cc/_ftp_/$1 -d
RewriteRule ^(.*)$ index.php?dir=$1 [L,QSA]

#如果是php文件则用index.php代理下载,而不允许直接访问。这里可以根据需要限制其他类型的文件。
RewriteRule ^(.*/)?(.+\.php[0-9]?)$ index.php?dir=$1&down=$2 [L,NC,QSA]

#如果是sh或者py文件则用index.php显示其内容,而不允许直接访问。这里可以根据需要限制其他类型的文件。
RewriteRule ^(.*/)?(.+\.(sh|py))$ index.php?dir=$1&view=$2 [L,NC,QSA]

#如果不是目录,也不是禁止直接访问的文件,则转到真实目录上去,这里/_ftp_/是真实目录在web上的
#位置,一般情况下它就是前面那个文件系统内位置的最后一段。
RewriteRule ^(.*)$ /_ftp_/$1 [L,QSA]

这个程序运行在常见的共享虚拟主机上,可以提供一个比较安全的公共文件服务功能。但如果用的是VPS或者独立主机,那就完全没有必要用这个方法来创建虚拟目录,用httpd.conf配置一下就行了。

更新日志

2009年1月1日,加入了geshi,提供程序语法高亮功能,排序时增加箭头表明是递增还是递减
2008年12月18日,第一版
附件大小
dirlisting.tar.gz394.7 KB

发表新评论

  • 你可以在文本中使用BBCode标记语言。 URL会自动被转为链接。

更多关於格式化选项的信息

CAPTCHA
请验证您是否是机器人。
Image CAPTCHA
Enter the characters shown in the image.