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

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

Oct 15, 2016 pm 04:27 PM

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

所有接口的实现除了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' => [
                    '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'
                ],
            ]
        ],
    ];
Salin selepas log masuk

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];
            }
        }
    }
Salin selepas log masuk

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);
        }
    }
Salin selepas log masuk

定义完小米推送实体后,我们只需要通过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;
    }
Salin selepas log masuk

以上就是这些了,通过以上的方式我们就用很少的代码封装了一个小米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();
}
Salin selepas log masuk


Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

Video Face Swap

Video Face Swap

Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)