is_dir function for FTP/FTPS connections I'm implementing an is_dir() function to determine if a given item is a directory or a file for FTP/FTPS connections. Currently, I have two methods: one using PHP's FTP wrapper for the is_dir() function and another recommended in the help page for the ftp_chdir() function.

Here's the first one (protocol wrapper):

if ($items = ftp_nlist($this-&gt;attributes["link"], $path)) {
    $output = null;

    foreach ($items as $item) {
        if (is_dir("ftp://{$this-&gt;attributes["user"]}:{$this-&gt;attributes["password"]}@{$this-&gt;attributes["host"]}/{$item}")) {
            $output[] = $item;
        }
    } 

    $output[] = sprintf("%5.4fs", (microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]));
    return $output;
}


Here's the second one (chdir implementation):

if ($items = ftp_nlist($this-&gt;attributes["link"], $path)) {
    $output = null;
    $current = ftp_pwd($this-&gt;attributes["link"]);

    foreach ($items as $item) {
        if (@ftp_chdir($this-&gt;attributes["link"], $item)) {
            ftp_chdir($this-&gt;attributes["link"], $current);
            $output[] = $item;
        }
    }

    $output[] = sprintf("%5.4fs", (microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"]));
    return $output;
}


The problem I find with these two implementations is they're quite slow (or, at least, I think they should be faster to be used within AJAX calls). Running these two functions and measuring their execution time with the last element in the returned array, these are their timed values (ran them 50 times to get an accurate enough time reading): 7.2312s for method A and 2.4534s for method B.

Which shows the ftp_chdir() implementation is almost 3x faster than using the FTP wrapper. Still... I have the feeling there may be room for improvement.

My development machine is Windows 7 x64 with Apache 2.4.4 (x86), PHP 5.4.13 (x86, thread-safe version) and MySQL 5.6.10 x64 (irrelevant in this case), always keeping up-to-date packages. The FTP server I ran these tests against is another Windows machine but a full-fledged production server (dedicated) on a data center.

Is there any other method to do the same but in a better (and/or faster) fashion?
In case someone is interested, here's a follow up to MarcDefiant's comment about using ftp_rawlist(). It's fast if you're already using it for getting the file list as well. Here's a snippet from the filebrowser.php in my GitHub filebrowser project. It's certainly not on the same level as Flysystem but I enjoyed working on it :).

public function isDir($path,$contents=NULL){
    $name = getPathName($path);
    if($contents === NULL){
        $path = getItemPath($path);
        $contents = $this-&gt;scandir($path);
    }
    foreach($contents as $content =&gt; $data){
        if($content == $name){
            if($data['type'] == 'directory'){
                return TRUE;
            }
            return FALSE;
        }
    }
    return FALSE;
}

public function scandir($path=NULL){
    if($path === NULL){
        $path = $this-&gt;Path;
    }
    if(!$path){
        $path = ".";
    }
    if(is_array($children = @ftp_rawlist($this-&gt;conn_id, $path))){
        $items = array();

        foreach($children as $name =&gt; $child){
            if(!$name){
                continue;
            }
            $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;
    }
    return FALSE;
}

function getPathName($path){
    return substr($path,strrpos("/".$path,"/"));
}