解决thinkcmf 中UEditor远程抓取问题


j_0028.gifcmf的远程抓取图片是不能用的

所以需要我们自己去改改。

/**
     * 获取远程图片
     */
    private function _get_remote_image()
    {
        // $source = $this->request->param()['source'];
        $params = $this->request->param();

        if (!isset($params['source'])) {
            return json_encode(['state' => '请求参数不对']);
        }
        $source = $params['source'];

        $item              = [
            "state"    => "",
            "url"      => "",
            "size"     => "",
            "title"    => "",
            "original" => "",
            "source"   => ""
        ];
        $date              = date("Ymd");
        $uploadSetting     = cmf_get_upload_setting();
        $uploadMaxFileSize = $uploadSetting['file_types']["image"]['upload_max_filesize'];
        $uploadMaxFileSize = empty($uploadMaxFileSize) ? 2048 : $uploadMaxFileSize;//默认2M
        $allowedExts       = explode(',', $uploadSetting['file_types']["image"]["extensions"]);
        $strSavePath       = ROOT_PATH . 'public' . DS . "ueditor" . DS . $date . DS;
        //远程抓取图片配置
        $config = [
            "savePath"   => $strSavePath,            //保存路径
            "allowFiles" => $allowedExts,// [".gif", ".png", ".jpg", ".jpeg", ".bmp"], //文件允许格式
            "maxSize"    => $uploadMaxFileSize,                    //文件大小限制,单位KB
        ];

        $storage_setting = cmf_get_cmf_settings('storage');
        $qiniu_domain    = $storage_setting['Qiniu']['domain'];
        $no_need_domains = [$qiniu_domain];

        $list = [];

        foreach ($source as $imgUrl) {
            $host = str_replace(['http://', 'https://'], '', $imgUrl);
            $host = explode('/', $host);
            $host = $host[0];
            if (in_array($host, $no_need_domains)) {
                continue;
            }
            $return_img           = $item;
            $return_img['source'] = $imgUrl;
            $imgUrl               = htmlspecialchars($imgUrl);
            $imgUrl               = str_replace("&", "&", $imgUrl);
            //http开头验证
            if (strpos($imgUrl, "http") !== 0) {
                $return_img['state'] = $this->stateMap['ERROR_HTTP_LINK'];
                array_push($list, $return_img);
                continue;
            }

            //获取请求头
            // is_sae()

            if (!cmf_is_sae()) {//SAE下无效
                $heads = get_headers($imgUrl);
                //死链检测
                if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
                    $return_img['state'] = $this->stateMap['ERROR_DEAD_LINK'];
                    array_push($list, $return_img);
                    continue;
                }
            }
            //获取content-type
            if (!isset($heads)) {
                return json_encode(['state' => '无法获取请求头']);
            }else{
                foreach ($heads as $key => $value) {
                    if(strpos($value, 'Content-Type') !== false){
                        $content_type = $heads[$key];
                    }
                }
            }
            //格式验证(扩展名验证和Content-Type验证)
            $fileType = explode('?', strtolower(strrchr($imgUrl, '.')));
            //后来的修改者:这里默认走if,不存在的时候走下面,其实最好的方法是直接写else里面的,if是原作者的思路,不知道什么意思,else里面的为我的思路
            if (strpos($fileType[0], ".") !== false) {
                if (!in_array(trim($fileType[0], '.'), $config['allowFiles']) || (strpos($content_type, "image") === false)) {
                    $return_img['state'] = $this->stateMap['ERROR_HTTP_CONTENTTYPE'];
                    array_push($list, $return_img);
                    continue;
                }
            }else{
                if (strpos($content_type, "image") === false) {
                    $return_img['state'] = $this->stateMap['ERROR_HTTP_CONTENTTYPE'];
                    array_push($list, $return_img);
                    continue;
                }
            }

            //打开输出缓冲区并获取远程图片
            ob_start();
            $context = stream_context_create(
                [
                    'http' => [
                        'follow_location' => false // don't follow redirects
                    ]
                ]
            );
            //请确保php.ini中的fopen wrappers已经激活
            readfile($imgUrl, false, $context);
            $img = ob_get_contents();
            ob_end_clean();
            //大小验证
            $uriSize   = strlen($img); //得到图片大小
            $allowSize = 1024 * $config['maxSize'];
            if ($uriSize > $allowSize) {
                $return_img['state'] = $this->stateMap['ERROR_SIZE_EXCEED'];
                array_push($list, $return_img);
                continue;
            }

            $file     = uniqid() . strrchr($imgUrl, '.');

            if (!$file) {
                $file = uniqid() . '.jpg';
            }else{
                $file_info = explode('?', $file);
                $file = $file_info[0];
            }

            $savePath = $config['savePath'];
            $tmpName  = $savePath . $file;
            //创建保存位置
            if (!file_exists($savePath)) {
                mkdir("$savePath", 0777, true);
            }
            $file_write_result = cmf_file_write($tmpName, $img);

            if ($file_write_result) {
                if (config('FILE_UPLOAD_TYPE') == 'Qiniu') {

                    //todo qiniu  code

                }elseif(config('FILE_UPLOAD_TYPE') == 'Local') {
                    $return_img['state'] = 'SUCCESS';
                    // $return_img['url']   = ROOT_PATH . 'public' . DS . "ueditor" . DS . $date . DS;
                    $return_img['url']   = 'http://' . $_SERVER['HTTP_HOST'] . DS . 'public' . DS . "ueditor" . DS . $date . DS . $file;
                    array_push($list, $return_img);
                }
            } else {
                $return_img['state'] = $this->stateMap['ERROR_WRITE_CONTENT'];
                array_push($list, $return_img);
            }
        }

        return json_encode([
            'state' => count($list) ? 'SUCCESS' : 'ERROR',
            'list'  => $list
        ]);
    }

另外,这里使用还有两个点需要注意:

如果发现这个方法不存在:cmf_file_write
请自己新建一个方法。

请在配置里面加上

'FILE_UPLOAD_TYPE' => 'Local'

ok.希望有朋友可以用上


评论

暂时关闭,稍后恢复~
文档请看10遍以上!有问题可加QQ群!
发表话题

源素材推荐

提问必知

0.话题发布后没及时显示,请联系官方QQ群管理;
1.话题支持代码,qq截屏直接粘贴,和QQ群一样;
2.问题描述清,比如服务器版本,程序版本;
3.能上代码,就不用文字;
4.把问题发到话题后再发QQ群;
5.如果感觉回复者解答的不错,可以发红包!
6.多帮助别人也是对自己的锻炼!
7.付费讨论中只有提问者和付费用户才可以查看回复

积分规则

1.评论积分+1;每天最多10次奖励
2.发布话题积分+1;每天最多5次奖励
3.垃圾评论积分-500;
4.黄色,暴力,违反我国法律评论直接封号


ThinkCMF 8.0.0发布啦!祝大家节日快乐! 立即体验!