PHP trait使用思考

20-04-10 13:27 字数 51 阅读 932 已编辑
  • 场景

yii2集成阿里云短信和OSS,定义了两个类:AliyunSms,AliyunOss,部分代码如下

<?php
namespace common\components;
use common\traits\SdkConfig;
use OSS\OssClient;
use Yii;
use yii\base\Component;
use yii\base\InvalidArgumentException;
use OSS\Model\BucketInfo;
use OSS\Core\OssException;
class AliyunOss extends Component
{
    use SdkConfig;

    /**
     * @var OssClient
     */
    private static $oss;

    public function __construct()
    {
        parent::__construct();
        $this->checkConfig(Yii::$app->params);
        self::$oss = new OssClient(
            $this->config('accessKeyId'),
            $this->config('accessKeySecret'),
            $this->config('endPoint')
        );
    }

    /**
     * 创建存储空间
     * @param string $bucket 存储空间名称
     */
    public function createBucket(string $bucket)
    {
        if (!$bucket) {
            throw new InvalidArgumentException('存储空间名称不为空');
        }
        // 设置存储空间的权限为公共读,默认是私有读写
        self::$oss->createBucket($bucket, OssClient::OSS_ACL_TYPE_PUBLIC_READ);
    }

    /**
     * 列举存储空间
     * @return BucketInfo[]
     * @throws OssException
     */
    public function listBuckets()
    {
        return self::$oss->listBuckets()->getBucketList();
    }

    /**
     * 字符串上传
     * @param string $object  保存到oss的文件名
     * @param string $content 文件内容
     * @return string
     */
    public function putObject(string $object, string $content)
    {
        $bucket = $this->config('bucket');
        $ret = self::$oss->putObject($bucket, $object, $content);
        return $ret['oss-request-url'];
    }
}
  • 需求 两个类都需要校验sdk必需配置参数的方法。
  • 思路 使用trait剥离关于配置的方法,减少冗余。
  • 实现
<?php
namespace common\traits;
use common\components\AliyunOss;
use common\components\AliyunSms;
use yii\base\InvalidArgumentException;
trait SdkConfig
{
    /**
     * @var array sdk配置
     */
    private $configs;

    /**
     * @var array sdk需要的配置
     */
    private $requiredConfigs;

    /**
     * @var string sdk简称
     */
    private $service;

    /**
     * @var string sdk中文名
     */
    private $serviceName;

    /**
     * 配置初始化
     */
    private function configInit()
    {
        switch (__CLASS__) {
            case AliyunOss::class:
                $this->requiredConfigs = ['accessKeyId', 'accessKeySecret', 'bucket', 'endPoint'];
                $this->service = 'oss';
                $this->serviceName = '对象存储';
                break;
            case AliyunSms::class:
                $this->requiredConfigs = ['accessKeyId', 'accessKeySecret', 'SignName', 'TemplateCode'];
                $this->service = 'sms';
                $this->serviceName = '短信';
                break;
        }
    }

    /**
     * 检查配置
     * @param array $configs
     */
    public function checkConfig(array $configs)
    {
        $this->configInit();
        if (!isset($configs[$this->service])) {
            throw new InvalidArgumentException(sprintf('缺少%s配置', $this->serviceName));
        }
        foreach ($this->requiredConfigs as $requiredConfig) {
            if (!in_array($requiredConfig, array_keys($configs[$this->service]))) {
                throw new InvalidArgumentException(sprintf('%s配置缺少:%s', $this->serviceName, $requiredConfig));
            }
        }
        $this->configs = $configs[$this->service];
    }

    /**
     * 获取配置
     * @param string $name
     * @param null $default
     * @return mixed|null
     */
    public function config(string $name, $default = null)
    {
        if (isset($this->configs[$name])) {
            return $this->configs[$name];
        }
        return $default;
    }
}
1人点赞>
关注 收藏 改进 举报
2 条评论
排序方式 时间 投票
kittyfamous

写的赞下,漂亮。

Up骚年

更新了文章排版

请登录后发表评论