WebDav-Client mit PHP
Aufgrund der unbeschritten Vorteile erfreut sich die HTTP-WebDav-Erweiterung immer größerer Beliebtheit. Die Anbieter der Betriebssysteme bauen für den Zugriff auf ein WebDav-Laufwerk bereits standardmäßige Erweiterungen ein. Es gibt aber auch die Alternative für einen Administrator oder Programmierer, auf eine betriebssystem-unabhängige Variante zurückzugreifen. WebDav besteht aus einer Sammlung von HTTP-Methoden und so gibt es die Möglichkeit, sich mit einer Sprache wie z.B. PHP, die den Zugriff auf Sockets unterstützt, einen eigenen WebDav-Client zu programmieren.Interne connect-Funktion der Klasse
Grundsätzlich beruht die Arbeit der PHP-Klasse darauf, dass in den einzelnen Funktionen, die vom Skript aus angesprochen werden, die Inhalte generiert werden und diese danach an die Socket-Funktion der Klasse übergeben werden, die auch die Antwort vom Server erhält. Der Quellcode dieser Socketfunktion kann z. B. so aussehen:function __connect( $param = array() )
{
$fp = fsockopen($this->server, 80, $errno, $errstr, 5);
if(!$fp)
{
return "$errno -> $errstr<br>";
}
else
{
fwrite($fp, $param['content']);
$output_array = array();
while(!feof($fp))
{
array_push($output_array,fgets($fp));
}
fclose($fp);
return $output_array;
}
}
public
kann die Funktion nur innerhalb der Klasse aufgerufen werden. Zuerst wird eine Socket-Verbindung über den Port 80 an die übergebene IP-Adresse oder Hostnamen hergestellt. Wenn das nach 5 Sekunden nicht möglich ist, wird eine Fehlernummer zusammen mit einem Fehlertext, der im Rahmen der fsockopen-Funktion zur Verfügung steht, zurückgegeben. Im Erfolgsfall wird über die Funktion fwrite
der an die Funktion übergebene Inhalt in das Socket geschrieben. Die Antwort der Gegenstelle wird innerhalb der while-Schleife in ein Array geschrieben, welches über return
zurückgegeben wird.
Funktionen der WebDav-Klasse
Man muss sicherlich den Fall mit einkalkulieren, dass der Programmierer der Anwendung nicht unbedingt auch der Betreuer des Webservers ist. Insofern ist es möglich, dass der Programmierer nur die IP-Adresse oder den Hostnamen des Webservers kennt und darüber hinaus keine Details zur Verfügung hat. Deshalb ist es sinnvoll eine Funktion mit in die Klasse einzubauen, die überprüft, ob der Webserver WeDav fähig ist oder nicht. Mit der folgenden Funktion ist dies möglich:public function check_webdav( $param=array() )
{
$content = "HEAD / HTTP/1.1 rn";
$content .= "Host: $this->server rn";
$content .= "Connection: Closern";
$content .= "rn";
$output = $this->__connect( array('content'=>$content) );
foreach($output as $line)
{
if( preg_match("/Server:/",$line) )
{
if( !preg_match("/DAV*/",$line) )
{
return "1";
}
}
}
}
$content
ein HTTP-Header mit der Methode HEAD zugewiesen. Damit werden nur sog. Kopfdaten und keine Nutzdaten per HTTP an den Server geschickt. Danach wird der Header an die interne connect
-Funktion geschickt und der Rückgabewert dieser Funktion als Array in die Variable $output
geschrieben. Zuletzt wird das Array $output nach der eindeutigen Zeile, die den Ausdruck "Server:" enthält, durchsucht. In der gleichen Zeile wird überprüft, ob diese den Ausdruck "DAV" enthält. Wenn das nicht der Fall ist, wird die "1" zurückgegeben. Das bedeutet, dass der angegebene Webserver nicht WebDav-fähig ist.
Inhalt des WebDav-Laufwerkes / Verzeichnisses
Nachdem man weiß, dass der Webserver WebDav unterstützt, sollte man sich als erstes den Inhalt des Laufwerkes oder eines bestimmten Verzeichnisses anzeigen lassen. Das folgende Beispiel bezieht sich auf einen bestimmten Ordner im WebDav-Laufwerk, der durch einen übergebenen Parameter eindeutig festgelegt wird. Die folgende Funktion zeigt eine Option auf, wie der Inhalt eines bestimmten Ordners angezeigt werden kann:public function show_content( $param=array() )
{
$user = $param['user'];
$content = "PROPFIND /files/$user/ HTTP/1.1 rn";
$content .= "Host: $this->server rn";
$content .= "Depth: 1rn";
$content .= "Content-Type: text/xmlrn";
$content .= "Connection:closern";
$content .= "Content-Length: 0rn";
$content .= "rn";
$content .= "<?xml version="1.0" encoding="utf-8"?>rn";
$content .= "<D:propfind xmlns:D="DAV:">rn";
$content .= "<D:allprop/>rn";
$content .= "</D:propfind>rn";
$output = $this->__connect( array('content'=>$content) );
array_pop($output);
$key = array_search("rn",$output);
$output = array_slice($output,($key+1));
}
Hinweise: Der Inhalt der Funktion wird nur bis zum Array
$output
angezeigt, welches als XML-Struktur alle abgefragten Details enthält. Die weitere Verarbeitung dieses Arrays bleibt jeden selbst überlassen. Die folgenden Informationen werden konkret abgerufen: Ordner-/Dateiname, Zeitpunkt der Erstellung, Zeitpunkt der letzten Änderung und - wenn möglich - die Dateigröße. Für jedes Verzeichnis, welches beim PROPFIND-Request ermittelt wurde, muss ein neuer Request durchgeführt werden, um den kompletten Laufwerksinhalt auf allen Ebenen darstellen zu können.
Upload einer Datei in das WebDav-Verzeichnis
Hier bietet sich die Anwendung der PHP-Funktioncopy()
an. Dabei muss man beachten, dass man für das Ziel zwar eine URL angeben kann, bei der Ausführung der Funktion mit dieser Variante aber ein Fehler angezeigt wird. Da ein WebDav-Laufwerk nichts anderes als ein Verzeichnis auf dem Server ist, kann jedoch auch der lokale Pfad für das Ziel hergenommen werden. Insofern kann ein Dateiupload in den WebDav-Pfad mit der folgenden Funktion realisiert werden:
public function file_upload( $param = array() )
{
$user = $param['user'];
$tmp_filename = $param['tmpfile'];
$filename = $param['file'];
if(copy($tmp_filename, "D:/Webdav/" . $user ."/" . $filename) )
{
$content = "<script type=text/javascript>
alert("Datei $filename wurde hochgeladen");
document.location.href="index.php";
</script>";
}
else
{
$content = "<script type=text/javascript>
alert("Datei $filename konnte nicht hochgeladen werden");
document.location.href="index.php";
</script>";
}
return $content;
}
Löschen einer Datei
Im Rahmen der Ermittlung des Verzeichnisinhaltes wurde in die Tabelle ein Button mit eingefügt, der es ermöglicht, die dazugehörige Datei zu löschen. Konkret sieht dieses kleine Formular so aus:<form action="?method=delete&file=$folder" method=post>
<input type=submit value="Datei löschen">
</form>
method
) und als Wert für $folder
wird die zu löschende Datei mitgeliefert. Der Quellcode der Lösch-Funktion in der PHP-Klasse sieht im Beispiel so aus:
public function delete_file( $param = array() )
{
$query_string = $param['query_string'];
$query_param = split("&",$query_string);
$filename = split("=",$query_param[1]);
$file_tmp = str_replace("%3CD:href%3E","",$filename[1]);
$file = str_replace("%3C/D:href%3E","",$file_tmp);
$file_param = pathinfo($file);
$path = $file_param['dirname'] . "/";
$file = $file_param['basename'];
$content = "DELETE $path/$file HTTP/1.1 rn";
$content .= "Host: $this->server rn";
$content .= "Connection: Closern";
$content .= "Content-length:0rn";
$content .= "Destroy:NoUndeletern";
$content .= "rn";
$output = $this->__connect( array('content'=>$content) );
if(preg_match("/204/",$output[0]))
{
$content = "<script type=text/javascript>
alert('Datei $file wurde gelöscht');
document.location.href="index.php";
</script>";
}
else
{
$content = "<script type=text/javascript>
alert('Datei $file konnte nicht gelöscht werden');
document.location.href="index.php";
</script>";
}
return $content;
}
Hinweis: Wenn eine Datei gelöscht wird, landet diese bei einem Windows-Server nicht im Papierkorb!
Anlegen eines neuen Ordners
Die WebDav-Methode MKCOL ermöglicht es, ein neues Verzeichnis im WebDav-Laufwerk anzulegen. Auch für diese Operation gibt es eine Funktion in der PHP-Beispielklasse. Der Code dieser Funktion sieht so aus:public function create_new_folder( $param = array() )
{
$user = $param['user'];
$folder = $param['folder'];
$content = "MKCOL /files/$user/$folder HTTP/1.1 rn";
$content .= "Host: $this->server rn";
$content .= "Connection: Closern";
$content .= "rn";
$output = $this->__connect( array('content'=>$content) );
if(preg_match("/201/",$output[0]))
{
$content = "<script type=text/javascript>
alert('Ordner $folder wurde angelegt');
document.location.href="index.php";
</script>";
}
else
{
$content = "<script type=text/javascript>
alert('Der Ordner $folder konnte nicht angelegt werden.');
document.location.href="index.php";
</script>";
}
return $content;
}
$user
und $folder
wird der Pfad und der Name des neuen Ordners der Funktion bekannt gemacht. Danach wird der HTTP-MKCOL-Request gebaut und an die Connect-Funktion übermitttelt. In der Antwort der Connect-Funktion wird wiederum nach der HTTP-Statusnummer gesucht. Mit einem regulären Ausdruck wird überprüft, ob die Statusnummer "201" ist, was einen Erfolg der Operation bedeutet. Wenn die Nummer nicht "201" ist, wird eine allgemeine Fehlermeldung ausgegeben. In beiden Fällen wird die Webseite zum Schluß aktualisiert.
Zugriff auf die PHP-Klasse in einem Skript
Nach dem Einbinden der Klasse mit include und dem Anlegen der Objekt-Instanz wird zuerst die WebDav-Fähigkeit des Webservers überprüft. In Abhängigkeit des Ergebnisses wird eine Fehlermeldung oder die zu Verfügung stehenden Optionen angezeigt.$conn_check = $webdav->check_webdav(array("server"=>"localhost"));
if($conn_check == "1")
{
print("Der angegebene Server ist nicht webdav-kompatibel");
}
else
{
... Anzeige des WebDav-Formulares ...
}
$content = $webdav->show_content( array("user"=>"test1") );
Aufruf der Funktionen in der PHP-Klasse
Die Funktionen der Klasse für die möglichen WebDav-Operationen werden immer nach dem gleichen Prinzip aufgerufen. Wenn z. B. ein neuer Ordner angelegt werden soll, werden in einem kleinen Formular alle notwendigen Informationen abgefragt. In diesem Fall ist es nur der Name des neuen Ordners. Das Formular sieht im Beispiel so aus:print("
<h1>Anlegen eines neuen Ordners</h1>
<form action="index.php?method=folder" method="post">
<input type="text" name="ordner">
<input type="submit" value="Ordner anlegen">
</form>
");
if(preg_match("/folder/",getenv('QUERY_STRING')))
{
$folder = $_POST['ordner'];
$folder_content = $webdav->create_new_folder(
array('user' => $user, 'folder' => $folder));
print_r($folder_content);
}
if(preg_match("/delete/",getenv('QUERY_STRING')))
{
$delete_content = $webdav->delete_file(
array('query_string' => getenv('QUERY_STRING')));
print("$delete_content");
}
if(preg_match("/upload/",getenv('QUERY_STRING')))
{
$upload = $webdav->file_upload(
array("user"=>$user, "tmpfile"=>$_FILES['file']['tmp_name'],
"file" => $_FILES['file']['name']));
print("$upload");
}
Du arbeitest in einer Agentur oder als Freelancer?
Dann wirf doch mal einen Blick auf unsere Software FeatValue.
Weiterlesen: ⯈ Umfragensystem
Über uns
Wir entwickeln Webanwendungen mit viel Leidenschaft. Unser Wissen geben wir dabei gerne weiter. Mehr über a coding project