• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

利用php重载和curl的并行方式优雅的封装小米推送sdk

php 搞代码 3年前 (2022-01-23) 32次浏览 已收录 0个评论

前段时间迁移小米推送部分代码,这部分之前是其他人负责的。读了代码,发现了两点:

所有接口的实现除了url和传参基本都是一致的

android和ios的设备需要分别推送一次

刚好这段时间了解了一下php的重载概念【动态的创建类属型和方法,不同于java等的参数不同方法名相通的概念,具体的概念可以RTFM】和curl的并发方式,所以

对于以上第一点:是否可以利用php的重载概念,用魔术方法__call()动态的变更接口调用的url参数和请求参数,去实现对小米推送不同接口的调用,也就是说我们所有的调用逻辑都是实现在__call这一个方法中,却对外提供小米推送不同接口的调用方法,这样就会极大的简化代码

对于以上第二点:是否可以利用curl的并行方式一次性推送给android和ios设备,这样理论上我们可以减少一次推送调用的时间,因为我们不需要再去等待给一类设备推送完了,再去推送给另一类设备

接下来,我们开始造代码。首先,构造一个mipush的实体,实体的成员属性包括:运行环境、初始化的一些配置参数、所实现的小米接口的信息(接口uri和参数等)

    /**     * 运行环境 develop:开发环境 product:生产环境     * @var string     */    private $_environment = 'develop';    /**     * 设备系统类型 android ios     * @var string     */    private $_osType      = '';    /**     * 小米推送域名     * @var string     */    private $_host        = '';    /**     * 请求头     * @var string     */    private $_headers     = '';    /**     * 接口url     * @var string     */    private $_url         = '';    /**     * 调用的接口方法名称     * @var array     */    private $_function    = [];    /**     * 请求参数     * @var array     */    private $_data        = [];    /**     * 小米推送设置     * @var array     */    private $_options = [        'title'                   => '消息通知自定义title',        'restricted_package_name' => '',        'pass_through'            => 0, // 0 通知栏消息 1 透传        'notify_type'             => -1, // -1:默认所有,1:使用默认提示音提示,2:使用默认震动提示,4:使用默认led灯光提示        'time_to_send'             => 0, // 定时推送 单位毫秒 默认0    ];    /**     * 运行环境配置     * @var array     */    private static $_environmentConfig = [        'domain' => [            'product'  => 'https://api.xmpush.xiaomi.com/',            'develop'  => 'https://sandbox.xmpush.xiaomi.com/'        ],    ];    /**     * 小米推送接口信息定义     *      * url/请求参数     * @var array     */    private $_functionDefine = [        'regid' => [            'uri' => 'v3/message/regid',            'arguments' => [                'registration_id' => [                    'type' => 'array',                    'must' => 'y'                ],                'description' => [                    'type' => 'string',                    'must' => 'y'                ],                'params' => [//自定义参数                    'type' => 'array',                    'must' => 'n'                ],            ]        ],        'userAccount' => [            'uri' => 'v2/message/user_account',            'arguments' => [                'user_account' => [                    'type' => 'array',                    'must' => 'y'                ],                'description' => [                    'type' => 'string',                    'must' => 'y'                ],                'params' => [//自定义参数                    'type' => 'array',                    'must' => 'n'                ],            ]        ],        'alias' => [            'uri' => 'v3/message/alias',            'arguments' => [                'alias' => [                    'type' => 'array',                    'must' => 'y'                ],                'description' => [                    'type' => 'string',                    'must' => 'y'                ],                'params' => [//自定义参数                    'type' => 'array',                    'must' => 'n'                ],            ]        ],        'topic' => [            'uri' => 'v3/message/topic',            'arguments' => [                'topics' => [                    'type' => 'array',                    'must' => 'y'                ],                'description' => [                    'type' => 'string',                    'must' => 'y'                ],                'params' => [//自定义参数                    'type' => 'array',                    'must' => 'n'                ],            ]        ],        'multiTopic' => [            'uri' => 'v3/message/multi_topic',            'arguments' => [                'topics' => [                    &#39<div>……本2文来源gaodai.ma#com搞##代!^码@网3</div><code>搞代gaodaima码</code>;type' => 'array',                    'must' => 'y'                ],                'topics_op' => [// UNION并集,INTERSECTION交集,EXCEPT差集                    'type' => 'string',                    'must' => 'y'                ],                'description' => [                    'type' => 'string',                    'must' => 'y'                ],                'params' => [//自定义参数                    'type' => 'array',                    'must' => 'n'                ],            ]        ],        'all' => [            'uri' => 'v3/message/all',            'arguments' => [                'description' => [                    'type' => 'string',                    'must' => 'y'                ],                'params' => [//自定义参数                    'type' => 'array',                    'must' => 'n'                ],            ]        ],    ];

mipush实体的构造函数:实现对一系列配置的初始化

/**     * 初始化配置     *      * @param $string $os_type 系统类型     * @param $string $config  配置     * @param array   $options 设置 [     *                        'title'        => 'string,标题',      *                        'pass_through' => 'tinyint,0通知栏消息,1透传,默认0'     *                        'notify_type'  => 'tinyint,-1,1,2,3,4',     *                        'time_to_send' => 'int, 定时推送, 毫秒'     *                        ]     * @param string  $environment 环境     */    public function __construct($os_type='', $config=array(), $options=array(), $environment='')    {        /* init environment */        if ($environment) {            $this->_environment = $environment;        }        if ($os_type === 'ios') {            $this->_host     = self::$_environmentConfig['domain'][$this->_environment];// ios        }else{            $this->_host     = self::$_environmentConfig['domain']['product'];// android        }                /* init option */        $this->_headers   = [];        $this->_headers[] = 'Authorization: key=' . $config['secret'];        if ($os_type === 'android') {            $this->_options['restricted_package_name'] = $config['package_name'];        }        foreach ($this->_options as $k => &$v) {            if (in_array($k, $options)) {                $v = $options[$k];            }        }    }

mipush实体的魔法方法__call:动态实现对小米推送接口的参数验证和调用,以至于我们未来实现新的小米推送接口及实现配置就可以。

/**     * 魔术方法     *      * 重载对象方法     * @param  string $name      小米推送方法名称     * @param  array  $arguments 请求参数     * @return mixed             void||object     */    public function __call($name,$arguments)    {        $arguments = $arguments[0];        $this->_function = $this->_functionDefine[$name];        $this->_url = $this->_host . $this->_function['uri'];        $this->dataCheck($arguments);        switch ($name) {            case 'regid':                $this->_data['registration_id'] = $arguments['registration_id'];                break;            case 'userAccount':                $this->_data['user_account'] = implode(',', $arguments['user_account']);                break;            case 'alias':                $this->_data['alias']        = implode(',', $arguments['alias']);                break;            case 'topic':                $this->_data['topic']        = $arguments['topic'];                break;            case 'multiTopic':                $this->_data['topics']       = implode(";$;", $arguments['topics']);                $this->_data['topic_op']     = $arguments['topic_op'];                break;            case 'all':                $this->_data['topics']       = implode(";$;", $topics);                $this->_data['topic_op']     = 'UNION';                break;                                default:                throw new \Exception('Sorry, This function is useless in this version', 404);                break;        }        $this->_data['description']  = $arguments['description'];        if($arguments['params']) {            foreach ($arguments['params'] as $k => $v) {                $this->_data['extra.'.$k] = $v;// 自定义参数            }        }        if ($this->_osType === 'android') {            $this->_data = array_merge($this->_data, $this->_options);        }    }

定义完小米推送实体后,我们只需要通过mipush这个实体,实例化生产不同设备类型的对象,再由curl并行的方式发起推送即可。

/**     * 并行推送     *      * @param  Mipush $mipush_ios     ios端实体     * @param  Mipush $mipush_android android端实体     * @return array                  推送结果     */    private static function curlRequest(Mipush $mipush_ios, Mipush $mipush_android)     {        $ch_ios     = curl_init();        $ch_android = curl_init();        curl_setopt($ch_ios, CURLOPT_URL, $mipush_ios->_url);        curl_setopt($ch_ios, CURLOPT_POST, 1);        curl_setopt($ch_ios, CURLOPT_POSTFIELDS, $mipush_ios->_data);        curl_setopt($ch_ios, CURLOPT_HTTPHEADER, $mipush_ios->_headers);        curl_setopt($ch_ios, CURLOPT_RETURNTRANSFER, 1);                 curl_setopt($ch_android, CURLOPT_URL, $mipush_android->_url);        curl_setopt($ch_android, CURLOPT_POST, 1);        curl_setopt($ch_android, CURLOPT_POSTFIELDS, $mipush_android->_data);        curl_setopt($ch_android, CURLOPT_HTTPHEADER, $mipush_android->_headers);        curl_setopt($ch_android, CURLOPT_RETURNTRANSFER, 1);                 $mh = curl_multi_init();        curl_multi_add_handle($mh, $ch_ios);        curl_multi_add_handle($mh, $ch_android);        $running=null;        do {           curl_multi_exec($mh,$running);        } while($running > 0);        $result['ios']        = json_decode(curl_multi_getcontent($ch_ios), true);        $result['android'] = json_decode(curl_multi_getcontent($ch_android), true);        curl_multi_remove_handle($mh, $ch_ios);        curl_multi_remove_handle($mh, $ch_android);        curl_multi_close($mh);        return $result;    }

以上就是这些了,通过以上的方式我们就用很少的代码封装了一个小米sdk,目前只实现了按regid(登记id),alias(别名),user_account(用户账号),topic(标签), multi_topic(多标签),all(全体)推送。

如何使用?

还没发布过packagist,我把这个发布到了packagist,有兴趣的同学可以自行google,haha~

composer require tigerb/easy-mipush使用格式:try {    Push::init(        ['secret' => 'string,必传,ios密钥'],         ['secret' => 'string,必传,android密钥', 'package_name' => 'string,必传,android包名']        [             'title'        => 'string,非必传,消息通知自定义title',          'pass_through' => 'int,非必传,0通知栏消息,1透传,默认0',          'notify_type'  => 'int,非必传,-1:默认所有,1:使用默认提示音提示,2:使用默认震动提示,4:使用默认led灯光提示',          'time_to_send' => 'int,非必传,定时推送,单位毫秒,默认0',        ],        'string,develop开发环境,product生产环境, 默认develop'        );      $res = Push::toUse('string,小米push方法名', 'array, 该方法对应的参数');    echo json_encode($res, JSON_UNESCAPED_UNICODE);} catch (Exception $e) {    echo $e->getMessage();}使用示例:use Mipush\Push;require './vendor/autoload.php';try {    Push::init(        ['secret' => 'test'],         ['secret' => 'test', 'package_name' => 'com.test'],        [             'title'        => 'test',          'pass_through' => 0,          'notify_type'  => -1,          'time_to_send' => 0,        ],        'develop'        );      $res = Push::toUse('userAccount', [            'user_account' => [1],            'description'  => 'test'        ]);    echo json_encode($res, JSON_UNESCAPED_UNICODE);} catch (Exception $e) {    echo $e->getMessage();}

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:利用php重载和curl的并行方式优雅的封装小米推送sdk

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址