PHPのお勉強!

PHP TOP

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 となります。

戻り値

各要素が 1 行分のテキストに対応する配列を返します。 渡された directory が無効な場合は false を返します。

出力に関する処理は全く行われません。結果の解釈の仕方を定義するために ftp_systype() から返されるシステム型 ID を使用することができます。

変更履歴

バージョン 説明
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"
}

参考

  • ftp_nlist() - 指定したディレクトリのファイルの一覧を返す
  • ftp_mlsd() - ディレクトリに存在するファイルの一覧を返す

add a note

User Contributed Notes 24 notes

up
41
fredvanetten at tinqle dot com
12 years ago
Here's a simple function that'll parse the data returned by ftp_rawlist() into an associative array. I wrote it because some of the functions listed below are way to long, complex or won't work with file names that contain spaces.

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

// Throw exception or return false < up to you
}
?>
up
4
weltvolk
16 years ago
With this handy function based on functions presented here you get the file list in alphabetical order with all directories on top:

<?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();
?>
up
7
mediaboat at gmail dot com
10 years ago
All parse_rawlist Functions here have one Problem.

when a file starts with a space character like " robots.txt ", it will be ignored.

Rename, delete will fail...
up
2
shaun at shaunfreeman dot co dot uk
14 years ago
Get a listing of all files including hidden files except '.' or '..' use:

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

This had me dancing in circles for some time!
up
2
Johnny Doe
14 years ago
In case anybody wants to get a detailed listing using the MLSD command over a passive connection, the following function might be helpful as a starting point for your own implementation:

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

Please note that this function ignores the setting of ftp_pasv(). Making the function to work universally for both active and passive connections is left as an exercise to the reader ;-)
up
0
Roline88 at hotmail dot com
6 years ago
Note that this function also will return false if the content of the provided directory is empty.
up
2
paul maybe at squirrel mail org
16 years ago
Regarding converting permissions from symbolic notation to octal, note that Hazem dot Khaled at gmail dot com's chmodnum function produces INCORRECT results. The resutls are base-10 numbers that only LOOK like they are octal numbers. The function also ignores setuid, setgid and sticky bits, and will produce incorrect numbers if such a file is encountered. Instead, this brute-force code works. Maybe there is something more slick, but this isn't too CPU-intensive (note that it assumes you've error-checked that you indeed have a 10-character string!):

$permissions = 'drwxr-xr-x'; // or whatever
$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);
up
2
admin at mikeholloway dot co dot uk
19 years ago
I was having problems picking up the directories on a mac using cjacobsen at pge dot cl's (11-Jan-05) solution. Slight ammendment to the regexp works for me:

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)
up
0
John
14 years ago
There are a couple of php-related reasons given here for ftp_rawlist returning an empty result. However be aware that ZoneAlarm (and possibly other) firewalls can block responses without giving any visible clue so be sure to check that first.
up
0
nospam at advancedonsite dot com
15 years ago
ftp_rawlist kept returning empty file listing, it would work on some machines but not others, it turned out to be ftp_pasv command was needed.
Very frustrating
up
1
marc dot peterlongo at francetelecom dot com
19 years ago
When you try:

$path = "directory pathname with spaces";
$list = ftp_rawlist($conn_id,$path);

It doesn't work

but when you try:

$path = "directory pathname with spaces";
ftp_chdir($conn_id,$path);
$list = ftp_rawlist($conn_id,".");

It works
up
0
ahmadmarafa at gmail dot com
15 years ago
this is function to check for dirs

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

}
else
{
return
false;
}
}
?>
up
0
tmp at gmx dot de
15 years ago
To format the _recrusive_ result of this function I use this:

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

// here the magic begins!
$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
// the 'children' attribut is automatically added if the folder contains at least one file
);
}
}

// in $structure is all the data
print_r($structure);

// little helper functions
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]));
}

?>
up
1
Anonymous
20 years ago
Note that there is no standard for the format, therefore don't be suprised when parsing routines for this work perfectly on some servers, and fail horribly on some.
up
0
francois frao_o
15 years ago
Why not using POSIX regex to do the job here ? A preg_replace returns the information in an associative array with the following keys:

<rights>
<number>
<owner>
<group>
<file_size>
<mod_time>
<file>
<type> * that's a bonus: it will tell you if the item is either a file or a directory

Code is shown below:

$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
up
0
www.bosssftp.com
16 years ago
Some FTP servers only allow you to get list of files under current working directory. So if you always get result as empty array (array(0){ }), try changing the cwd befor get the list:

<?php
function ftprawlist($connid, $dir) {
ftp_chdir($connid, $dir);
return
ftp_rawlist($connid, "-a");
}
?>
up
0
ari at bs-inc dot com
18 years ago
This is a little cleaner:

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;

}