2015-06-26 15 views
8

Tôi muốn tải tệp lên máy chủ FTP nhưng nội dung tệp được giữ trong một biến chứ không phải trong tệp cục bộ thực. Tôi muốn tránh sử dụng một tập tin; điều này là để tránh rủi ro bảo mật khi xử lý dữ liệu nhạy cảm trên hệ thống (có thể) không an toàn (*), cũng như để giảm thiểu chi phí xử lý tệp (đã thấp).Đặt tệp trên trang FTP với nội dung từ biến chuỗi (không có tệp cục bộ)

Nhưng API FTP của PHP chỉ cung cấp tệp tải lên từ tệp cục bộ thông qua hàm ftp_put hoặc (khi tệp đã được mở dưới dạng xử lý tệp) ftp_fput.

Hiện nay, tôi sử dụng chức năng này với một tập tin tạm thời, trong đó tôi viết nội dung trước khi tải lên:

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

Có một cách đơn giản mà không sử dụng các tập tin trên các địa phương (PHP) trang web ở tất cả?

ftp_raw mà có thể được sử dụng để gửi các lệnh tùy ý, vì vậy tôi có thể thực hiện lệnh PUT bằng tay, tuy nhiên tôi không thấy một cách để tự viết các dữ liệu trên các kênh dữ liệu ...

Tôi không biết nếu nó là quan trọng, nhưng kết nối FTP được bảo đảm bằng SSL (ftp_ssl_connect).


(*) Xem xét trường hợp kẻ tấn công có quyền kiểm soát chỉ đọc trên toàn bộ hệ thống tệp.

Trả lời

12

Đây có thể là không có giải pháp cuối cùng nhưng tôi đoán là vẫn tốt hơn so với cách tiếp cận ban đầu:

Bạn có thể tránh các file tạm thời trên hệ thống tập tin bằng cách sử dụng một bộ nhớ dòng PHP. Về cơ bản, nó là một phần mềm xử lý tệp (đằng sau hậu trường) không sử dụng tệp thực tế mà thay vào đó là một phần bộ nhớ.

Vì vậy, hầu như bạn vẫn sử dụng một tập tin xử lý (vì vậy ftp_fput là hạnh phúc), nhưng không thực tế tập tin (vì vậy không có tập tin được ghi vào đĩa và chi phí được giữ tối thiểu).

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

Lưu ý rằng khi tải lên nhiều tập tin, bạn có thể tiếp tục giảm thiểu chi phí bằng cách tái sử dụng tay cầm tập tin tương tự cho tất cả các file (trừ khi bạn parallelize thủ tục, tất nhiên). Trong trường hợp này, cũng tua lại tệp sau ftp_fput cũng như cắt bớt tệp bằng cách sử dụng ftruncate($tmpfile, 0).

+1

Tại sao không phải là giải pháp cuối cùng này, là thế này bởi vì nó là loại hacky, hoặc vì điều này tạo ra rủi ro? – Martijn

+1

@ Martart Vâng, với tôi nó chỉ là âm thanh hacky - không có mối quan tâm an ninh. Tôi đã tìm kiếm một cái gì đó như 'ftp_puts' (đưa dữ liệu từ một đối số chuỗi), mà dường như không tồn tại. Nói chung, api "wrapper" của PHP cho phép phá vỡ chức năng API bị thiếu, điều này nghe có vẻ khó hiểu với tôi nhưng có vẻ là cách "bình thường" để làm điều gì đó với các tệp "ảo", khi một số API khác chỉ cung cấp các tệp xử lý chẳng hạn như API FTP. Ai đó có thể tìm thấy nó thanh lịch, một người nào đó tìm thấy nó hacky. ;) – leemes

0

----- Nội dung PUT FTP (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

Với không có tập tin địa phương liên quan (ftp_fput):

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

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

fclose($stream); 
Các vấn đề liên quan