얼마 전 샤오미에서 푸시한 일부 코드가 마이그레이션되었습니다. 이 부분은 이전에는 다른 사람의 책임이었습니다. 코드를 읽은 후 두 가지 점을 발견했습니다.
URL 및 매개변수 전송을 제외하면 모든 인터페이스의 구현은 기본적으로 동일합니다.
Android 및 iOS 기기는 별도로 한 번 푸시해야 합니다
이때 막 PHP에서의 오버로딩 개념에 대해 배웠습니다. [타입과 메소드를 동적으로 생성하는데, 이는 Java 등에서 다른 매개변수를 사용하여 다른 메소드 이름을 갖는 개념과 다릅니다. 구체적인 개념은 RTFM이 될 수 있습니다.]
위의 첫 번째 사항에 대해: PHP의 오버로딩 개념을 사용하고 매직 메서드 __call()을 사용하여 URL 매개 변수와 호출 매개 변수를 동적으로 변경할 수 있습니까? Xiaomi가 푸시한 다양한 인터페이스에 대한 호출을 구현하기 위한 인터페이스, 즉 모든 호출 로직이 __call 메서드에서 구현된다고 하지만 Xiaomi가 푸시한 다양한 인터페이스에 대한 외부 호출 메서드를 제공합니다.
위의 두 번째 사항에 대해: 컬의 병렬 방법을 사용하여 Android 및 iOS 장치에 동시에 푸시하는 것이 가능합니까? 이론적으로는 더 이상 푸시를 기다릴 필요가 없기 때문에 푸시 호출 시간을 줄일 수 있습니다. 한 유형의 장치에 완료하기 전에 다른 유형의 장치로 푸시
다음으로 코드 작성을 시작합니다. 먼저, mipush 엔터티를 구성합니다. 엔터티의 멤버 속성에는 실행 환경, 일부 초기화된 구성 매개변수, 구현된 Xiaomi 인터페이스에 대한 정보(인터페이스 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' ], ] ], ];
구성 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: 매개변수 확인 및 Xiaomi 푸시 인터페이스 호출을 동적으로 구현하여 새로운 Xiaomi 푸시 인터페이스를 구현할 수 있습니다. 향후 구현을 구성하기만 하면 됩니다.
/** * 魔术方法 * * 重载对象方法 * @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); } }
Xiaomi 푸시 엔터티를 정의한 후에는 mipush 엔터티를 사용하여 다양한 장치 유형의 개체를 인스턴스화하고 생성한 다음 컬을 사용하여 병렬로 푸시를 시작하면 됩니다.
/** * 并行推送 * * @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; }
위 방법을 통해 아주 적은 코드로 Xiaomi SDK를 캡슐화했습니다. 현재는 regid(등록 ID), alias(별칭), user_account(사용자 계정), 주제(라벨), multi_topic(여러 라벨), 모두(모두) 푸시.
사용방법은?
아직 packagist에 올리지 않았는데요. 관심 있는 학생들은 직접 구글링해보시면 됩니다 ㅎㅎ
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(); }