Heim >类库下载 >PHP类库 >Verwenden Sie die parallele Methode des PHP-Neuladens und Curl, um das Xiaomi Push SDK elegant zu kapseln

Verwenden Sie die parallele Methode des PHP-Neuladens und Curl, um das Xiaomi Push SDK elegant zu kapseln

高洛峰
高洛峰Original
2016-10-15 16:27:241701Durchsuche

Vor einiger Zeit wurde ein Teil des Xiaomi Push-Codes migriert. Dieser Teil lag zuvor in der Verantwortung anderer. Nachdem ich den Code gelesen hatte, entdeckte ich zwei Punkte:

Die Implementierung aller Schnittstellen ist bis auf die URL- und Parameterübertragung grundsätzlich gleich

Android- und iOS-Geräte müssen einmal separat gepusht werden

Während dieser Zeit habe ich gerade etwas über das Konzept der Überladung in PHP gelernt [dynamische Erstellung von Typen und Methoden, was sich vom Konzept unterschiedlicher Methodennamen mit unterschiedlichen Parametern in Java usw. unterscheidet. Das spezifische Konzept kann RTFM sein] und die Parallelitätsmethode von Curl, also

Zum ersten Punkt oben: Ist es möglich, das Überladungskonzept von PHP zu verwenden und die magische Methode __call() zu verwenden, um die von aufgerufenen URL-Parameter und Anforderungsparameter dynamisch zu ändern? Schnittstelle zum Implementieren von Aufrufen an verschiedene von Xiaomi gepushte Schnittstellen, das heißt, dass unsere gesamte Aufruflogik in der __call-Methode implementiert ist, aber wir stellen externe Aufrufmethoden für verschiedene von Xiaomi gepushte Schnittstellen bereit. Dies wird den Code erheblich vereinfachen >

Zum zweiten Punkt oben: Ist es möglich, mit der Parallelmethode von Curl gleichzeitig auf Android- und iOS-Geräte zu pushen, können wir theoretisch die Zeit eines Push-Aufrufs verkürzen, da wir nicht mehr auf den Push warten müssen

Als nächstes beginnen wir mit dem Schreiben von Code. Erstellen Sie zunächst eine Mipush-Entität. Zu den Mitgliedsattributen der Entität gehören: laufende Umgebung, einige initialisierte Konfigurationsparameter, Informationen über die implementierte Xiaomi-Schnittstelle (Schnittstellen-URI und Parameter usw.)

    /**
     * 运行环境 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'
                ],
            ]
        ],
    ];
Konstruktion der mipush-Entität Funktion: Implementiert die Initialisierung einer Reihe von Konfigurationen

/**
     * 初始化配置
     * 
     * @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];
            }
        }
    }
Die magische Methode der mipush-Entität __call: Implementiert dynamisch die Parameterüberprüfung und den Aufruf der Xiaomi-Push-Schnittstelle, sodass wir neue Xiaomi-Push-Schnittstellen implementieren können und Implementierungen in der Zukunft. Konfigurieren Sie es einfach.

/**
     * 魔术方法
     * 
     * 重载对象方法
     * @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);
        }
    }
Nachdem wir die Xiaomi-Push-Entität definiert haben, müssen wir nur noch die Mipush-Entität verwenden, um Objekte verschiedener Gerätetypen zu instanziieren und zu erzeugen, und dann Curl verwenden, um den Push parallel zu initiieren.

/**
     * 并行推送
     * 
     * @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;
    }
Das ist es. Mit der oben genannten Methode haben wir ein Xiaomi-SDK mit sehr wenig Code gekapselt. Derzeit implementieren wir nur regid (Registrierungs-ID), Alias ​​(Alias), user_account (Benutzerkonto). topic (Label), multi_topic (mehrere Labels), all (alle) Push.

Wie benutzt man?

Ich habe das noch nicht auf packagist gepostet. Interessierte Studenten können es selbst googeln, 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();
}


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

In Verbindung stehende Artikel

Mehr sehen