天气应用收获总结

最近做了一款天气应用,看了前辈们的代码,学习到了不少的知识,特此记录下来。

1. 天气服务的接入

  天气有多个服务提供商,如果将service层的代码写死的话,那么当天气提供商变化的时候,service层的代码完全不能用,做不到灵活的替换。为了避免这种问题,采用了动态绑定的方法。

  目前是这样实现的:service->interface接口,interface接口可以在与具体的实现绑定在一起。

  优化的逻辑方法:加一个中间件,然后在中间件中加策略,调用工厂模式来实现需求。具体代码如下所示:

class FaceplusMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param $request
     * @param Closure $next
     * @return mixed
     * @throws AppExceptionsFaceplusParamException
     */
    public function handle($request, Closure $next)
    {
        $driver = $request->header('driver', 'hub_acs');

        app()->configure('faceplus');
        $config = config('faceplus');
        $strategy = array_get($config, $driver . '.strategy', []);
        $forwarding_driver = Util::tryMatchForwardingDriver($driver, $strategy);
        if ($forwarding_driver) {
            app()->bind(FaceContract::class, $forwarding_driver);
        } else {
            switch ($driver) {
                case 'hub_acs':
                    app()->bind(FaceContract::class, HubAcs::class);
                    break;
                case 'acs':
                    app()->bind(FaceContract::class, Acs::class);
                    break;
                case 'zhima':
                    app()->bind(FaceContract::class, Zhima::class);
                    break;
                default:
                    list($code, $message) = ParamException::INVALID_HEAD_DRIVER;
                    throw new ParamException($message, $code);
                    break;
            }
        }return $next($request);
    }
}

2. 图片剪裁

    public function cutImage($image, $width, $height)
    {
        $imageSrc = env('WEATHER_IMAGE_HOST_CDN', 'https://img.vipplusclub.com/') . $image; // 拼接图片完整的url
        $type = $this->getTypeOfImage($imageSrc); // 获取图片文件的后缀
        // 根据图片文件的后缀来调用获取图片的方法
        if ($type == 'png') {
            $sourceImg =imagecreatefrompng($imageSrc);
        }
        if ($type == 'jpeg' || $type = 'jpg') {
            $sourceImg = imagecreatefromjpeg($imageSrc);
        }
        // 针对图片进行剪裁
        $imageTemp = imagecreatetruecolor($width, $height); // 创建画板
        $color = imagecolorallocatealpha($imageTemp, 255, 255, 255, 0);
        list($width_src, $height_src) = getimagesize($imageSrc);
        imagecopyresized($imageTemp, $sourceImg, 0,0, 0,0, $width, $height, $width_src, $height_src);
        $timeStamp = time();
        $tmpFileName = '/tmp/weather_' . $timeStamp . '.jpg';
        imagejpeg($imageTemp, $tmpFileName);
        imagedestroy($imageTemp);
        $result = $this->uploadYunService($tmpFileName);
        @unlink($imageTemp);
        return $result;
    }

3. 图片和文字打水印

阿里云文档地址:https://helpcdn.aliyun.com/document_detail/44957.html

操作代码:

    protected function urlsafeB64encode($string)
    {
        $data = base64_encode($string);
        $data = str_replace(array('+','/','='), array('-','_',''), $data);
        return $data;
    }
    protected function displayStruct($struct)
    {
        $format = [];
        foreach ($struct as $k => $v) {
            $format[] = $k . '_' .$v;
        }
        return '/watermark,' . implode(',', $format);
    }
    protected function buildImageUrl($string, $x = 0, $y = 0, $g = 'se')
    {
        $base64Str = $this->urlsafeB64encode($string);
        $struct = [
            'g' => $g,
            'image' => $base64Str,
            'x' => $x,
            'y' => $y,
        ];
        return $this->displayStruct($struct);
    }

    protected function buildTextUrl($string, $size = 15, $x = 0, $y = 0, $color = '000000', $fontType = 'd3F5LXplbmhlaQ')
    {
        $base64Str = $this->urlsafeB64encode($string);
        $struct = [
            'type' => $fontType,
            'size' => $size,
            'text' => $base64Str,
            'x' => $x,
            'y' => $y,
            'color' => $color,
        ];
        return $this->displayStruct($struct);
    }
        $config = config('weather');
        $orig = env('IMAGE_HOST', 'http://vipplus-public-bucket.oss-cn-hangzhou.aliyuncs.com/') .
            array_get($config, 'menuCover') .
            array_get($config, 'menuCoverSuf');
        $areaUrl = $this->buildTextUrl($areaName, 30, 560, 1040, '2D3A50', 'ZmFuZ3poZW5naGVpdGk');

        $iconUrl = $this->buildImageUrl(
            array_get($currentWeather, 'wea_img_path'),
            380,
            160
        );
        //因为阿里云最多支持3组汉字
        $path = $orig.$areaUrl.$iconUrl;
        $image1 = imagecreatefromjpeg($path);
        $ttf = __DIR__.'/ttf/jian.ttf';
        $color = imagecolorallocatealpha($image1, 255, 255, 255, 0);
        imagettftext(
            $image1,
            30,
            0,
            50,
            1230,
            $color,
            $ttf,
            array_get($currentWeather, 'win') . ' ' . array_get($currentWeather, 'win_speed')
        );

4. 执行方法前先读缓存

    protected function handleCache($cacheKey, $funcName, $cityId)
    {
        if ($this->needCache) {
            $cacheData = $this->redisService->get($cacheKey);
            if (!empty($cacheData)) {
                return $cacheData;
            }
        }
        $return = $this->{$funcName}($cityId);
        if ($this->needCache) {
            $this->redisService->put($cacheKey, $return, $this->getCacheExpireMinute());
        }
        return $return;
    }
原文地址:https://www.cnblogs.com/cjjjj/p/10863607.html