ftp_rawlist

(PHP 4, PHP 5, PHP 7, PHP 8)

ftp_rawlist返回给定目录中文件的详细列表

说明

ftp_rawlist(FTP\Connection $ftp, string $directory, bool $recursive = false): array|false

ftp_rawlist() 执行 FTP LIST 命令,并将结果作为数组返回。

参数

ftp

一个 FTP\Connection 实例。

directory

目录路径。可以包含 LIST 命令的参数。

recursive

如果设置为 true,发出的命令将为 LIST -R

返回值

返回一个数组,其中每个元素对应一行文本。当传递的 directory 无效时,返回 false

输出不会以任何方式解析。由 ftp_systype() 返回的系统类型标识符可用于确定应如何解释结果。

变更日志

版本 说明
8.1.0 ftp 参数现在期望一个 FTP\Connection 实例;以前,期望的是一个 资源

范例

示例 #1 ftp_rawlist() 示例

<?php

// 设置基本连接
$ftp = ftp_connect($ftp_server);

// 使用用户名和密码登录
$login_result = ftp_login($ftp, $ftp_user_name, $ftp_user_pass);

// 获取 / 的文件列表
$buff = ftp_rawlist($ftp, '/');

// 关闭连接
ftp_close($ftp);

// 输出缓冲区
var_dump($buff);
?>

以上示例将输出类似于

array(3) {
  [0]=>
  string(65) "drwxr-x---   3 vincent  vincent      4096 Jul 12 12:16 public_ftp"
  [1]=>
  string(66) "drwxr-x---  15 vincent  vincent      4096 Nov  3 21:31 public_html"
  [2]=>
  string(73) "lrwxrwxrwx   1 vincent  vincent        11 Jul 12 12:16 www -> public_html"
}

参见

添加备注

用户贡献的备注 24 备注

41
fredvanetten at tinqle dot com
11 年前
这里有一个简单的函数,它将通过 ftp_rawlist() 返回的数据解析为一个关联数组。我编写它是因为下面列出的一些函数过于冗长、复杂,或者不能处理包含空格的文件名。

<?php
function listDetailed($resource, $directory = '.') {
if (
is_array($children = @ftp_rawlist($resource, $directory))) {
$items = array();

foreach (
$children as $child) {
$chunks = preg_split("/\s+/", $child);
list(
$item['rights'], $item['number'], $item['user'], $item['group'], $item['size'], $item['month'], $item['day'], $item['time']) = $chunks;
$item['type'] = $chunks[0]{0} === 'd' ? 'directory' : 'file';
array_splice($chunks, 0, 8);
$items[implode(" ", $chunks)] = $item;
}

return
$items;
}

// 抛出异常或返回 false < 由您决定
}
?>
4
weltvolk
16 年前
使用这里介绍的函数,您可以获得按字母顺序排列的文件列表,并将所有目录放在最上面。

<?php
function rawlist_dump() {
global
$ftp_connect;
$ftp_rawlist = ftp_rawlist($ftp_connect, ".");
foreach (
$ftp_rawlist as $v) {
$info = array();
$vinfo = preg_split("/[\s]+/", $v, 9);
if (
$vinfo[0] !== "total") {
$info['chmod'] = $vinfo[0];
$info['num'] = $vinfo[1];
$info['owner'] = $vinfo[2];
$info['group'] = $vinfo[3];
$info['size'] = $vinfo[4];
$info['month'] = $vinfo[5];
$info['day'] = $vinfo[6];
$info['time'] = $vinfo[7];
$info['name'] = $vinfo[8];
$rawlist[$info['name']] = $info;
}
}
$dir = array();
$file = array();
foreach (
$rawlist as $k => $v) {
if (
$v['chmod']{0} == "d") {
$dir[$k] = $v;
} elseif (
$v['chmod']{0} == "-") {
$file[$k] = $v;
}
}
foreach (
$dir as $dirname => $dirinfo) {
echo
"[ $dirname ] " . $dirinfo['chmod'] . " | " . $dirinfo['owner'] . " | " . $dirinfo['group'] . " | " . $dirinfo['month'] . " " . $dirinfo['day'] . " " . $dirinfo['time'] . "<br>";
}
foreach (
$file as $filename => $fileinfo) {
echo
"$filename " . $fileinfo['chmod'] . " | " . $fileinfo['owner'] . " | " . $fileinfo['group'] . " | " . $fileinfo['size'] . " Byte | " . $fileinfo['month'] . " " . $fileinfo['day'] . " " . $fileinfo['time'] . "<br>";
}
}
rawlist_dump();
?>
7
mediaboat at gmail dot com
10 年前
这里所有的 parse_rawlist 函数都存在一个问题。

当文件以空格字符开头,例如 " robots.txt ",它将被忽略。

重命名、删除将失败……
2
shaun at shaunfreeman dot co dot uk
14 年前
获取所有文件列表,包括隐藏文件,除了 “.” 或 “..” 使用

<?php
ftp_chdir($connid, $dir);
ftp_rawlist($connid, "-A");
?>

这让我绕了好一阵子!
2
Johnny Doe
13 年前
如果有人想使用 MLSD 命令通过被动连接获取详细列表,以下函数可能作为您自己的实现的起点。

<?php
function ftp_mlsd($ftp, $directory) {
$ok = @ftp_chdir($ftp, $directory);
if (!
$ok) {
return
false;
}
$ret = ftp_raw($ftp, 'PASV');
if (
preg_match(
'/^227.*\(([0-9]+,[0-9]+,[0-9]+,[0-9]+),([0-9]+),([0-9]+)\)$/',
$ret[0], $matches)) {
$controlIP = str_replace(',', '.', $matches[1]);
$controlPort = intval($matches[2])*256+intval($matches[3]);
$socket = fsockopen($controlIP, $controlPort);
ftp_raw($ftp, 'MLSD');
$s = '';
while (!
feof($socket)) {
$s .= fread($socket, 4096);
}
fclose($socket);
$files = array();
foreach (
explode("\n", $s) as $line) {
if (!
$line) {
continue;
}
$file = array();
foreach (
explode(';', $line) as $property) {
list(
$key, $value) = explode('=', $property);
if (
$value) {
$file[$key] = $value;
} else {
$filename = trim($key);
}
}
$files[$filename] = $file;
}
return
$files;
}
return
false;
}
?>

请注意,此函数忽略了 ftp_pasv() 的设置。让该函数对主动和被动连接普遍适用留给读者作为练习 ;-)
0
Roline88 at hotmail dot com
6 年前
请注意,如果提供的目录内容为空,此函数也将返回 false。
2
paul maybe at squirrel mail org
16 年前
关于将权限从符号表示转换为八进制,请注意 Hazem dot Khaled at gmail dot com 的 chmodnum 函数会产生不正确的结果。结果是基数为 10 的数字,它们看起来像八进制数字。该函数还忽略了 setuid、setgid 和粘性位,如果遇到这样的文件,会产生不正确的数字。相反,这段暴力代码有效。可能还有更巧妙的方法,但这并不太占用 CPU 资源(注意,它假设您已经对 10 个字符的字符串进行了错误检查!)。

$permissions = 'drwxr-xr-x'; // 或者其他
$mode = 0;

if ($permissions[1] == 'r') $mode += 0400;
if ($permissions[2] == 'w') $mode += 0200;
if ($permissions[3] == 'x') $mode += 0100;
else if ($permissions[3] == 's') $mode += 04100;
else if ($permissions[3] == 'S') $mode += 04000;

if ($permissions[4] == 'r') $mode += 040;
if ($permissions[5] == 'w') $mode += 020;
if ($permissions[6] == 'x') $mode += 010;
else if ($permissions[6] == 's') $mode += 02010;
else if ($permissions[6] == 'S') $mode += 02000;

if ($permissions[7] == 'r') $mode += 04;
if ($permissions[8] == 'w') $mode += 02;
if ($permissions[9] == 'x') $mode += 01;
else if ($permissions[9] == 't') $mode += 01001;
else if ($permissions[9] == 'T') $mode += 01000;

printf('Mode is %d decimal and %o octal', $mode, $mode);
2
admin at mikeholloway dot co dot uk
18 年前
我使用 cjacobsen at pge dot cl 的 (11-Jan-05) 解决方案在 mac 上获取目录时遇到问题。对正则表达式进行了一些细微的修改,对我来说有效。

ereg("([-dl][rwxstST-]+).* ?([0-9 ]* )?([a-zA-Z0-9]+).* ([a-zA-Z0-9]+).* ([0-9]*) ([a-zA-Z]+[0-9: ]*[0-9])[ ]+(([0-9]{2}:[0-9]{2})|[0-9]{4}) (.+)", $file, $regs)
0
John
14 年前
这里给出了几个与 php 相关的理由,说明 ftp_rawlist 返回空结果。但是要注意,ZoneAlarm(以及可能的其他)防火墙可以阻止响应,而不会给出任何可见的线索,因此请务必首先检查。
0
nospam at advancedonsite dot com
14 年前
ftp_rawlist 始终返回空文件列表,它在某些机器上可以工作,而在其他机器上则不能,事实证明需要使用 ftp_pasv 命令。
非常令人沮丧
1
marc dot peterlongo at francetelecom dot com
19 年前
当您尝试

$path = "包含空格的目录路径名";
$list = ftp_rawlist($conn_id,$path);

它不起作用

但是当您尝试

$path = "包含空格的目录路径名";
ftp_chdir($conn_id,$path);
$list = ftp_rawlist($conn_id,".");

它起作用了
0
ahmadmarafa at gmail dot com
15 年前
这是用于检查目录的函数

<?php
function ftp_isdir($connect_id,$dir)
{
if(
ftp_chdir($connect_id,$dir))
{
ftp_cdup($connect_id);
return
true;

}
else
{
return
false;
}
}
?>
0
tmp at gmx dot de
15 年前
为了格式化此函数的_递归_结果,我使用以下方法

<?php
$conn_id
= ftp_connect(FTP_SERVER);

$login_result = ftp_login($conn_id, FTP_USR, FTP_PASS);

$rawfiles = ftp_rawlist($conn_id, '/', true);

ftp_close($conn_id);

// 这里开始变魔法!
$structure = array();
$arraypointer = &$structure;
foreach (
$rawfiles as $rawfile) {
if (
$rawfile[0] == '/') {
$paths = array_slice(explode('/', str_replace(':', '', $rawfile)), 1);
$arraypointer = &$structure;
foreach (
$paths as $path) {
foreach (
$arraypointer as $i => $file) {
if (
$file['text'] == $path) {
$arraypointer = &$arraypointer[ $i ]['children'];
break;
}
}
}
} elseif(!empty(
$rawfile)) {
$info = preg_split("/[\s]+/", $rawfile, 9);
$arraypointer[] = array(
'text' => $info[8],
'isDir' => $info[0]{0} == 'd',
'size' => byteconvert($info[4]),
'chmod' => chmodnum($info[0]),
'date' => strtotime($info[6] . ' ' . $info[5] . ' ' . $info[7]),
'raw' => $info
// 'children' 属性会在文件夹至少包含一个文件时自动添加
);
}
}

// $structure 中包含所有数据
print_r($structure);

// 一些辅助函数
function byteconvert($bytes) {
$symbol = array('B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
$exp = floor( log($bytes) / log(1024) );
return
sprintf( '%.2f ' . $symbol[ $exp ], ($bytes / pow(1024, floor($exp))) );
}

function
chmodnum($chmod) {
$trans = array('-' => '0', 'r' => '4', 'w' => '2', 'x' => '1');
$chmod = substr(strtr($chmod, $trans), 1);
$array = str_split($chmod, 3);
return
array_sum(str_split($array[0])) . array_sum(str_split($array[1])) . array_sum(str_split($array[2]));
}

?>
1
Anonymous
19 年前
请注意,没有针对格式的标准,因此当解析例程在这方面完美地适用于某些服务器,而在某些服务器上却惨败时,不要感到惊讶。
0
francois frao_o
15 年前
为什么不在这里使用 POSIX 正则表达式来完成工作呢?preg_replace 以关联数组的形式返回信息,该数组包含以下键

<rights>
<number>
<owner>
<group>
<file_size>
<mod_time>
<file>
<type> * 这是一个额外的功能:它会告诉您该项目是文件还是目录

代码如下所示

$list=@ftp_rawlist($con,$directory) ;

$items=array() ;

foreach($list as $_)
preg_replace(

'`^(.{10}+)(\s*)(\d{1})(\s*)(\d*|\w*)'.
'(\s*)(\d*|\w*)(\s*)(\d*)\s'.
'([a-zA-Z]{3}+)(\s*)([0-9]{1,2}+)'.
'(\s*)([0-9]{2}+):([0-9]{2}+)(\s*)(.*)$`Ue',

'$items[]=array(
"rights"=>"$1",
"number"=>"$3",
"owner"=>"$5", "group"=>"$7",
"file_size"=>"$9",
"mod_time"=>"$10 $12 $14:$15",
"file"=>"$17",
"type"=>print_r((preg_match("/^d/","$1"))?"dir":"file",1));',

$_) ; # :p
0
www.bosssftp.com
15 年前
某些 FTP 服务器只允许您获取当前工作目录下的文件列表。因此,如果您始终获得空数组作为结果(array(0){ }),请尝试在获取列表之前更改 cwd

<?php
function ftprawlist($connid, $dir) {
ftp_chdir($connid, $dir);
return
ftp_rawlist($connid, "-a");
}
?>
0
ari at bs-inc dot com
17 年前
这更简洁一些

function parse_rawlist( $array )
{
foreach($array as $curraw)
{
$struc = array();
$current = preg_split("/[\s]+/",$curraw,9);

$struc['perms'] = $current[0];
$struc['number'] = $current[1];
$struc['owner'] = $current[2];
$struc['group'] = $current[3];
$struc['size'] = $current[4];
$struc['month'] = $current[5];
$struc['day'] = $current[6];
$struc['time'] = $current[7];
$struc['year'] = $current[8];
$struc['raw'] = $curraw;
$structure[$struc['name']] = $struc;
}
return $structure;

}
-2
nickman at freemail dot hu
10 年前
fredvanetten 在 tinqle dot com 的解决方案很好,但需要进一步评估,因为 preg_split 和静态变量列表会导致不同的值:比较今天或更早的年份的文件。

数组
(
[时间] => 2012
[天] => 11
[月] => Sep
[大小] => 37262
[组] => group
[用户] => owner
[号码] => 1
[权限] => -rw-rw-rw-
)

数组
(
[时间] => 14:01
[天] => 23
[月] => Apr
[大小] => 37262
[组] => group
[用户] => owner
[号码] => 1
[权限] => -rw-rw-rw-
)
0
nate at 8networks dot com
19 年前
这段代码修复了列表中的日期问题,并整理了变量

$filedata['access_permissions']
$filedata['link_count']
$filedata['uid']
$filedata['gid']
$filedata['size']
$filedata['mod_date_month']
$filedata['mod_date_day']
$filedata['mod_time']
$filedata['name']

list($filedata['access_permissions'], $filedata['link_count'], $filedata['uid'], $filedata['gid'], $filedata['size'], $filedata['mod_date_month'], $filedata['mod_date_day'], $filedata['mod_time'], $filedata['name']) = preg_split("/[\s,]+/", $value);

$filedata['type'] = $filedata['access_permissions']{0};

$filedata['access_permissions'] = substr($filedata['access_permissions'],1);

// 现在检查日期以查看最后修改是在今年还是去年。

if ( strrpos($filedata['mod_time'], ':') != 2 ) { $filedata['mod_date'] = $filedata['mod_date_month'] ." " . $filedata['mod_date_day'] . " " . $filedata['mod_time']; $filedata['mod_time'] = "00:00"; } else { $filedata['mod_date'] = $filedata['mod_date_month'] ." " . $filedata['mod_date_day'] . " " . date("Y"); }
0
cjacobsen at pge dot cl
19 年前
表达式很棒,但当 'x' 被禁用时,不会匹配 SUID、SGUI 和粘滞位标志。使用 [rwxstST-] 修复它。

<?php

function itemize_dir($contents) {
foreach (
$contents as $file) {
if(
ereg("([-dl][rwxstST-]+).* ([0-9]*) ([a-zA-Z0-9]+).* ([a-zA-Z0-9]+).* ([0-9]*) ([a-zA-Z]+[0-9: ]*[0-9])[ ]+(([0-9]{2}:[0-9]{2})|[0-9]{4}) (.+)", $file, $regs)) {
$type = (int) strpos("-dl", $regs[1]{0});
$tmp_array['line'] = $regs[0];
$tmp_array['type'] = $type;
$tmp_array['rights'] = $regs[1];
$tmp_array['number'] = $regs[2];
$tmp_array['user'] = $regs[3];
$tmp_array['group'] = $regs[4];
$tmp_array['size'] = $regs[5];
$tmp_array['date'] = date("m-d",strtotime($regs[6]));
$tmp_array['time'] = $regs[7];
$tmp_array['name'] = $regs[9];
}
$dir_list[] = $tmp_array;
}
return
$dir_list;
}
$buff = ftp_rawlist($cid, "/");
$items = itemize_dir($buff);

?>
0
greg at upsdn dot net
19 年前
列出所有内容(包括隐藏文件和目录)
<?php
$contents
= ftp_rawlist($conn_id, "-al ".$dir_name);
?>

就像 ftp 命令一样
LIST al

"-aF " 等于 '-al',请参考 "ls --help"
0
greg at upsdn dot net
19 年前
之前的正则表达式(由 Jonathan Almarez、ergye at yahoo dot com 和 guru at virusas dot lt)非常好,但我发现它没有考虑目录(数字>9)。

将 [0-9] 更改为 [0-9]*

下面的代码不仅解析
drwxrwxr-x 9 msik ia 4096 Nov 5 14:19 Group3

它还解析
drwxrwxr-x 19 msik ia 4096 Nov 5 14:19 Group3
3
drwxrwxr-x 119 msik ia 4096 Nov 5 14:19 Group3
3

0 = 文件
1 = 目录
2 = 符号链接
<?php

function itemize_dir($contents) {
foreach (
$contents as $file) {
if(
ereg("([-dl][rwxst-]+).* ([0-9]*) ([a-zA-Z0-9]+).* ([a-zA-Z0-9]+).* ([0-9]*) ([a-zA-Z]+[0-9: ]*[0-9])[ ]+(([0-9]{2}:[0-9]{2})|[0-9]{4}) (.+)", $file, $regs)) {
$type = (int) strpos("-dl", $regs[1]{0});
$tmp_array['line'] = $regs[0];
$tmp_array['type'] = $type;
$tmp_array['rights'] = $regs[1];
$tmp_array['number'] = $regs[2];
$tmp_array['user'] = $regs[3];
$tmp_array['group'] = $regs[4];
$tmp_array['size'] = $regs[5];
$tmp_array['date'] = date("m-d",strtotime($regs[6]));
$tmp_array['time'] = $regs[7];
$tmp_array['name'] = $regs[9];
}
$dir_list[] = $tmp_array;
}
return
$dir_list;
}
$buff = ftp_rawlist($cid, "/");
$items = itemize_dir($buff);

?>
0
Anonymous
20 年前
如果你写
<?php
rawlist
($ftp, "-a");
?>
该命令将是 "LIST -a",因此返回的列表也将包含隐藏文件,如 ".htaccess"。

在这种情况下,将包含当前目录中的所有文件和文件夹。
要列出另一个文件夹,你必须使用 "ftp_chdir" 切换到它。
-1
eros at speedy dot com dot ar
19 年前
不,不,不。

上面的例子都是错的,数组中给出的空格并非“仅仅因为”存在,而只是一个制表符结构。在 PHP 中,我们没有像 C/C++ 中那样的结构,但以下函数可以完成工作。

<?php

函数 parse_rawlist( $array ) {

对于 (
$i = 1; $i < count($array); $i++ ) {

$current = $array[$i];

$structure[$i]['perms'] = substr($current, 0, 10);
$structure[$i]['number'] = trim(substr($current, 11, 3));
$structure[$i]['owner'] = trim(substr($current, 15, 8));
$structure[$i]['group'] = trim(substr($current, 24, 8));
$structure[$i]['size'] = trim(substr($current, 33, 8));
$structure[$i]['month'] = trim(substr($current, 42, 3));
$structure[$i]['day'] = trim(substr($current, 46, 2));
$structure[$i]['time'] = substr($current, 49, 5);
$structure[$i]['name'] = substr($current, 55, strlen($current) - 55);

}

返回
$structure;

}

?>
To Top