支付宝支付线上报错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); }

浙公网安备 33010602011771号