diff --git a/qywechat.class.php b/qywechat.class.php index b9198bf..1b63f2c 100644 --- a/qywechat.class.php +++ b/qywechat.class.php @@ -272,7 +272,11 @@ private function http_post($url,$param,$post_file=false){ curl_setopt($oCurl, CURLOPT_URL, $url); curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt($oCurl, CURLOPT_POST,true); + if(PHP_VERSION_ID >= 50500){ + curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, FALSE); + } curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST); + $sContent = curl_exec($oCurl); $aStatus = curl_getinfo($oCurl); curl_close($oCurl); diff --git a/test/test-upload-shake-around-media.php b/test/test-upload-shake-around-media.php new file mode 100644 index 0000000..c063ea6 --- /dev/null +++ b/test/test-upload-shake-around-media.php @@ -0,0 +1,13 @@ + '', //填写高级调用功能的app id, 请在微信开发模式后台查询 + 'appsecret' => '', //填写高级调用功能的密钥 + ); + $weObj = new Wechat($options); + $weObj->uploadShakeAroundMedia(array('media'=>'@')); \ No newline at end of file diff --git a/wechat.class.php b/wechat.class.php index 78df628..20af647 100755 --- a/wechat.class.php +++ b/wechat.class.php @@ -52,6 +52,7 @@ class Wechat const MSGTYPE_NEWS = 'news'; const MSGTYPE_VOICE = 'voice'; const MSGTYPE_VIDEO = 'video'; + const MSGTYPE_SHORTVIDEO = 'shortvideo'; const EVENT_SUBSCRIBE = 'subscribe'; //订阅 const EVENT_UNSUBSCRIBE = 'unsubscribe'; //取消订阅 const EVENT_SCAN = 'SCAN'; //扫描带参数二维码 @@ -1128,7 +1129,24 @@ private function http_post($url,$param,$post_file=false){ curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 } - if (is_string($param) || $post_file) { + if (PHP_VERSION_ID >= 50500 && class_exists('\CURLFile')) { + $is_curlFile = true; + } else { + $is_curlFile = false; + if (defined('CURLOPT_SAFE_UPLOAD')) { + curl_setopt($oCurl, CURLOPT_SAFE_UPLOAD, false); + } + } + if (is_string($param)) { + $strPOST = $param; + }elseif($post_file) { + if($is_curlFile) { + foreach ($param as $key => $val) { + if (substr($val, 0, 1) == '@') { + $param[$key] = new \CURLFile(realpath(substr($val,1))); + } + } + } $strPOST = $param; } else { $aPOST = array(); @@ -1351,48 +1369,7 @@ public function getCardSign($card_type='',$card_id='',$code='',$location_id='',$ * @param array $arr */ static function json_encode($arr) { - if (count($arr) == 0) return "[]"; - $parts = array (); - $is_list = false; - //Find out if the given array is a numerical array - $keys = array_keys ( $arr ); - $max_length = count ( $arr ) - 1; - if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //See if the first key is 0 and last key is length - 1 - $is_list = true; - for($i = 0; $i < count ( $keys ); $i ++) { //See if each key correspondes to its position - if ($i != $keys [$i]) { //A key fails at position check. - $is_list = false; //It is an associative array. - break; - } - } - } - foreach ( $arr as $key => $value ) { - if (is_array ( $value )) { //Custom handling for arrays - if ($is_list) - $parts [] = self::json_encode ( $value ); /* :RECURSION: */ - else - $parts [] = '"' . $key . '":' . self::json_encode ( $value ); /* :RECURSION: */ - } else { - $str = ''; - if (! $is_list) - $str = '"' . $key . '":'; - //Custom handling for multiple data types - if (!is_string ( $value ) && is_numeric ( $value ) && $value<2000000000) - $str .= $value; //Numbers - elseif ($value === false) - $str .= 'false'; //The booleans - elseif ($value === true) - $str .= 'true'; - else - $str .= '"' . addslashes ( $value ) . '"'; //All other things - // :TODO: Is there any more datatype we should be in the lookout for? (Object?) - $parts [] = $str; - } - } - $json = implode ( ',', $parts ); - if ($is_list) - return '[' . $json . ']'; //Return numerical JSON - return '{' . $json . '}'; //Return associative JSON + return json_encode($arr,JSON_UNESCAPED_UNICODE); } /** @@ -3996,7 +3973,7 @@ public function bindPageShakeAroundDevice($device_id,$page_ids=array(),$bind=1,$ */ public function uploadShakeAroundMedia($data){ if (!$this->access_token && !$this->checkAuth()) return false; - $result = $this->http_post(self::API_URL_PREFIX.self::SHAKEAROUND_MATERIAL_ADD.'access_token='.$this->access_token,$data,true); + $result = $this->http_post(self::API_BASE_URL_PREFIX.self::SHAKEAROUND_MATERIAL_ADD.'access_token='.$this->access_token,$data,true); if ($result) { $json = json_decode($result,true); @@ -4578,7 +4555,7 @@ function encode($text) //计算需要填充的位数 $amount_to_pad = PKCS7Encoder::$block_size - ($text_length % PKCS7Encoder::$block_size); if ($amount_to_pad == 0) { - $amount_to_pad = PKCS7Encoder::block_size; + $amount_to_pad = PKCS7Encoder::$block_size; } //获得补位所用的字符 $pad_chr = chr($amount_to_pad); @@ -4627,89 +4604,63 @@ function Prpcrypt($k) $this->key = base64_decode($k . "="); } - /** - * 对明文进行加密 - * @param string $text 需要加密的明文 - * @return string 加密后的密文 - */ - public function encrypt($text, $appid) - { - - try { - //获得16位随机字符串,填充到明文之前 - $random = $this->getRandomStr();//"aaaabbbbccccdddd"; - $text = $random . pack("N", strlen($text)) . $text . $appid; - // 网络字节序 - $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC); - $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); - $iv = substr($this->key, 0, 16); - //使用自定义的填充方式对明文进行补位填充 - $pkc_encoder = new PKCS7Encoder; - $text = $pkc_encoder->encode($text); - mcrypt_generic_init($module, $this->key, $iv); - //加密 - $encrypted = mcrypt_generic($module, $text); - mcrypt_generic_deinit($module); - mcrypt_module_close($module); - - // print(base64_encode($encrypted)); - //使用BASE64对加密后的字符串进行编码 - return array(ErrorCode::$OK, base64_encode($encrypted)); - } catch (Exception $e) { - //print $e; - return array(ErrorCode::$EncryptAESError, null); - } + /** + * 对明文进行加密 + * @param string $text 需要加密的明文 + * @return string 加密后的密文 + */ + public function encrypt($text, $appid){ + try { + //获得16位随机字符串,填充到明文之前 + $random = $this->getRandomStr(); + $text = $random . pack("N", strlen($text)) . $text . $appid; + $iv = substr($this->key, 0, 16); + $pkc_encoder = new PKCS7Encoder; + $text = $pkc_encoder->encode($text); + $encrypted = openssl_encrypt($text,'AES-256-CBC',substr($this->key, 0, 32),OPENSSL_ZERO_PADDING,$iv); + return array(ErrorCode::$OK, $encrypted); + } catch (Exception $e) { + //print $e; + return array(ErrorCode::$EncryptAESError, null); } - - /** - * 对密文进行解密 - * @param string $encrypted 需要解密的密文 - * @return string 解密得到的明文 - */ - public function decrypt($encrypted, $appid) - { - - try { - //使用BASE64对需要解密的字符串进行解码 - $ciphertext_dec = base64_decode($encrypted); - $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); - $iv = substr($this->key, 0, 16); - mcrypt_generic_init($module, $this->key, $iv); - //解密 - $decrypted = mdecrypt_generic($module, $ciphertext_dec); - mcrypt_generic_deinit($module); - mcrypt_module_close($module); - } catch (Exception $e) { - return array(ErrorCode::$DecryptAESError, null); - } - - - try { - //去除补位字符 - $pkc_encoder = new PKCS7Encoder; - $result = $pkc_encoder->decode($decrypted); - //去除16位随机字符串,网络字节序和AppId - if (strlen($result) < 16) - return ""; - $content = substr($result, 16, strlen($result)); - $len_list = unpack("N", substr($content, 0, 4)); - $xml_len = $len_list[1]; - $xml_content = substr($content, 4, $xml_len); - $from_appid = substr($content, $xml_len + 4); - if (!$appid) - $appid = $from_appid; - //如果传入的appid是空的,则认为是订阅号,使用数据中提取出来的appid - } catch (Exception $e) { - //print $e; - return array(ErrorCode::$IllegalBuffer, null); - } - if ($from_appid != $appid) - return array(ErrorCode::$ValidateAppidError, null); - //不注释上边两行,避免传入appid是错误的情况 - return array(0, $xml_content, $from_appid); //增加appid,为了解决后面加密回复消息的时候没有appid的订阅号会无法回复 - + } + /** + * 对密文进行解密 + * @param string $encrypted 需要解密的密文 + * @return string 解密得到的明文 + */ + public function decrypt($encrypted, $appid){ + try { + $iv = substr($this->key, 0, 16); + $decrypted = openssl_decrypt($encrypted,'AES-256-CBC',substr($this->key, 0, 32),OPENSSL_ZERO_PADDING,$iv); + } catch (Exception $e) { + return array(ErrorCode::$DecryptAESError, null); } - + try { + //去除补位字符 + $pkc_encoder = new PKCS7Encoder; + $result = $pkc_encoder->decode($decrypted); + //去除16位随机字符串,网络字节序和AppId + if (strlen($result) < 16) + return ""; + $content = substr($result, 16, strlen($result)); + $len_list = unpack("N", substr($content, 0, 4)); + $xml_len = $len_list[1]; + $xml_content = substr($content, 4, $xml_len); + $from_appid = substr($content, $xml_len + 4); + if (!$appid) + $appid = $from_appid; + //如果传入的appid是空的,则认为是订阅号,使用数据中提取出来的appid + } catch (Exception $e) { + //print $e; + return array(ErrorCode::$IllegalBuffer, null); + } + if ($from_appid != $appid) + return array(ErrorCode::$ValidateAppidError, null); + //不注释上边两行,避免传入appid是错误的情况 + return array(0, $xml_content, $from_appid); + //增加appid,为了解决后面加密回复消息的时候没有appid的订阅号会无法回复 + } /** * 随机生成16位字符串