如何使用 PHP 将图像返回到 https 请求 [英] How to return an image to an https request with PHP

查看:41
本文介绍了如何使用 PHP 将图像返回到 https 请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几个小时后,

我解决了有关使用 https 请求下载图像的问题.当我使用硬路径 (https://mysite/tmp/file.jpg) 访问图像时,apache成功返回它,我可以在浏览器中查看它,无需任何额外的操作.当我尝试使用另一条路径访问它时(https://mysite/files/file.jpg),为了用php控制它的访问,我得到来自我的 php 代码的响应,但我无法在浏览器中查看图像.

I nailed down my problem concerning downloading an image with an https request. When I access an image with the hard path (https://mysite/tmp/file.jpg), apache returns it with success and I can view it in the browser, without any extra manipulation. When I try to access it with another path (https://mysite/files/file.jpg), in order to control its access with php, I get a response from my php code, but I cannot view the image in the browser.

  • 定义了虚拟主机;mysite:设置为/var/www/mysite
  • $app['controllers']->requireHttps();

环境描述:

mysite/tmp/file.jpg          
mysite/files/.htaccess
            //... no files; handled by Silex router. here is the .htaccess:
            ---
            <IfModule mod_rewrite.c>
                RewriteEngine On
                RewriteRule ^ ../web/index.php [L]
            </IfModule>
            ---

  • https://mysite/tmp/file.jpg,以https:200提供并在浏览器中查看;好的
  • https://mysite/files/file.jpg 提供 https:200 但不是 在浏览器中查看;?
  • 以下是尝试的 3 种方法:

    Here are the 3 methods tried:

    方法一:Silex sendFile() 直接方法>

    $app->get('/files/{onefile}', function ($onefile) use ($app) {    
        // Validate authorization;  if ok, then
        return $app->sendFile('/var/www/mysite/tmp/' . $onefile);
    });
    

    方法 2:Silex Streaming >

    $app->get('/files/{onefile}', function ($onefile) use ($app) {   
        // Validate authorization;  if ok, then
       $stream = function () use ($file) {
           readfile($file);
       };
       return $app->stream($stream, 200, array('Content-Type' => 'image/jpeg'));
    

    方法三:Symfony2风格>

    $app->get('/files/{onefile}', function ($onefile) use ($app) {   
        // Validate authorization;  if ok, then
        $exactFile="/var/www/mysite/tmp/" . $onefile;
        $response = new StreamedResponse();
        $response->setCallback(function () use ($exactFile) {
            $fp = fopen($exactFile, 'rb');
            fpassthru($fp);
        });
        $response->headers->set('Content-Type', 'image/jpg');
        $response->headers->set('Content-length', filesize($exactFile));
        $response->headers->set('Connection', 'Keep-Alive');
        $response->headers->set('Accept-Ranges','bytes');
        $response->send();
    

    Chrome 呈现的内容:

    This is what Chrome presents:

    使用此 Chrome 图像,这是 Http(是否为 Https,结果相同)请求

    Request URL:https://mysite/files/tmpphp0XkXn9.jpg
    Request Method:GET
    Status Code:200 OK
    
    Request Headers:
    Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Encoding:gzip,deflate,sdch
    Accept-Language:en-US,en;q=0.8
    Cache-Control:no-cache
    Connection:keep-alive
    Cookie:XDEBUG_SESSION=netbeans-xdebug; _MYCOOKIE=u1k1vafhaqik2d4jknko3c94j1
    Host:mysite
    Pragma:no-cache
    User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.110 Safari/537.36
    
    Response Headers:
    Accept-Ranges:bytes
    Cache-Control:no-cache
    Connection:Keep-Alive, Keep-Alive
    Content-Length:39497
    Content-Type:image/jpg
    Date:Thu, 13 Jun 2013 13:44:55 GMT
    Keep-Alive:timeout=15, max=99
    Server:Apache/2.2.16 (Debian)
    X-Powered-By:PHP/5.3.3-7+squeeze15
    

    为消除可能的不良行为而进行的其他测试:

    • 我检查了 BOM 并确保响应请求的 php 代码有效并且没有使用 Emacs (set-buffer-file-coding-system utf-8) 的不需要的字节顺序标记 (BOM).此外,为了避免未知的 BOM 标记文件,我在 mysite 目录 (grep -rl $'\xEF\xBB\xBF' .) 中执行了以下命令.没有出现任何异常.
    • I checked the BOM and made sure the php code responding to the request is valid and do not have undesired byte-order marks (BOMs) using Emacs (set-buffer-file-coding-system utf-8). Furthermore, to avoid unknown BOM tagged files, I executed the following command in the mysite directory (grep -rl $'\xEF\xBB\xBF' .). Nothing abnormal appeared.

    更新:

    查看浏览器收到的文件(图片)(每张图片上的save as),这是工具(Hex Friend)帮我找到的,但我还是不明白为什么:

    Looking at the files (image) received by the browser (save as on each image), this is what the tool (Hex Friend) help me to find, but I still do not understand why:

    比较两个文件

    • (成功的一个: mysite/tmp/file.jpg ;由 Apache 直接提供)
    • (一个没有成功:mysite/files/file.jpg;由一个 PHP 脚本提供).

    在二进制文件的开头,我得到了这个区别:

    在二进制文件的末尾,我得到了这个区别:

    问题:如何使用 php 代码返回图像(流或其他技术),并在浏览器中查看?所有 php 代码方法都返回相同的输出,我怀疑是环境问题.是否存在可能产生我正在试验的错误的环境设置?

    Question: How can I return an image (in stream or some other technique) with a php code, and view it in the browser ? All php code methods return the same output, I suspect an environment problem. Is there an environment setting that could produce the error I am experimenting ?

    推荐答案

    我对这个解决方案不满意 (A PATCH),但问题已解决,通过添加以下调用:

    I am not happy with this solution (A PATCH), but the problem is fixed, by adding the following call:

    $app->get('/files/{onefile}', function ($onefile) use ($app) {    
      ob_end_clean();  // ob_clean() gave me the same result.
    ...
    }
    

    好的,它已修复,但是,有人可以向我解释如何更智能地修复它吗?

    Ok, it is fixed, but, can somebody explain to me how to fix it more intelligently ?

    更新

    发生了什么?:

    这是我的解释:
    额外的换行符保留在原始 php 原始文件中无意中的位置!原来当你有一个php文件时

    This is what my interpretation:
    Extra newlines remains in the orignal php raw files to a unintentionally position! It turns out that when you have a php file

    <?php
    ...
    ?>
    

    您在 ?> 之后留下了一些换行符(或空格),这些换行符将在输出缓冲区中累加.然后尝试将文件流式传输到输出将把这些加起来的换行符放在它们所属的地方:在标题流中,或在页脚流中.具有固定大小的流(等于图像大小)将特别采用标题额外字符并相应地移动输出到浏览器的字节.我怀疑我添加了与从浏览器接收到的图像中发现的 (linefeed linefeed space linefeed linefeed) 相对应的 5 个字符 (0A 0A 20 0A 0A).现在浏览器无法识别二进制图像的图像结构,从偏移量 0 偏移 5 个非逻辑字符.因此,浏览器只能显示损坏的图像图标.

    where you left some newlines (or spaces) after the ?>, those newlines will add up in the output buffer. Then trying to stream a file to the output will take these add up newlines and put them where they belong: in the header stream, or at the footer stream. Having a fixed size for the stream (equal to the image size) will take specially the header extra characters and shift accordingly the bytes outputted to the browser. I suspected that I add exactly 5 characters (0A 0A 20 0A 0A) corresponding to (linefeed linefeed space linefeed linefeed) discovered in the received image from the browser. Now the browser do not recognize the image structure, being shift from the offset 0, of 5 non logical character for the binary image. Therefore, the browser can only show a broken image icon.

    另请参阅:另一个帮助 SO 修复

    给 PHP 框架开发者的建议:

    如果你提供了一个 sendFile() 等效方法,也许你应该抛出一个 Exception,当 ob_get_contents() 没有返回一个空的缓冲区,就在流到输出之前!

    If you provide a sendFile() equivalent method, maybe you should thrown an Exception, when ob_get_contents() does not return an empty buffer, just before streaming to the output !

    目前:

    这个小的linux批处理文件至少可以让你找到你的代码应该清理的地方.使用它后,我能够在分析这个小脚本的输出后删除 ob_end_clean()....它会告诉您可疑的 php 文件,这些文件可能在 php 文件的末尾包含额外的空格或换行符.只需执行并手动修复文件:

    This small linux batch file can at least let you find where your code should be cleaned. After using it, I was able to remove the ob_end_clean()... after analyzing the output of this small script. It tells you suspicious php files that might contain extra space or newline at the end of your php files. Just execute and manually fix files:

    #!/bin/bash
    
    for phpfiles in $(ls -1R *.php); do
       hexdump -e '1/1 "%.2x"' $phpfiles | tail -1 >endofphpfile;
       if [  `cat endofphpfile` = "3f3e" ]; then
          echo "OK.................File  $phpfiles"
       else 
          thisout=`cat endofphpfile`
          echo "File  $phpfiles: Suspucious. Check ($thisout) at the EOF; it should end with '?>' (in hex 3f3e) "
       fi
    done
    

    它肯定可以改进,但至少应该可以帮助任何人!

    It can surely be improved, but that should, at least, help anybody !

    这篇关于如何使用 PHP 将图像返回到 https 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆