getimagesize() 不适用于具有 HTTPS 的 PNG 图像

getimagesize() is not working with PNG images having HTTPS

我有这张图片:

  $imgurl = 'https://www.danmurphys.com.au/media/DM/Product/308x385/913411_0_9999_med_v1_m56577569854513142.png';

这两个代码我都试过了

  1. $image = @getimagesize($imgurl);
    print_r($image);
    

没有结果。

见下面的第二种情况,以函数 getRanger

开头
  1. public static function getRanger($url){
        $headers = array(
        "Range: bytes=0-327680"
        );
    
        $curl = curl_init($url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $data = curl_exec($curl);
        curl_close($curl);
        return $data;
    }
    
    $raw    = self::getRanger($imgurl);
    $im     = imagecreatefromstring($raw);
    
    $width  = imagesx($im);
    $height = imagesy($im);
    
    echo $width;
    echo $height;
    

两者都给我空结果。你们中的一些人可以帮助我吗?

提前致谢。

第二个就快到了。

我很确定调用

echo curl_error($curl);

执行 curl 后会出现:SSL 证书问题:无法获取本地颁发者证书

基本上有两种方法可以解决这个问题 -

正确的方法

https://curl.haxx.se/docs/caextract.html 下载 cacert.pem 文件,将其保存在脚本可以访问的地方,并在 curl_exec() 之前添加以下行;打电话

    // Add certification atuhority info
    curl_setopt($curl, CURLOPT_CAINFO, './path/to/cacert.pem'); 

请注意,这不适用于自签名 SSL 证书

快速修复

您可能想要进行 SSL 检查 'loose'。

    // disable SSL checks
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);

请注意,此方法甚至可以使用自签名 SSL 证书,但这样做被认为是不安全的。

我知道这个答案被接受已经有一段时间了,但它不太适合我的用例,所以我想添加这个。在 OP 的示例中,他们有一个 HTTPS url,其证书未通过 SSL 检查。在我的例子中,我使用 TCPDF 将 HTML 转换为 PDF,其中 HTML 包含一个 img 标签,使用自签名证书调用 HTTPS 服务器。 TCPDF 硬编码了对 $img_size = @getimagesize() 的调用,因此无法用某些自定义函数替换它。

1。尽可能自定义上下文

适用于接受上下文的函数,例如 file_get_contents

<?php
// Create a read context that disables peer verification when used
$context = stream_context_create(array(
    'ssl' => array(
        'verify_peer' => false,
        'verify_peer_name' => false,
    )
));

// The self-signed server URL
$url = 'https://domain.tld/doc.png';

// Make this the global default context
stream_context_set_default($context);
$content = file_get_contents($url);

// OR use in a specific function call without changing global context
$content = file_get_contents($url, false, $context);

2。流包装器解决方案

使用 GD 库函数,包括 getimagesize

<?php
// Unregister existing https handling
stream_wrapper_unregister('https');

// Register the custom handler
stream_wrapper_register('https', "HttpsInsecureStream", STREAM_IS_URL);

/**
 * Content is read with CURL into a tmpfile that is deleted as soon as the stream is closed
 */
class HttpsInsecureStream {
    public $context = null;

    public function __construct() {
        $this->context = tmpfile();
    }

    public function stream_open($path,$mode,$options,&$opened_path){
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $path);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
        fwrite($this->context, curl_exec($curl));
        rewind($this->context);
        curl_close($curl);
        return true;
    }

    public function stream_stat() {
        return fstat($this->context);
    }

    public function stream_seek($seek_offset, $seek_whence) {
        return (fseek($this->context, $seek_offset, $seek_whence) === 0);
    }

    public function stream_tell(){
        return ftell($this->context);
    }

    public function stream_read($read_buffer_size){
        $result = fread($this->context, $read_buffer_size);
        return $result;
    }

    public function stream_write($write_data){
        return fwrite($this->context, $write_data);
    }

    public function stream_eof(){
        return feof($this->context);
    }

    public function stream_close () {
        return fclose($this->context);
    }

    public function stream_flush () {
        return fflush($this->context);
    }

    public function url_stat ($path ,$flags ) {
        return $this->stream_stat();
    }

    /* These functions are not implemented in this example, not sure if 
     * any of them make sense in the context of an HTTPS request.
     * Including them as a reference for the other handler functions that
     * are possible to implement in custom stream handler classes.
     */

    /*
    public function dir_closedir() { echo 1; return true; }
    public function dir_opendir ($path , $options ) { echo 2; return true; }
    public function dir_readdir () { echo 3; return true; }
    public function dir_rewinddir () { echo 4; return true; }
    public function mkdir ($path ,$mode ,$options ) { echo 5; return true; }
    public function rename ($path_from ,$path_to ) { echo 6; return true; }
    public function rmdir ($path ,$options ) { echo 7; return true; }

    public function stream_cast ($cast_as ) { echo 8; return $this->resource; }
    public function stream_lock ($operation ) { echo 'A'; return true; }
    public function stream_metadata ($path ,$option , mixed $value ) { echo 'B'; return true; }
    public function stream_set_option ($option ,$arg1 ,$arg2 ) { echo 'C'; return true; }
    public function stream_truncate ($new_size ) { echo 'D'; return true; }

    public function unlink ($path ) { echo 'E'; return true; }
    */
}

我想澄清的是,上面的例子展示了如何让它工作,但是不安全。我在开发服务器上使用它,如果我必须在生产中使用它,我会使用 CURLOPT_CAINFO 选项(参见上面的@Zenithies 解决方案)。

参考:https://www.php.net/manual/en/class.streamwrapper.php