2023年1月

升级PHP7之后微信公众号开发遇到的几个问题

由于微信公众号官方给出的示例代码都是比较老旧的,基本支持的都是PHP5.6以前的版本。如果将PHP版本升级到PHP7,那么代码无法正常运行,大概有下面几个问题:

一、$GLOBALS["HTTP_RAW_POST_DATA"] 失效

原因:经过在网上查询发现 PHP >= 5.6 的时候 HTTP_RAW_POST_DATA 被移除了。但是 PHP = 5.6 还可以在配置文件 php.ini 还能找到 always_populate_raw_post_data 选项。当 PHP >= 7.0 就已经彻底移除了 always_populate_raw_post_data 配置。
解决方案:使用file_get_contents('php://input');代替。

二、提示构造函数deprecated

原因:自 PHP 5.3.3 起,在命名空间中,与类名同名的方法不再作为构造函数。不使用命名空间中的类则不受影响。
解决方案:修改pkcs7Encoder.phpwxBizMsgCrypt.php两个文件中的构造函数,使用__construct即可。

三、mcrypt_module_open函数报错

原因:在 PHP7mcrypt_module_open()已经被 OPENSSL 取代。
解决方案:修改pkcs7Encoder.php文件中Prpcrypt类的encryptdecrypt方法,重点是使用openssl_encryptopenssl_decrypt代替mcrypt_开头的函数。为避免表达不清楚,将代码贴在下面。

public function encrypt($text, $appid)
{

    try {
        // 获得16位随机字符串,填充到明文之前
        $random = $this->getRandomStr();
        $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);
// 下面这句是重点,使用openssl方法
        $encrypted = openssl_encrypt($text, 'AES-256-CBC', $this->key, OPENSSL_ZERO_PADDING, $iv);
//         mcrypt_generic_deinit($module);
//         mcrypt_module_close($module);

        //print(base64_encode($encrypted));
        //使用BASE64对加密后的字符串进行编码
//         return array(ErrorCode::$OK, base64_encode($encrypted));
        return array(ErrorCode::$OK, $encrypted);
    } catch (Exception $e) {
        //print $e;
        return array(ErrorCode::$EncryptAESError, null);
    }
}

// 只截取了一部分
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);
        $decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', $this->key, OPENSSL_ZERO_PADDING, $iv);
    } catch (Exception $e) {
        return array(ErrorCode::$DecryptAESError, null);
    }
...