2015-06-26 4 views
8

Ich möchte eine Datei auf einen FTP-Server hochladen, aber der Dateiinhalt wird in einer Variablen gespeichert, nicht in einer tatsächlichen lokalen Datei. Ich möchte vermeiden, eine Datei zu verwenden; Dies dient der Vermeidung von Sicherheitsrisiken im Umgang mit sensiblen Daten auf einem (möglicherweise) nicht so sicheren System (*), sowie zur Minimierung des (ohnehin geringen) Overheads beim Dateihandling.Eine Datei auf die FTP-Site mit Inhalt aus einer String-Variablen setzen (keine lokale Datei)

Aber PHP FTP-API bietet nur Hochladen von Dateien aus lokalen Dateien über die Funktion ftp_put oder (wenn die Datei bereits als Datei-Handle geöffnet ist) ftp_fput.

Derzeit verwende ich diese Funktion mit einer temporären Datei, in der ich den Inhalt vor dem Upload schreiben:

$tmpfile = tmpfile(); 
fwrite($tmpfile, $content); 
fseek($tmpfile, 0); 
ftp_fput($ftp, $filename, $tmpfile, FTP_BINARY); 

Gibt es einen einfacheren Weg, ohne Dateien auf der lokalen (PHP) Website überhaupt mit?

Es gibt ftp_raw, die verwendet werden können, beliebige Befehle zu senden, so kann ich manuell den PUT Befehl ausgeben, aber ich sehe nicht, einen Weg, um die Daten manuell auf dem Datenkanal zu schreiben ...

Ich weiß nicht, ob es wichtig ist, aber die FTP-Verbindung ist mit SSL gesichert (ftp_ssl_connect).


(*) Betrachten Sie das Szenario, in dem ein Angreifer read-only hat die Kontrolle über das gesamte Dateisystem.

Antwort

12

Dies kann keine ultimative Lösung sein, aber ich denke, als der ursprüngliche Ansatz noch besser ist:

Sie temporäre Dateien auf dem Dateisystem unter Verwendung eines PHP Speicher-Stream vermeiden. Es ist im Grunde ein Datei-Handle-Wrapper, der (hinter den Kulissen) keine tatsächliche Datei, sondern einen Teil des Speichers verwendet.

Sie verwenden also praktisch noch ein Datei-Handle (so ftp_fput ist glücklich), aber keine tatsächliche Datei (also keine Datei auf die Festplatte geschrieben wird, und der Aufwand ist minimal gehalten).

$tmpfile = fopen('php://memory', 'r+'); 
fputs($tmpfile, $content); 
rewind($tmpfile); // or fseek 

Beachten Sie, dass, wenn mehrere Dateien hochladen, können Sie weitere Aufwand minimieren, indem die gleiche Datei-Handle für alle Dateien, die Wiederverwendung (es sei denn, Sie die Prozedur parallelisieren, natürlich). In diesem Fall spulen Sie die Datei auch nach ftp_fput zurück und schneiden Sie sie unter Verwendung von ftruncate($tmpfile, 0) ab.

+1

Warum ist das nicht die ultimative Lösung, ist dies, weil es ist eine Art von Hacky, oder weil dies schafft Risiken? – Martijn

+1

@Martijn Nun, für mich klingt es einfach hacky - keine Sicherheitsbedenken. Ich war auf der Suche nach etwas wie 'ftp_puts' (put Daten von einem String-Argument), das scheint nicht zu existieren. Im Allgemeinen erlaubt das Protokoll "wrapper" API von PHP, solche fehlenden API Funktionalität zu umgehen, die hacky zu mir scheint, aber scheint, die "normale" Weise zu sein, etwas mit "imaginären" Dateien zu tun, wenn eine andere API nur Handhabung von Akten anbietet wie die FTP-API. Jemand könnte es elegant finden, jemand anderes findet es hacky. ;) – leemes

0

----- FTP PUT Inhalt (php 7.0) ---

$tmpFile = tmpfile(); 
fwrite($tmpFile, $contents); 
rewind($tmpFile); 
$tmpMetaData = stream_get_meta_data($tmpFile); 

if (ftp_put($ftpObj, $remoteFile, $tmpMetaData['uri'], FTP_ASCII)) { 
     echo "success"; 
}else { 
     echo "fail" 
} 
fclose($tmpFile); 
2

Ohne lokale Datei beteiligt (ftp_fput):

$stream = fopen('php://memory','r+'); 
fwrite($stream, $newFileContent); 
rewind($stream); 

$success = ftp_fput($connectionId, "remoteFileName", $stream, FTP_BINARY); 

fclose($stream); 
Verwandte Themen