支付宝支付线上报错Optional parameter $n declared before required parameter $charset is implici

使用的是支付宝sdkv2,调起支付宝小程序支付。本地接口没问题,线上报错Optional parameter $n declared before required parameter $charset is implici。

根据报错提示是vendor/alipaysdk/openapi/v2/aop/AopClient.php,网上查了下,大致意思是因为php8以上版本会因为参数顺序问题导致报错。

查看代码以后发现,有些方法中带有默认值的参数在没有默认值参数前面,修改以后正常运行。

line 897 splitCN方法

function splitCN($cont, $n = 0, $subnum, $charset)
{
    //$len = strlen($cont) / 3;
    $arrr = array();
    for ($i = $n; $i < strlen($cont); $i += $subnum) {
        $res = $this->subCNchar($cont, $i, $subnum, $charset);
        if (!empty ($res)) {
            $arrr[] = $res;
        }
    }

    return $arrr;
}

line 911 subCNchar方法

 function subCNchar($str, $start = 0, $length, $charset = "gbk")
    {
        if (strlen($str) <= $length) {
            return $str;
        }
        $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("", array_slice($match[0], $start, $length));
        return $slice;
    }

调整下参数顺序,顺便在调用的地方修改下就可以了。

line 910 方法rsaDecrypt调用

  public function rsaDecrypt($data, $rsaPrivateKeyPem, $charset)
    {

        if ($this->checkEmpty($this->rsaPrivateKeyFilePath)) {
            //读字符串
            $priKey = $this->rsaPrivateKey;
            $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
                wordwrap($priKey, 64, "\n", true) .
                "\n-----END RSA PRIVATE KEY-----";
        } else {
            $priKey = file_get_contents($this->rsaPrivateKeyFilePath);
            $res = openssl_get_privatekey($priKey);
        }
        ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置');
        //转换为openssl格式密钥
        $decodes = explode(',', $data);
        $strnull = "";
        $dcyCont = "";
        foreach ($decodes as $n => $decode) {
            if (!openssl_private_decrypt($decode, $dcyCont, $res)) {
                echo "<br/>" . openssl_error_string() . "<br/>";
            }
            $strnull .= $dcyCont;
        }
        return $strnull;
    }

    function splitCN($cont, $n = 0, $subnum, $charset)
    {
        //$len = strlen($cont) / 3;
        $arrr = array();
        for ($i = $n; $i < strlen($cont); $i += $subnum) {
            $res = $this->subCNchar($cont, $i, $subnum, $charset);
            if (!empty ($res)) {
                $arrr[] = $res;
            }
        }

        return $arrr;
    }

line 852 调用splitCN

 public function rsaEncrypt($data, $rsaPublicKeyFilePath, $charset)
    {
        if ($this->checkEmpty($this->alipayPublicKey)) {
            //读取字符串
            $pubKey = $this->alipayrsaPublicKey;
            $res = "-----BEGIN PUBLIC KEY-----\n" .
                wordwrap($pubKey, 64, "\n", true) .
                "\n-----END PUBLIC KEY-----";
        } else {
            //读取公钥文件
            $pubKey = file_get_contents($rsaPublicKeyFilePath);
            //转换为openssl格式密钥
            $res = openssl_get_publickey($pubKey);
        }

        ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确');
        $blocks = $this->splitCN($data, 0, 30, $charset);
        $chrtext  = null;
        $encodes  = array();
        foreach ($blocks as $n => $block) {
            if (!openssl_public_encrypt($block, $chrtext , $res)) {
                echo "<br/>" . openssl_error_string() . "<br/>";
            }
            $encodes[] = $chrtext ;
        }
        $chrtext = implode(",", $encodes);

        return base64_encode($chrtext);
    }

 

posted @ 2025-06-24 18:44  秋江月  阅读(30)  评论(0)    收藏  举报