读写php://temp流时遇到问题

29

我在 PHP 5.3.2 中读写 php://temp 流时遇到了问题。

我的代码如下:

file_put_contents('php://temp/test', 'test');
var_dump(file_get_contents('php://temp/test'));

我唯一得到的输出是 string(0) ""

我不应该得到返回的 'test' 吗?

4个回答

29

php://temp并不是一个文件路径,它是一个伪协议,每次使用时总是创建一个新的随机临时文件。实际上,/test会完全被忽略。 php://temp包装器接受的唯一额外“参数”是/maxmemory:n。您需要保持已打开的临时流的文件句柄,否则它将被丢弃:

$tmp = fopen('php://temp', 'r+');
fwrite($tmp, 'test');
rewind($tmp);
fpassthru($tmp);
fclose($tmp);

请查看http://php.net/manual/en/wrappers.php.php#refsect1-wrappers.php-examples


找到了我需要的 - 使用vfsStream。 - HorusKol
那么为什么手册中说file_put_contents()可以像fopen()一样接受URL包装器呢? - Accountant م
1
@会计师م …‽ ‍♂️ 它可以完美地运行。只是这个特定的包装器表现出非常特殊的方式。还有其他一些可以很好地与它配合使用的包装器。手册并没有说每个包装器都适合与file_put_contents一起使用。 - deceze
@deceze '只有这个特定的包装器表现出非常特殊的方式' 是的,我终于在手册中找到了一篇注释,它使用了与问题中完全相同的代码示例,并解释了 php://tempphp://memory 不可重用。我想他们的意思是一旦 file_put_contents() 在内部关闭流,我就无法通过 file_get_contents() 再次获取它。 - Accountant م

12

每次使用fopen获取处理程序时,php://temp的内容都将被清空。使用rewind()和stream_get_contents()获取内容。或者,使用常规的缓存器,如APC或memcache :)


4
顺便提一下,你可以使用 stream_get_contents($stream, -1, 0) 隐式地倒带。这将从开头读取整个流。 - quickshiftin

4

终于找到了一篇记录的小笔记,解释了为什么

PHP手册的示例5几乎使用了和你完全相同的代码示例,并且说:

php://memory and php://temp are not reusable, i.e. after the streams have been closed there is no way to refer to them again.

file_put_contents('php://memory', 'PHP');
echo file_get_contents('php://memory'); // prints nothing
我猜这意味着file_put_contents()在内部关闭了流,这使得file_get_contents()无法再次恢复流中的数据。

2

我知道有点晚了,但是除了@OZ_的答案之外,我刚刚发现在rewind之后,'fread'也可以使用。

$handle = fopen('php://temp', 'w+');

fwrite($handle, 'I am freaking awesome');

fread($handle); // returns '';

rewind($handle); // resets the position of pointer

fread($handle, fstat($handle)['size']); // I am freaking awesome

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接