码迷,mamicode.com
首页 > 其他好文 > 详细

文件存到aws的S3后, 调用getimagesize失败分析

时间:2015-03-19 18:12:54      阅读:1308      评论:0      收藏:0      [点我收藏+]

标签:

一、问题

将图片在windows下用图片查看器修改后,上传到s3中,调用getimagesize获取图片信息总是返回false,其它图片正常;

 

代码如下:

$fileName = ‘s3://sdk1/20150317/174290_1_1428371.JPG‘;
$size = getimagesize($fileName);
var_dump($size);

 

以上代码总是输出false。

即部分图片调用成功,部分调用失败;

图片上传后,可以对上传的临时文件调用getimagesize获取图片信息;

PHP的版本为5.6.2

 

二、分析过程:

1、准备知识

先说下PHP中对流的封装,通过函数stream_wrapper_register,我们可以注册一个新的URL,像上面的s3开头的文件;

AWS封装了一套对这类文件的操作,包括读、写、定位、打开目录等函数,这方面资料可以看下PHP文档,AWS的封装代码可以看下AWS的PHP的SDK。

 

通过追代码,发现对S3文件的请求最终会转成一个HTTPS的请求,https://sdk1.s3.cn-north-1.amazonaws.com.cn/20150317/174290_1_1428371.JPG

 

2、代码追踪

看下getimagesize函数的实现,

技术分享

 

这个是调用php_getimagesize_from_any来实现的,

技术分享

重要函数为php_getimagesize_from_stream,看下这个函数:

技术分享

会先读取文件的前三字节,获取文件类型,具体可以看下php_getimagetype函数;

 

如果是jpg类型的图片,会调用php_handle_jpeg函数,

技术分享

其中函数php_next_marker会读取文件的二进制流当前字节,根据不同字节作不同的处理,

技术分享

如果当前字节为宏M_APP0至M_APP15,即0xe0到0xef,表示是APP或变量;

 

出问题的图片当前是variable,看下php_skip_variables函数

技术分享

如果当前是一个变量,则要跳过这个变量,读取下一块信息,这里调用php_stream_seek来进行seek操作,

技术分享

 

看两块关键代码,上面一段表示seek的位置在已经读取的范围内;

下一块表示这个流不支持seek操作,返回失败;

在我们的例子里,上面表示正常情况,下面表示失败情况的;

 

我们再回到s3的seek操作的封装:

 return $this->cache[self::SEEKABLE] ? fseek($this->stream, $offset, $whence) === 0 : false;

 

即不支持seek,所以失败了;

 

明白了吗,原理就是getimagesize为从文件的二进制流中读取图片信息,而这个信息是文件的位置是不固定的,必须一块一块的解析,正常的图片的相关信息是在文件前8192个字节之内,而

出错的是8192之外的,如果在8192之外的,需要先将文件流定位到相应位置,再从该位置读取信息,而s3开头的路径不支持seek操作,导致PHP读不文件元信息。

 

三、改进方法

改写Stream::seek方法

public function seek($offset, $whence = SEEK_SET)

    {

        if ($whence == SEEK_SET)

        {

            $pos = $this->ftell();

            if ($pos < $offset)

            {

                $this->read($offset - $pos);

            }

        }

        return $this->cache[self::SEEKABLE] ? fseek($this->stream, $offset, $whence) === 0 : false;

文件存到aws的S3后, 调用getimagesize失败分析

标签:

原文地址:http://www.cnblogs.com/szprg/p/4350985.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!