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 取得目錄結構。