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(); }