Php 在FTP站点上放置包含字符串变量内容的文件(无本地文件)

Php 在FTP站点上放置包含字符串变量内容的文件(无本地文件),php,ftp,Php,Ftp,我想将文件上载到FTP服务器,但文件内容保存在变量中,而不是实际的本地文件中。我想避免使用文件;这是为了在(可能)不太安全的系统(*)上处理敏感数据时避免安全风险,以及最大限度地减少(已经很低的)文件处理开销 但是PHP的FTP API只提供通过函数或(当文件已经作为文件句柄打开时)从本地文件上传文件 目前,我在一个临时文件中使用此功能,在上传之前,我会在其中写入内容: $tmpfile = tmpfile(); fwrite($tmpfile, $content); fseek($tmpfil

我想将文件上载到FTP服务器,但文件内容保存在变量中,而不是实际的本地文件中。我想避免使用文件;这是为了在(可能)不太安全的系统(*)上处理敏感数据时避免安全风险,以及最大限度地减少(已经很低的)文件处理开销

但是PHP的FTP API只提供通过函数或(当文件已经作为文件句柄打开时)从本地文件上传文件

目前,我在一个临时文件中使用此功能,在上传之前,我会在其中写入内容:

$tmpfile = tmpfile();
fwrite($tmpfile, $content);
fseek($tmpfile, 0);
ftp_fput($ftp, $filename, $tmpfile, FTP_BINARY);
是否有一种更简单的方法根本不使用本地(PHP)站点上的文件?

有一种方法可以用来发送任意命令,因此我可以手动发出
PUT
命令,但是我看不到在数据通道上手动写入数据的方法

我不知道这是否重要,但FTP连接是用SSL()保护的



(*)考虑攻击者对整个文件系统有只读控制的情况。

fOpect应该能够通过FTP连接:

然后使用fwrite将字符串写入连接:


fwrite的第二个参数是需要写入的字符串-您不需要在其中写入文件。

这可能不是最终的解决方案,但我想仍然比原始方法更好:

通过使用PHP内存流,可以避免文件系统上的临时文件。它基本上是一个文件句柄包装器,它(在幕后)不使用实际的文件,而是使用一些内存块

因此,实际上您仍然使用文件句柄(因此
ftp\u fput
很高兴),但没有实际的文件(因此没有文件写入磁盘,并且开销保持最小)

请注意,在上载多个文件时,您可以通过对所有文件重用相同的文件句柄来进一步减少开销(当然,除非您并行化该过程)。在这种情况下,也可以在
ftp\u fput
之后倒带文件,并使用
ftruncate($tmpfile,0)

--ftp PUT contents(PHP7.0)将其截断---


不涉及本地文件(ftp\U fput):


为什么这不是最终的解决方案,这是因为它有点黑客行为,还是因为这会带来风险?@Martijn嗯,对我来说,这听起来只是黑客行为——没有安全问题。我在寻找像
ftp\u put
(从字符串参数中放入数据)这样的东西,但它似乎不存在。总的来说,PHP的协议“包装器”api允许绕过这种缺失的api功能,我觉得这听起来有点骇人听闻,但似乎是处理“虚构”文件的“正常”方式,而其他一些api只提供处理文件(如FTP api)。有人可能会觉得它很优雅,有人会觉得它很俗气您将如何使用此文件名发送文件名?@user2924019在随后调用的ftp命令中,您始终明确指定远程文件名。此解决方案以及指定要上载的文件名时都是如此。不工作->警告:ftp_put()要求参数3为有效路径
$tmpfile = fopen('php://memory', 'r+');
fputs($tmpfile, $content);
rewind($tmpfile); // or fseek
$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);
$stream = fopen('php://memory','r+');
fwrite($stream, $newFileContent);
rewind($stream);

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

fclose($stream);