Image.php 7.1 KB
<?php

namespace app\files\controller;

use think\Request;
use think\Response;
use think\Cache;

/**
 * 通用图片处理
 */
class Image {

    protected $request;
    protected $config;


    /**
     * 缓存前缀
     */
    const PREFIX = '_image_';
    const EXPIRE = 2592000;

    public function __construct(Request $request) {
        $this->request = $request;
        $this->config = config('upload_img');
    }

    /**
     * 输出返回数据
     * @access protected
     * @param mixed     $data 要返回的数据
     * @param String    $type 返回类型 JSON XML
     * @param integer   $code HTTP状态码
     * @return Response
     */
    protected function response($msg, $code = 200, $data = '', $type = 'json') {
        $result = [
            'code' => $code,
            'msg' => $msg,
            'data' => $data,
            '_link' => '',
        ];
        if ($data) {
            if (is_array($data)) {
                foreach ($data as $key => $value) {
                    $result['_link'][] = getFileUrl($value);
                }
            } else {
                $result['_link'] = getFileUrl($data);
            }
        }
        $header = ['x_end_time' => $this->request->time()];
        $response = Response::create($result, $type)->code($code)->header($header);
        throw new \think\exception\HttpResponseException($response);
    }

    /**
     * 显示资源列表
     *
     * @return \think\Response
     */
    public function index($sha1, $w = 0, $h = 0, $type = 3) {
        if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
            header("HTTP/1.1 304 Not Modified");
            exit;
        }
        $info = Cache::get(self::PREFIX . $sha1);
        if (empty($info)) {
            $info = db('picture')->where('sha1', $sha1)->find();
            if (empty($info)) {
                return $this->response('指定图片不存在!', 404);
            }
            Cache::set(self::PREFIX . $sha1, $info, self::EXPIRE);
        }
        $path = '../../' . $info['path'];
        if (!is_file($path)) {
//            db('picture')->delete($info['id']);
            return $this->response('指定图片已被系统删除!', 404,$path);
        }
        $content = '';
        $last_modified_time = gmdate(time() + ((30 * 60 * 60 * 24))) . " GMT";
        $header = str_replace(['%Expires%', "%etag%", '%Last-Modified%'], [$last_modified_time, $sha1 . ':' . $w . '_' . $h . '_' . $type, $last_modified_time], $this->config['header_cache']);
        if ($w > 0 && $h > 0) {
            $path = $this->cacheImage($info, $w, $h, $type);
            $content = file_get_contents($path);
            $header['Content-Length'] = strlen($content);
        } else {
            $content = file_get_contents($path);
            $header['Content-Length'] = $info['size'];
        }
        return response($content, 200, $header);
    }

    /**
     * 生成缩略图缓存
     * @param type $info
     * @param type $w
     * @param type $h
     * @return string
     */
    private function cacheImage($info, $w, $h, $type = 1) {
        $cache = $this->config['cache'] . substr($info['sha1'], 0, 2) . DS . substr($info['sha1'], 2) . DS;
        $filename = $cache . $w . '_' . $h . '_' . $type;
        $this->_mkdir($cache);
        if (is_file($filename)) {
            return $filename;
        }
        $img = \think\Image::open('./.' . $info['path']);
        $img->thumb($w, $h, $type)->save($filename);
        return $filename;
    }

    /**
     * 创建目录
     * @param  string $savepath 要创建的穆里
     * @return boolean          创建状态,true-成功,false-失败
     */
    private function _mkdir($path) {
        if (is_dir($path)) {
            return true;
        }
        if (mkdir($path, 0755, true)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 图片上传
     */
    public function upload() {
        $files = $this->request->file($this->config['name']);
        if (empty($files)) {
            $this->response('没有上传的文件!', 400);
        }
        $type = $this->request->param('type', 'single');
        if ($type == 'multi') {
            return $this->multi($files);
        } else {
            return $this->single($files);
        }
    }

    /**
     * 单图片上传
     * @param type $file file对象
     * @return type
     */
    private function single($file) {
        if (is_array($file)) {
            $file = current($file);
        }
        if ($file->check($this->config['rule']) === false) {
            return $this->response($file->getError(), 400);
        }
        $info = db('picture')->where('sha1', $file->hash())->find();
        if (empty($info) || !is_file('./.' . $info['path'])) {
            if (isset($info['path']) && !is_file('./.' . $info['path'])) {
                db('picture')->delete($info['id']);
            }
            $res = $file->rule($this->config['savename'])->move(ROOT_PATH . $this->config['path']);
            if ($res === false) {
                return $this->response($file->getError(), 400);
            }
            $data = [
                'path' => $this->config['path'] . $res->getSaveName(),
                'create_time' => $this->request->time(),
                'sha1' => $res->hash(),
                'size' => $res->getSize(),
            ];
            if (isset($info['id'])) {
                $data['id'] = $info['id'];
                db('picture')->update($data);
                Cache::set(self::PREFIX . $data['sha1'], $info, self::EXPIRE);
            } else {
                db('picture')->insert($data);
            }
        }
        $this->response('上传成功!', 200, $file->hash());
    }

    /**
     * 多图片上传
     * @param type $files file对象集合
     * @return type
     */
    private function multi($files) {
        if (!is_array($files)) {
            $files = [$files];
        }
        $savedata = [];
        $data = [];
        foreach ($files as $file) {
            if ($file->check($this->config['rule']) === false) {
                return $this->response($file->getError(), 400);
            }
            $info = db('picture')->where('sha1', $file->hash())->find();
            if (empty($info) || !is_file('./.' . $info['path'])) {
                if (isset($info['path']) && !is_file('./.' . $info['path'])) {
                    db('picture')->delete($info['id']);
                }
                $res = $file->rule($this->config['savename'])->move(ROOT_PATH . $this->config['path']);
                if ($res === false) {
                    return $this->response($file->getError(), 400);
                }
                $savedata[] = [
                    'path' => $this->config['path'] . $res->getSaveName(),
                    'create_time' => $this->request->time(),
                    'sha1' => $res->hash(),
                    'size' => $res->getSize(),
                ];
            }
            $data[] = $file->hash();
        }
        if (!empty($savedata)) {
            db('picture')->insertAll($savedata);
        }
        $this->response('上传成功!', 200, $data);
    }

}