PHP FTP 递归目录列表
P粉621033928
2023-08-25 00:36:20
<p>我正在尝试创建一个递归函数来从数组中的 ftp 服务器获取所有目录和子目录。</p>
<p>我尝试了很多在网上找到的功能。最适合我的是这个:</p>
<pre class="brush:php;toolbar:false;">public function getAllSubDirFiles() {
$dir = array(".");
$a = count($dir);
$i = 0;
$depth = 20;
$b = 0;
while (($a != $b) && ($i < $depth)) {
$i++;
$a = count($dir);
foreach ($dir as $d) {
$ftp_dir = $d . "/";
$newdir = ftp_nlist($this->connectionId, $ftp_dir);
foreach ($newdir as $key => $x) {
if ((strpos($x, ".")) || (strpos($x, ".") === 0)) {
unset($newdir[$key]);
} elseif (!in_array($x, $dir)) {
$dir[] = $x;
}
}
}
$b = count($dir);
}
return $dir ;
}</pre>
<p>这个函数的问题是它不允许目录有“.”。在它的名称中,位于根目录中的每个文件也将被视为一个目录。所以我调整了函数并得到了这个:</p>
<pre class="brush:php;toolbar:false;">public function getAllSubDirFiles($ip, $id, $pw) {
$dir = array(".");
$a = count($dir);
$i = 0;
$depth = 20;
$b =0;
while (($a != $b) && ($i < $depth)) {
$i++;
$a = count($dir);
foreach ($dir as $d) {
$ftp_dir = $d . "/";
$newdir = ftp_nlist($this->connectionId, $ftp_dir);
foreach ($newdir as $key => $x) {
if (!is_dir('ftp://'.$id.':'.$pw.'@'.$ip.'/'.$x)) {
unset($newdir[$key]);
} elseif (!in_array($x, $dir)) {
$dir[] = $x;
}
}
}
$b = count($dir);
}
return $dir ;
}</pre>
<p>这工作得很好,但给出了我想要的结果。但它太慢了,无法使用。 </p>
<p>我也尝试过使用<code>ftp_rawlist</code>,但它也有同样的缺点,那就是速度非常慢。</p>
<pre class="brush:php;toolbar:false;">public function getAllSubDirFiles() {
$dir = array(".");
$a = count($dir);
$i = 0;
$depth = 20;
$b = 0;
while (($a != $b) && ($i < $depth)) {
$i++;
$a = count($dir);
foreach ($dir as $d) {
$ftp_dir = $d . "/";
$newdir = $this->getFtp_rawlist('/' . $ftp_dir);
foreach ($newdir as $key => $x) {
$firstChar = substr($newdir[$key][0], 0, 1);
$a = 8;
while ($a < count($newdir[$key])) {
if ($a == 8) {
$fileName = $ftp_dir . '/' . $newdir[$key][$a];
} else {
$fileName = $fileName . ' ' . $newdir[$key][$a];
}
$a++;
}
if ($firstChar != 'd') {
unset($newdir[$key]);
} elseif (!in_array($fileName, $dir)) {
$dir[] = $fileName;
}
}
}
$b = count($dir);
}
return $dir;
}
public function getFtp_rawlist($dir) {
$newArr = array();
$arr = ftp_rawlist($this->connectionId, $dir);
foreach ($arr as $value) {
$stringArr = explode(" ", $value);
$newArr[] = array_values(array_filter($stringArr));
}
return $newArr;
}</pre>
<p>过去几天我一直被这个问题困扰,我越来越绝望了。如果有人有任何建议请告诉我</p>
我构建了一个 OOP FTP 客户端库,可以帮助您解决此问题很多,仅使用此代码,您可以检索仅包含附加有用信息的目录列表,例如(chmod、上次修改时间、大小...)。
代码:
如果您的服务器支持
MLSD
命令并且您有 PHP 7.2 或更高版本,则可以使用ftp_mlsd
函数:如果您没有 PHP 7.2,您可以尝试自行实现
MLSD
命令。首先,请参阅ftp_rawlist
命令的用户注释:https://www.php.net/manual/en/ function.ftp-rawlist.php#101071
如果您无法使用
MLSD
,那么您在判断条目是文件还是文件夹时尤其会遇到问题。虽然您可以使用ftp_size
技巧,但调用 每个条目的ftp_size
可能需要很长时间。但是,如果您只需要针对一个特定的 FTP 服务器进行工作,则可以使用
ftp_rawlist
以特定于平台的格式检索文件列表并对其进行解析。以下代码假定采用常见的 *nix 格式。
对于 DOS 格式,请参阅:使用 PHP 从 FTP 获取目录结构。