Abend!
Meine Ftp-Klasse ist nun endlich fertig und ich bin dabei einen kleinen FTP-Client zu basteln, der Vorrangig als Testoberfläche genutzt werden soll und später eben als kleines Feature auf meiner Seite verfügbar sein wird. Nun bin ich dabei eine zweite Klasse zu basteln, die auf FtpConnect aufbaut und deren Standard-Commandos nutzt und erweitert. So soll diese eine visualisierte Ausgabe in einer Tabelle, rekursives löschen, verschieben und andere nützliche Operationen ermöglichen. Nun stoße ich aber auf ein kleines Problem. Die Methode listPath() der Klasse FtpConnect liefert einen sehr sehr langen String zurück, den die Methode showList() verarbeitet. showList()Speichert zuerst die einzelnen Absätze des Strings in ein Array $list. Jedes Array-Element von $list wird nun via split() anhand seiner Leerzeichen weiter unterteilt und das Ergebnis in das zweidimensionale Array $list geschrieben. Festgelegte Konstanten erlauben nun die Ausgabe einzelner Informationen eines Datensatzes in einer foreach()-Schleife. Soweit so gut! Nun tritt aber das übliche Problem mit den Verzeichnissen ./ und ../ auf, die man gefiltert haben möchte. Denkt man sich kein Problem der Name der Datei bzw. des Verzeichnisses ist ja in der Variable $file[FNAME] gespeichert, prüft man diese also einfach auf den Inhalt . und .., aber Pustekuchen. Das funktioniert irgendwie nicht.
Kann mir vielleicht jemand helfen? Habe den Quellcode der Klassse WebFtp mal angehängt. Hoffe er ist für euch übersichtlich genug! Habe mir angewöhnt nach diesem hier ersichtlichem Schema zu coden, damit auch andere meinen Gedankengang verstehen. Ein Fehler in der Klasse FtpConnect liegt 100%ig nicht vor!
- Code: Alles auswählen
<?php
error_reporting(E_ALL);
// define some constants
define ('FPERM', 0);
define ('FINODE', 1);
define ('FUID', 2);
define ('FGID', 3);
define ('FSIZE', 4);
define ('FMONTH', 5);
define ('FDAY', 6);
define ('FTIME', 7);
define ('FNAME', 8);
// call FtpConnector class
require_once("FtpConnect.php");
/***
* WebFtp supplement FtpConnect class with a view methods,
* which for example allow you to delete directories recursiv.
*
* @package WebFtp
* @version 1.0
* @author Andreas Wilhelm <Andreas2209@web.de>
* @copyright Andreas Wilhelm
**/
class WebFtp extends FtpConnect
{
// public class variables
protected $var;
/**
* Constructor - Is called when the class is instanced
*
* @access: public
* @param Str $host
* @param Int $port
* @param Str $user
* @param Str $pwd
* @param Boo $log
* @return NONE
*/
public function __construct($host='localhost', $port=21, $user, $pwd, $log=false)
{
parent::__construct($host, $port, $user, $pwd, $log);
}
/**
* Constructor - Is called when the class is instanced
*
* @access: public
* @param Str $data
* @param Str $path
* @return NONE
*/
public function showList($path = "")
{
// alternate path
if(empty($path))
$path = $this->pwd();
// save each line of data to an array-element
$list = split("\n", $this->listPath($path));
// cut last result, because it's empty
$list = array_slice($list, 0, count($list)-1);
foreach($list as $file)
{
// split up the differnet elements of a line by delimeter " "
$file = preg_split("/ /", $file, 20, PREG_SPLIT_NO_EMPTY);
if($this->isDot($file[FNAME]))
{
// prepare download-link for directories
if(preg_match('/^d/',trim($file[FPERM])))
{
$downlink = "dir.php?dir=". urlencode("$path/".$file[FNAME]);
}
// prepare download-links for files
else
{
$downlink = "getfile.php?filename=". urlencode("$path/".$file[FNAME]);
}
// print out table layout with information
printf('<tr>
<td><a href="%s">%s</a></td>
<td>%s</td>
<td>%s.%s %s</td>
<td>%s</td>
<td>%s / %s</td>
</tr>',
$downlink, $file[FNAME],
number_format($file[FSIZE]/1024, 0, ",", ".")." kb",
$file[FDAY], $file[FMONTH], $file[FTIME],
$file[FPERM],
$file[FUID], $file[FGID]);
}
}
}
/***
* delPath() - Removes a full tree of dirs and files recursive
*
* @access public
* @param Str $path
* @return boolean
**/
public function delPath($path)
{
// save each line of data to an array-element
$list = split("\n", $this->listPath($path));
// cut last result, because it's empty
$list = array_slice($list, 0, count($list)-1);
foreach($list as $file)
{
if ($file[FNAME] != "." && $file[FNAME] != "..")
{
// check if handle is a dir or a file
if (preg_match('/^d/',trim($file[FPERM])))
$this->delPath("$path/".$file[FNAME]);
else
unlink("$path/".$file[FNAME]);
}
}
//remove dir
rmdir($dir);
return true;
}
/***
* isDot() - checks if $dir is ./ or ../
*
* @access public
* @param Str $dir
* @return boolean
**/
private function isDot($dir)
{
// checks if dir is "." or ".."
return ($dir == "." || $dir == "..") ? false : true;
}
}
?>
MfG, Andy
//EDIT: Mir fällt da gerade noch etwas ein. Kann mir jemand sagen, ob das verschieben eines Ordners via FTP rekursiv ist oder ähnlich wie beim Löschen erst so programmiert werden muss?
//EDIT: Problem gelöst! Habe einfach folgende Zeilen
- Code: Alles auswählen
// cut last result, because it's empty
$list = array_slice($list, 0, count($list)-1);
zu
- Code: Alles auswählen
// cut first and second result because it is ./ and ../
// and cut last result, because it's empty
$list = array_slice($list, 2, -1);
geändert und die if()-Abfrage weggelassen.
//EDIT: bleibt aber dennoch die Frage offen, ob man RNFR und RNTO rekursiv verschieben kann oder nicht.