From d1db61c20d6eeef27b6d9279d72168158454b12f Mon Sep 17 00:00:00 2001 From: David de Boer Date: Sat, 19 Nov 2011 13:00:20 +0100 Subject: [PATCH 1/2] Add directory listing functionality --- src/Ssh/Sftp.php | 50 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/Ssh/Sftp.php b/src/Ssh/Sftp.php index c4448ab..f1d283a 100644 --- a/src/Ssh/Sftp.php +++ b/src/Ssh/Sftp.php @@ -200,6 +200,56 @@ public function getUrl($filename) return sprintf('ssh2.sftp://%s/%s', $this->getResource(), $filename); } + /** + * Scan a URL for files and directories + * + * Unfortunately, using a (recursive) directory iterator is not possible + * over SFTP: see https://bugs.php.net/bug.php?id=57378. Also, is_dir() is + * unreliable and often returns false for valid directories. Therefore, I + * use @scandir() instead. + * + * @param string $url + * @return array + */ + protected function scanUrl($url) + { + if (!$files = @scandir($url)) { + return null; + } + + return array_filter($files, function($file) { + if ($file != '.' && $file != '..') { + return true; + } + }); + } + + /** + * List files and directories in a directory + * + * @param string $directory + * @param boolean $includeSubdirectories + * @return array + */ + public function listDirectory($directory, $includeSubdirectories = true) + { + $url = $this->getUrl($directory); + + $contents = array(); + foreach ($this->scanUrl($url) as $file) { + if (true === $includeSubdirectories + && $subFiles = $this->scanUrl("$url/$file")) { + foreach ($subFiles as $subFile) { + $contents[] = "$directory/$file/$subFile"; + } + } else { + $contents[] = "$directory/$file"; + } + } + + return $contents; + } + /** * {@inheritDoc} */ From 77763efcba4050626cffc889e47411a2638b150b Mon Sep 17 00:00:00 2001 From: David de Boer Date: Mon, 5 Dec 2011 17:31:22 +0100 Subject: [PATCH 2/2] Separate listing into keys and dirs --- src/Ssh/Sftp.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Ssh/Sftp.php b/src/Ssh/Sftp.php index f1d283a..2012efa 100644 --- a/src/Ssh/Sftp.php +++ b/src/Ssh/Sftp.php @@ -234,16 +234,20 @@ protected function scanUrl($url) public function listDirectory($directory, $includeSubdirectories = true) { $url = $this->getUrl($directory); + $contents = array( + 'keys' => array(), + 'dirs' => array() + ); - $contents = array(); - foreach ($this->scanUrl($url) as $file) { + $files = $this->scanUrl($url); + foreach ($files as $file) { if (true === $includeSubdirectories && $subFiles = $this->scanUrl("$url/$file")) { foreach ($subFiles as $subFile) { - $contents[] = "$directory/$file/$subFile"; + $contents['keys'][] = "$directory/$file/$subFile"; } } else { - $contents[] = "$directory/$file"; + $contents['keys'][] = "$directory/$file"; } }