PHPのお勉強!

PHP TOP

ftp_nlist

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

ftp_nlist指定したディレクトリのファイルの一覧を返す

説明

ftp_nlist(FTP\Connection $ftp, string $directory): array|false

パラメータ

ftp

FTP\Connection クラスのインスタンス

directory

一覧を表示するディレクトリ。このパラメータには引数を含めることができます。 例: ftp_nlist($ftp, "-la /your/dir"); このパラメータはエスケープ処理されません。スペースやその他の文字を含む ファイル名では問題が発生する可能性があることに注意してください。

戻り値

成功した場合は指定したディレクトリ内のファイル名の配列を、 エラー時には false を返します。

変更履歴

バージョン 説明
8.1.0 引数 ftp は、FTP\Connection のインスタンスを期待するようになりました。 これより前のバージョンでは、リソース を期待していました。

例1 ftp_nlist() の例

<?php

// 接続を確立する
$ftp = ftp_connect($ftp_server);

// ユーザー名とパスワードでログインする
$login_result = ftp_login($ftp, $ftp_user_name, $ftp_user_pass);

// カレントディレクトリの内容を得る
$contents = ftp_nlist($ftp, ".");

// $contents を出力する
var_dump($contents);

?>

上の例の出力は、 たとえば以下のようになります。

array(3) {
  [0]=>
  string(11) "public_html"
  [1]=>
  string(10) "public_ftp"
  [2]=>
  string(3) "www"

参考

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

add a note

User Contributed Notes 37 notes

up
73
Anonymous
14 years ago
Some complain that ftp_nlist, always return FALSE. I did experience this behavior myself, until I used ftp_pasv, which is useful if your client is behind a firewall (which most clients are now), then ftp_nlist worked just fine. I don't really know what are all the implications of using ftp_pasv, but if you read or experience that ftp_nlist, ftp_get, ftp_nb_get doesn't work, try adding the following:

ftp_pasv($conn_id,true);
up
11
tobrien at florahill dot vic dot edu dot au
21 years ago
ftp_nlist() or ftp_rawlist() takes ages then returns nothing...

If you are having this issue, you may need to enable PASV mode FTP transfers using the ftp_pasv() function.

Example...

<?php
$ftp_host
= "yourFTPHost";
$ftp_user = "yourUsername";
$ftp_password = "yourPassword";

//Connect
echo "<br />Connecting to $ftp_host via FTP...";
$conn = ftp_connect($ftp_host);
$login = ftp_login($conn, $ftp_user, $ftp_password);

//
//Enable PASV ( Note: must be done after ftp_login() )
//
$mode = ftp_pasv($conn, TRUE);

//Login OK ?
if ((!$conn) || (!$login) || (!$mode)) {
die(
"FTP connection has failed !");
}
echo
"<br />Login Ok.<br />";

//
//Now run ftp_nlist()
//
$file_list = ftp_nlist($conn, "");
foreach (
$file_list as $file)
{
echo
"<br>$file";
}

//close
ftp_close($conn);

?>
up
3
gerben at gerbs dot net
6 years ago
Be aware that since PHP 7.2 a new function is available, that returns the list of files as an array with all details ready to use: http://php.net/manual/en/function.ftp-mlsd.php
up
7
zgardner at allofe dot com
14 years ago
While running WAMP (Vista, Apache 2.21, MySQL 5.1.36, PHP 5.3) and recursively downloading files from a LAMP FTP server (Ubuntu 8.04, Apache 2.2.8, MySQL 5.1.51a, PHP 5.2.4, VSFPTD), I would find that my script stops downloading files after a while. I traced it to the call to ftp_nlist halting the script.

To solve this, I did a ftp_pasv($ftp, true). There's nothing in the VSFTPD, Apache, or PHP error logs on either the client or the server. Very strange.
up
6
Jacob Slomp
12 years ago
Hi,

I wrote this function to get the file list, I tested it only with php5 with linux ftp. And works fine for me.

it will return an array with the name, type (file/folder), owner, owner_id and rights.

<?php
function ftp_get_filelist($con, $path){
$files = array();
$contents = ftp_rawlist ($con, $path);
$a = 0;

if(
count($contents)){
foreach(
$contents as $line){

preg_match("#([drwx\-]+)([\s]+)([0-9]+)([\s]+)([0-9]+)([\s]+)([a-zA-Z0-9\.]+)([\s]+)([0-9]+)([\s]+)([a-zA-Z]+)([\s ]+)([0-9]+)([\s]+)([0-9]+):([0-9]+)([\s]+)([a-zA-Z0-9\.\-\_ ]+)#si", $line, $out);

if(
$out[3] != 1 && ($out[18] == "." || $out[18] == "..")){
// do nothing
} else {
$a++;
$files[$a]['rights'] = $out[1];
$files[$a]['type'] = $out[3] == 1 ? "file":"folder";
$files[$a]['owner_id'] = $out[5];
$files[$a]['owner'] = $out[7];
$files[$a]['date_modified'] = $out[11]." ".$out[13] . " ".$out[13].":".$out[16]."";
$files[$a]['name'] = $out[18];
}
}
}
return
$files;
}
?>

Greets,

Jacob
up
1
turigeza on yahoo com
19 years ago
Recursive directory delete using ftp_nlist() ...
<?php
function ftp_rmdirr($path, $handle)
{
if (!(@
ftp_rmdir($handle, $path) || @ftp_delete($handle, $path)))
{
$list = ftp_nlist($handle, $path);
if (!empty(
$list))
foreach(
$list as $value)
ftp_rmdirr($value, $handle);
}
@
ftp_rmdir($handle, $path);
}
?>
It would be very useful if it was built into php. After all most of the time we want to remove non empty directories too. I bet everyone out there dealing with the file system had faced this problem.
up
1
aRc
21 years ago
in windows, ftp_nlist will die on a directory with a space in it's name. to get around this, use ftp_chdir:

//change directory
ftp_chdir($conn, "directory with spaces");
//then blindly list
$contents = ftp_nlist($conn, "");
up
1
fsa at dwarf dot dk
8 years ago
So I wrote a simple function using ftp_nlist() to recursively list only files in a specified directory.

/**
* Returns a list of files in the given directory, excluding directories.
*
* @param resource $ftp_stream
* The link identifier of the FTP connection.
* @param string $directory
* The directory to be listed.
* Note that this parameter isn't escaped so there may be some issues with filenames containing spaces and other characters.
* @param bool $recursive
* (optional) If set to TRUE, the issued command will be done recursively.
*
* @return array
* Returns an array of filenames from the specified directory.
*/
function ftp_files_list($ftp_stream, $directory, $recursive = false) {
$files = array();

$list = ftp_nlist($ftp_stream, $directory);
if (is_array($list)) {
// Strip away dot directories.
$list = array_slice($list, 2);

foreach ($list as $filename) {
$path = $directory . '/' . $filename;
// If size equals -1 it's a directory.
if (ftp_size($ftp_stream, $path) === -1) {
if ($recursive) {
$files = array_merge($files, ftp_files_list($ftp_stream, $path, $recursive));
}
} else {
// Strip away root directory path to ensure all file paths are relative.
$files[] = substr($path, strpos($path, '/') + 1);
}
}
}

return $files;
}
up
1
bintjes at gmail dot com
17 years ago
I've made a recursive function to list all files from folders and subfolders using ftp_rawlist() . I used the function below from ari, parse_rawlist()

function list_all_files($conn_id, $path){
$buff = ftp_rawlist($conn_id, $path);
$res = parse_rawlist( $buff) ;
static $flist = array();
if(count($res)>0){
foreach($res as $result){
// verify if is dir , if not add to the list of files
if($result['size']== 0){
// recursively call the function if this file is a folder
list_all_files($conn_id, $path.'/'.$result['name']);
}
else{
// this is a file, add to final list
$flist[] = $result;
}
}
}
return $flist;
}
up
1
franck569 at free dot fr
18 years ago
better version of turigeza on yahoo com ftp_rmdirr() function.

This return true or false if the path will be removed :

function ftp_rmdirr($handle, $path)
{
if(!@ftp_delete($handle, $path))
{
$list = @ftp_nlist($handle, $path);
if(!empty($list))
foreach($list as $value)
ftp_rmdirr($handle, $value);
}

if(@ftp_rmdir($handle, $path))
return true;
else
return false;
}
up
1
vijay dot mahrra at fronter dot com
13 years ago
We needed to get a list of all files in all subdirectories and couldn't see a method to do this so we wrote our own:

<?php
/**
* ftpRecursiveFileListing
*
* Get a recursive listing of all files in all subfolders given an ftp handle and path
*
* @param resource $ftpConnection the ftp connection handle
* @param string $path the folder/directory path
* @return array $allFiles the list of files in the format: directory => $filename
* @author Niklas Berglund
* @author Vijay Mahrra
*/
function ftpRecursiveFileListing($ftpConnection, $path) {
static
$allFiles = array();
$contents = ftp_nlist($ftpConnection, $path);

foreach(
$contents as $currentFile) {
// assuming its a folder if there's no dot in the name
if (strpos($currentFile, '.') === false) {
ftpRecursiveFileListing($ftpConnection, $currentFile);
}
$allFiles[$path][] = substr($currentFile, strlen($path) + 1);
}
return
$allFiles;
}
?>
up
1
juhakala at gmail dot com
16 years ago
I noticed that this function won't work if working path is different, because $dir keeps value of whole path string. That's why adding basename()-function strips the path and this function will work also sub folders, not only in root folder.

function ftp_is_dir($dir) {
global $ftp_connect;
if (ftp_chdir($ftp_connect, basename($dir))) {
ftp_chdir($ftp_connect, '..');
return true;
} else {
return false;
}
}
up
1
nekrostar at gmx dot net
18 years ago
This function returns an array with the directory path and all files and subdirs which are in this

function ftp_searchdir($conn_id, $dir)
{
if( !@ftp_is_dir( $conn_id, $dir ) ) {
die( 'No such directory on the ftp-server' );
}
if( strrchr( $dir, '/' ) != '/' ) {
$dir = $dir.'/';
}
$dirlist[0] = $dir;
$list = ftp_nlist( $conn_id, $dir );
foreach( $list as $path ) {
$path = './'.$path;
if( $path != $dir.'.' && $path != $dir.'..') {
if( ftp_is_dir( $conn_id, $path ) ) {
$temp = ftp_searchdir( $conn_id, ($path), 1 );
$dirlist = array_merge( $dirlist, $temp );
} else {
$dirlist[] = $path;
}
}

}
ftp_chdir( $conn_id, '/../' );

return $dirlist;

}
----------------------------------------------------------------------
//Looks if a directory ($dir) is isset
//returns true or false

function ftp_is_dir( $conn_id, $dir )
{
if( @ftp_chdir( $conn_id, $dir ) ) {
ftp_chdir( $conn_id, '/../' );
return true;
} else {
return false;
}
}
up
1
dreamsavior at gmail dot com
19 years ago
Here is the function that would checking whether the given path is directory or not, using ftp_nlist;

<?php
function is_ftp_dir($itempath, $ftp_server, $ftp_user_name='anonymous', $ftp_user_pass='') {
if (empty(
$ftp_user_name)) {
$ftp_user_name = "anonymous";
}
if (
$itempath[0]!=="/") {
$itempath = "/".$itempath;
}

$conn_id = ftp_connect($ftp_server);
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);

$contents = ftp_nlist($conn_id, "$itempath");

if (!empty(
$contents[0])) {
$check = str_replace($itempath, "", $contents[0]);
if (!empty(
$check)) {
return
true;
}
}
ftp_close($conn_id);
}

// example :
if (is_ftp_dir("/pub/ftp/unknownitem", "ftp.nowhere", 'username', 'verysecret'')) {
// do something related to directory handling action
} else {
// The target item is a file ...
}

?>
up
3
mail at martinauer dot net
18 years ago
Beware:
The array will contain complete paths, not just filenames. At least in PHP 4.3.11 when I tried

ftp_nlist("www.example.com/docs/some/thing")

it dumped something like this:

[0]=>
string(41) "www.example.com/docs/some/thing/file1.htm"
[1]=>
string(41) "www.example.com/docs/some/thing/file2.htm"
[2]=>
string(41) "www.example.com/docs/some/thing/file3.htm"
[3]=>
string(41) "www.example.com/docs/some/thing/file4.htm"
[4]=>
string(41) "www.example.com/docs/some/thing/file5.htm"
up
0
rmaslo at archa dot cz
2 years ago
Some FTP servers convert accented characters to character "?". You can try:

<?php
$ftp
= ftp_connect($ftp_server);
$login_result = ftp_login($ftp, $ftp_user_name, $ftp_user_pass);
ftp_raw($ftp, 'OPTS UTF8 ON'); //Sets the server to return results in UTF
$contents = ftp_nlist($ftp, ".");
var_dump($contents);
?>
up
2
artiom1st at yahoo dot com
18 years ago
Sometimes, you won't be able to get folder content because of NAT or Firewall issues on your server. As a result you need to put ftp connection into a passive mode:

<?php

// set up basic connection
$conn_id = ftp_connect($ftp_server);

// login with username and password
$login_result = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);

// enabling passive mode
ftp_pasv( $conn_id, true );

// get contents of the current directory
$contents = ftp_nlist($conn_id, ".");

// output $contents
var_dump($contents);

?>
up
1
wim dot dupre at skynet dot be
17 years ago
php 5.2.2 on MAC OS 1.4 (Tiger) seems to defaut to active ftp. to get ftp_nlist functioning, i needed to force ftp to passive.
the default behaviour with PHP 5.2.3 on windows XP seems to be passive ftp.

greetz,

wim