简体   繁体   中英

How to check using PHP FTP functionality if folder exists on server or not?

有没有办法使用 PHP Ftp 功能检查服务器上是否存在 aa 文件夹?

For PHP 5:

$folder_exists = is_dir('ftp://user:password@example.com/some/dir/path');

http://php.net/manual/en/function.is-dir.php : "As of PHP 5.0.0, this function can also be used with some URL wrappers."

http://php.net/manual/en/wrappers.ftp.php : [Support] "As of PHP 5.0.0: filesize(), filetype(), file_exists(), is_file(), and is_dir()"

Try this:

if (ftp_nlist($ftp_stream, $new_folder) == false) {
    ftp_mkdir($ftp_stream, $new_folder);
}

There is no 'exists' function for ftp connections in php.

You could try ftp_chdir and check the result

stumbled upon this question from 2009 and found that question unsatisfying for me. I've done little research of my own a found a little tweak for that issue.

So if found the *ftp_nlist* function witch returns an array of string with files and folders names witch exist under the current ftp directory, and then I've simply checked under the array (with foreacah loop) if the folder or file we searched for exist there and an new ifExist method as been created.

you can read more at php.net: http://php.net/manual/en/function.ftp-nlist.php

another option for the YII framework users its the ftp extension that masks the php ftp lib and makes it even easier to work with an ftp server from code.

Hope you'l find helpful.

The solution that works for me:

if (!in_array($dirName.'/'.$something, $ftp->nlist($dirName))) {  
   // do something
}             

Me also not satisfied with any anwser incl. accepted one. I have standard connection (not OO-style like in @Lackeeee's answer which is closest to mine):

$ftp = ftp_connect($host, 21, 30);
ftp_login($ftp, $user, $password);

// if $my_dir name exists in array returned by nlist in current '.' dir
if (in_array($my_dir, ftp_nlist($ftp, '.'))) {
    // do smth with $my_dir
}

ftp_close($ftp);

ftp_mdtm() gets the last modified time for a remote file. It returns the last modified time as a Unix timestamp on success, or -1 on error. Note that ftp_mdtm() does not work with directories. So if we get -1 then maybe the file is directory.

Note also that not all servers support this feature!

for checking multiple files it is better to use ftp_chdir instead using the is_dir / file_exists function with URL wrappers, cause there are pretty slow (foreach file there must be opened a new ftp connection ...).

foreach ($list as $item) {
    $is_dir = @ftp_chdir($ftp_handle, $item); //produces warning if file...
    if ($is_dir) {
        ftp_chdir($ftp_handle, '..');
        $dirs[] = $item;
    } else {
        $files[] = $item;
    }
}

This script was ready after ~10 sec.

The same script using is_dir and file_exists needed more than 45 sec. (each file had 10 runs)

On modern FTP-servers you can use MLST/MLSD command to retrieve detailed machine-readable information about files. Read RFC page https://tools.ietf.org/html/rfc3659#page-23 to learn more about this command.

Here is sample code to determine filesystem node type:

function isDir($ftp, $fsNodePath) {
    $type = strtolower(fsNodeType($ftp, $fsNodePath));
    return ($type === 'cdir' || $type === 'pdir' || $type === 'dir');

}

function isFile($ftp, $fsNodePath) {
    $type = strtolower(fsNodeType($ftp, $fsNodePath));
    return ($type === 'file');
}

function isLink($ftp, $fsNodePath) {
    $type = strtolower(fsNodeType($ftp, $fsNodePath));
    return (preg_match('/^OS\.unix\=(slink|symlink)/i', $type) === 1);
}

function fsNodeType($ftp, $fsNodePath)
{
    $lines = array_values(ftp_raw($ftp, "MLST $fsNodePath"));
    $linesCount = count($lines);
    if ($linesCount === 1) {
        throw new Exception('Unsuitable response for MLST command: ' . $lines[0]);
    }
    if ($linesCount !== 3) {
        $e = new Exception('Unexpected response for MLST command (1)');
        $e->response = $lines;
        throw $e;
    }
    if (!preg_match('/^250\-/', $lines[0]) || !preg_match('/^250 /', $lines[2])) {
        $e = new Exception('Unexpected response for MLST command (2)');
        $e->response = $lines;
        throw $e;
    }
    $spEntry = ' ' . $lines[1];
    if (preg_match('/[\s\;]type\=([^\;]+)/i', $spEntry, $matches)) {
        $type = trim($matches[1]);
        return $type;
    } else {
        throw new Exception('Failed to extract filesystem node type from SP entry:' . $spEntry);
    }
}

$ftp = ftp_connect('192.168.0.100');
ftp_login($ftp, 'user', '1234');
$is = isDir($ftp, 'tmp');
var_dump($is);

Note that not every server supports MLST command. For example, ftp.freebsd.org does not :(

Here is a function to do this. It returns a simple true or false . It also handles some edge cases.

function isDir($connection, $dir)
{
    $dir = trim($dir, '/');
    $dir = '/' . $dir;
    if ($dir === '/') {
        return true;
    }
    return in_array($dir, ftp_nlist($connection, dirname($dir)));
}

ftp_nlist already kinda does it:

function ftp_is_dir($path) {
  global $ftp_conn;
  $list = ftp_nlist($ftp_conn, $path);
  if ($list && count($list)>1) return true;
  else return false;
}

ftp_nlist returns an array of one element when a valid file (not folder) is given as $path, whereas, even an empty folder will yield 2 elements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM