加载图像文件时print()和readfile()之间有什么区别?

时间:2012-11-12 17:27:35

标签: php readfile

只是想知道以下两个代码示例是否有任何区别:

$image = 'http://www.example.com/image.jpg'

$photo = file_get_contents($image);

ob_start();
header("Content-type: image/jpeg");
print($photo);
ob_end_flush(); 

...或

$image = 'http://www.example.com/image.jpg'

$photo = file_get_contents($image);

ob_start();
header("Content-type: image/jpeg");
readfile($photo);
ob_end_flush();

3 个答案:

答案 0 :(得分:1)

readfile将文件名作为参数,存在非常显着的差异。

第二个片段应该是

$image = ...
readfile($image)

这样做的好处是不必将整个文件内容存储在内存(字符串)中,因为readfile会立即发出它。当然,如果缓冲输出不再是真的。

答案 1 :(得分:1)

在第一种情况下,您的代码永远不会起作用

  readfile($photo);
              ^--------------- Takes file name not string 

PHP DOC SAYS

  

读取文件并将其写入输出缓冲区。

你不需要重新发生事件并将其与多个其他函数重复,只是说

 readfile = file_get_contents + print 

就像使用fopen代替file_get_contents一样只需在文件中获取简单内容

最后readfile在相同图像上使用10000循环进行更快的测试

Single Run
Array
(
    [m1] => 0.0006101131439209
    [m2] => 0.00031208992004395
)
Dual Run
Array
(
    [m1] => 3.4585757255554   
    [m2] => 2.9963381290436   <---- Faster 
)

m1&amp; m2函数

function m1($array) {
    $photo = file_get_contents('a.png');
    ob_start();
    print($photo);
    ob_end_clean();
}

// Array clean copy
function m2($array) {
    ob_start();
    readfile('a.png');
    ob_end_clean();
}

答案 2 :(得分:1)

readfile的参数是文件名,而不是内容本身。因此,你可以这样称呼它:

$image = 'http://www.example.com/image.jpg'
ob_start();
header("Content-type: image/jpeg");
readfile($image);
ob_end_flush();

由于readfile一次读取和写入块,因此其内存消耗将保持不变,而当您将file_get_contents的结果存储到$photo时,您需要有足够的内存消耗内存来存储图像。

在您的情况下,输出缓冲使file_get_contents变体需求两次与图像的大小一样多。对于大图像,readfile因此将内存需求减半。请注意,输出缓冲意味着下载将被延迟。如果您不需要它,那么如果您只是禁用它,您将获得更好的性能(实际速度和服务器内存要求):

$image = 'http://www.example.com/image.jpg'
header("Content-type: image/jpeg");
if (@readfile($image) === false) {
   // print error image
}