2015-06-26 18 views
8

Desidero caricare un file su un server FTP, ma il contenuto del file è contenuto in una variabile, non in un file locale effettivo. Voglio evitare di usare un file; questo per evitare rischi per la sicurezza quando si gestiscono dati sensibili su un sistema (eventualmente) non sicuro (*), nonché per ridurre al minimo il sovraccarico (già basso) della gestione dei file.Inserire un file sul sito FTP con contenuto da variabile stringa (nessun file locale)

Tuttavia, l'API FTP di PHP offre solo il caricamento di file da file locali tramite la funzione ftp_put o (quando il file è già aperto come handle di file) ftp_fput.

Attualmente, io uso questa funzione con un file temporaneo in cui scrivo il contenuto prima del caricamento:

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

C'è un modo più semplice senza utilizzare file sul locale (PHP) sito a tutti?

C'è ftp_raw che può essere utilizzato per inviare comandi arbitrari, così ho potuto emettere il comando PUT manualmente, ma non vedo un modo per scrivere manualmente i dati sul canale dati ...

Non so se è importante, ma la connessione FTP è protetta con SSL (ftp_ssl_connect).


(*) Si consideri lo scenario in cui un attaccante ha di sola lettura controllo sull'intero file system.

risposta

12

Questo può essere alcuna soluzione definitiva, ma credo che sia ancora meglio che l'approccio originale:

È possibile evitare i file temporanei sul file system utilizzando un flusso di memoria PHP. Fondamentalmente è un wrapper di handle di file che (dietro le quinte) non usa file effettivi, ma un po 'di memoria.

Così praticamente si usano ancora un handle di file (così ftp_fput è felice), ma nessun reale file di (in modo che nessun file viene scritto il disco e l'overhead è tenuto il minimo).

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

Si noti che durante il caricamento di più file, è possibile ridurre al minimo il bisogno di una riutilizzando lo stesso handle di file per tutti i file (a meno che non parallelizzare la procedura, ovviamente). In questo caso, riavvolgere il file anche dopo ftp_fput e troncarlo utilizzando ftruncate($tmpfile, 0).

+1

Perché non è questa la soluzione definitiva, è questo perché è una specie di hacky, o perché questo crea rischi? – Martijn

+1

@Martijn Beh, a me sembra solo un hacker - nessun problema di sicurezza. Stavo cercando qualcosa come 'ftp_puts' (metti i dati da un argomento stringa), che non sembra esistere. In generale, il protocollo "wrapper" API di PHP consente di aggirare tale funzionalità API mancante, che mi sembra un po 'hacky ma sembra essere il modo "normale" di fare qualcosa con i file "immaginari", quando alcune altre API offrono solo file di gestione come l'API FTP. Qualcuno potrebbe trovarlo elegante, qualcun altro lo trova hacky. ;) – leemes

0

----- Contenuto FTP PUT (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

Con alcun file locali coinvolti (ftp_fput):

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

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

fclose($stream); 
Problemi correlati