搜尋
首頁後端開發php教程PHP實現後端銀聯支付及退款實例詳解
PHP實現後端銀聯支付及退款實例詳解May 21, 2018 am 11:04 AM
php實例退款

本篇文章主要介紹PHP實作後端銀聯支付及退款實例詳解,有興趣的朋友參考下,希望對大家有幫助。

聲明:此文以當前銀聯官方最新SDK(2016-08-09 5.1.0版)進行說明,若出現包不相同的情況請檢查是否是此版本

#近期遇到銀聯支付以及相關退款(此文僅以手機控制支付作為前提)操作,下面會依次寫出期間遇到的問題以及基本流程,在此之前通過官方的一張圖片了解一個支付中,對於後端人員的我們需要做到的一些事

由此圖可以看出,後端在此負責1、平台訂單產生;2、銀聯全通路平台訂單推播;3、返回tn碼給前端支付;4、處理前台通知以及全通路平台的非同步通知。

此間難點有三,訂單推播、非同步通知處理、訂單狀態查詢。

透過官方的郵件說明下載相關的套件並放入後端php程式碼中,(支付控制項去下載你看到的估計只有IOS,安卓版的SDK,對於後端來說,隨便下載一個即可,PHP的程式碼在裡面都有放置);然後仔細閱讀SDK中的readme.txt文件,此後進行以下步驟:

一、相關參數配置

對接過程中使用在sdk的assets資料夾中測試環境設定檔及證書,放置到sdk資料夾中,並設定/sdk/SDKconfig.php檔案已正確的讀取acp_sdk.ini設定檔。

在acp_sdk.ini檔案中設定好acpsdk.signCert.path、acpsdk.encryptCert.path、acpsdk.rootCert.path、acpsdk.middleCert.path四個檔案的絕對位址(自訂檔案路徑即可)。

因專案開發過程中會出現系統不同或專案位址不同導致的憑證絕對位址等錯誤,尤其在實際生產環境中,極易出現專案部署檔案位址不同,不可能在開發後每次更新都要更換憑證位址,在此修改了一下SDK中的SDKconfig.php已相容於不同檔案位址較長,這裡也請點擊展開檢視

<?php
namespace com\unionpay\acp\sdk;;
include_once &#39;log.class.php&#39;;
include_once &#39;common.php&#39;;
 
class SDKConfig {
   
  private static $_config = null;
  public static function getSDKConfig(){
    if (SDKConfig::$_config == null ) {
      SDKConfig::$_config = new SDKConfig();
    }
    return SDKConfig::$_config;
  }
   
  private $frontTransUrl;
  private $backTransUrl;
  private $singleQueryUrl;
  private $batchTransUrl;
  private $fileTransUrl;
  private $appTransUrl;
  private $cardTransUrl;
  private $jfFrontTransUrl;
  private $jfBackTransUrl;
  private $jfSingleQueryUrl;
  private $jfCardTransUrl;
  private $jfAppTransUrl;
  private $qrcBackTransUrl;
  private $qrcB2cIssBackTransUrl;
  private $qrcB2cMerBackTransUrl;
   
  private $signMethod;
  private $version;
  private $ifValidateCNName;
  private $ifValidateRemoteCert;
   
  private $signCertPath;
  private $signCertPwd;
  private $validateCertDir;
  private $encryptCertPath;
  private $rootCertPath;
  private $middleCertPath;
  private $frontUrl;
  private $backUrl;
  private $secureKey;
  private $logFilePath;
  private $logLevel;
 
  function __construct(){
 
    //如果想把acp_sdk.ini挪到其他路径的话,请修改下面这行指定绝对路径。
    $configFilePath = dirname(__FILE__) . "/acp_sdk.ini";
    $certsFilePath = dirname(dirname(__FILE__)) . "/certs/";
     
    if(!file_exists($configFilePath)){
      $logger = LogUtil::getLogger();
      $logger->LogError("配置文件加载失败,文件路径:[" . $configFilePath . "].请检查启动php的用户是否有读权限。");
      return;
    }
    $ini_array = parse_ini_file($configFilePath, true);
    $sdk_array = $ini_array["acpsdk"];
    $this->frontTransUrl = array_key_exists("acpsdk.frontTransUrl", $sdk_array)?$sdk_array["acpsdk.frontTransUrl"] : null;
    $this->backTransUrl = array_key_exists("acpsdk.backTransUrl", $sdk_array)?$sdk_array["acpsdk.backTransUrl"] : null;
    $this->singleQueryUrl = array_key_exists("acpsdk.singleQueryUrl", $sdk_array)?$sdk_array["acpsdk.singleQueryUrl"] : null;
    $this->batchTransUrl = array_key_exists("acpsdk.batchTransUrl", $sdk_array)?$sdk_array["acpsdk.batchTransUrl"] : null;
    $this->fileTransUrl = array_key_exists("acpsdk.fileTransUrl", $sdk_array)?$sdk_array["acpsdk.fileTransUrl"] : null;
    $this->appTransUrl = array_key_exists("acpsdk.appTransUrl", $sdk_array)?$sdk_array["acpsdk.appTransUrl"] : null;
    $this->cardTransUrl = array_key_exists("acpsdk.cardTransUrl", $sdk_array)?$sdk_array["acpsdk.cardTransUrl"] : null;
    $this->jfFrontTransUrl = array_key_exists("acpsdk.jfFrontTransUrl", $sdk_array)?$sdk_array["acpsdk.jfFrontTransUrl"] : null;
    $this->jfBackTransUrl = array_key_exists("acpsdk.jfBackTransUrl", $sdk_array)?$sdk_array["acpsdk.jfBackTransUrl"] : null;
    $this->jfSingleQueryUrl = array_key_exists("acpsdk.jfSingleQueryUrl", $sdk_array)?$sdk_array["acpsdk.jfSingleQueryUrl"] : null;
    $this->jfCardTransUrl = array_key_exists("acpsdk.jfCardTransUrl", $sdk_array)?$sdk_array["acpsdk.jfCardTransUrl"] : null;
    $this->jfAppTransUrl = array_key_exists("acpsdk.jfAppTransUrl", $sdk_array)?$sdk_array["acpsdk.jfAppTransUrl"] : null;
    $this->qrcBackTransUrl = array_key_exists("acpsdk.qrcBackTransUrl", $sdk_array)?$sdk_array["acpsdk.qrcBackTransUrl"] : null;
    $this->qrcB2cIssBackTransUrl = array_key_exists("acpsdk.qrcB2cIssBackTransUrl", $sdk_array)?$sdk_array["acpsdk.qrcB2cIssBackTransUrl"] : null;
    $this->qrcB2cMerBackTransUrl = array_key_exists("acpsdk.qrcB2cMerBackTransUrl", $sdk_array)?$sdk_array["acpsdk.qrcB2cMerBackTransUrl"] : null;
 
    $this->signMethod = array_key_exists("acpsdk.signMethod", $sdk_array)?$sdk_array["acpsdk.signMethod"] : null;
    $this->version = array_key_exists("acpsdk.version", $sdk_array)?$sdk_array["acpsdk.version"] : null;
    $this->ifValidateCNName = array_key_exists("acpsdk.ifValidateCNName", $sdk_array)?$sdk_array["acpsdk.ifValidateCNName"] : "true";
    $this->ifValidateRemoteCert = array_key_exists("acpsdk.ifValidateRemoteCert", $sdk_array)?$sdk_array["acpsdk.ifValidateRemoteCert"] : "false";
 
    $this->signCertPath = $certsFilePath . (array_key_exists("acpsdk.signCert.path", $sdk_array)?$sdk_array["acpsdk.signCert.path"]: null);
    $this->signCertPwd = array_key_exists("acpsdk.signCert.pwd", $sdk_array)?$sdk_array["acpsdk.signCert.pwd"]: null;
     
    $this->validateCertDir = array_key_exists("acpsdk.validateCert.dir", $sdk_array)? $sdk_array["acpsdk.validateCert.dir"]: null;
    $this->encryptCertPath = $certsFilePath . (array_key_exists("acpsdk.encryptCert.path", $sdk_array)? $sdk_array["acpsdk.encryptCert.path"]: null);
    $this->rootCertPath = $certsFilePath . (array_key_exists("acpsdk.rootCert.path", $sdk_array)? $sdk_array["acpsdk.rootCert.path"]: null);
    $this->middleCertPath = $certsFilePath . (array_key_exists("acpsdk.middleCert.path", $sdk_array)?$sdk_array["acpsdk.middleCert.path"]: null);
     
    $this->frontUrl = array_key_exists("acpsdk.frontUrl", $sdk_array)?$sdk_array["acpsdk.frontUrl"]: null;
    $this->backUrl = array_key_exists("acpsdk.backUrl", $sdk_array)?$sdk_array["acpsdk.backUrl"]: null;
     
    $this->secureKey = array_key_exists("acpsdk.secureKey", $sdk_array)?$sdk_array["acpsdk.secureKey"]: null;
    $this->logFilePath = array_key_exists("acpsdk.log.file.path", $sdk_array)?$sdk_array["acpsdk.log.file.path"]: null;
    $this->logLevel = array_key_exists("acpsdk.log.level", $sdk_array)?$sdk_array["acpsdk.log.level"]: null;
     
  }
 
  public function __get($property_name)
  {
    if(isset($this->$property_name))
    {
      return($this->$property_name);
    }
    else
    {
      return(NULL);
    }
  } 
}

二、全通路商品訂單推送

相關程式碼請點選查看

##

use com\unionpay\acp\sdk\AcpService;
use com\unionpay\acp\sdk\LogUtil;
use com\unionpay\acp\sdk\SDKConfig;
 
  /**
   * 银联支付下单
   *
   * @param $orders
   * @param $orders_type
   * @return array
   */
  public function unionPay($orders, $orders_type = 0)
  {
    include_once dirname(dirname(dirname(__FILE__))) . &#39;/Model/unionpay-sdk/sdk/acp_service.php&#39;;
    $config = new SDKConfig();
    $AcpService = new AcpService();
    $log = LogUtil::getLogger();
    $time = date(&#39;YmdHis&#39;, time());
    $params = array(
 
      //以下信息非特殊情况不需要改动
      &#39;version&#39; => $config->getSDKConfig()->version,         //版本号
      &#39;encoding&#39; => &#39;utf-8&#39;,         //编码方式
      &#39;txnType&#39; => &#39;01&#39;,           //交易类型
      &#39;txnSubType&#39; => &#39;01&#39;,         //交易子类
      &#39;bizType&#39; => &#39;000201&#39;,         //业务类型
      &#39;frontUrl&#39; => $config->getSDKConfig()->frontUrl, //前台通知地址
      &#39;backUrl&#39; => $this->getURL(&#39;api_pay_unionpay_call_back&#39;),  //后台通知地址
      &#39;signMethod&#39; => $config->getSDKConfig()->signMethod,         //签名方法
      &#39;channelType&#39; => &#39;08&#39;,         //渠道类型,07-PC,08-手机
      &#39;accessType&#39; => &#39;0&#39;,        //接入类型
      &#39;currencyCode&#39; => &#39;156&#39;,      //交易币种,境内商户固定156
 
      //TODO 以下信息需要填写
      &#39;merId&#39; => $this->getParameter(&#39;mer_id&#39;),   //商户代码,请改自己的测试商户号
      &#39;orderId&#39; => $orders["order_no"],  //商户订单号,8-32位数字字母,不能含“-”或“_”
      &#39;txnTime&#39; => $time, //订单发送时间,格式为YYYYMMDDhhmmss,取北京时间
      &#39;txnAmt&#39; => $orders[&#39;total_price&#39;] * 100,  //交易金额,单位分
    );
 
    $AcpService->sign ( $params ); // 签名
    $url = $config->getSDKConfig()->appTransUrl;
 
    $result_arr = $AcpService->post ($params, $url);
 
    if(count($result_arr)<=0) { //没收到200应答的情况 $log->LogInfo(&#39;没收到200应答的情况&#39;);
    }
 
//    $this->printResult ($url, $params, $result_arr ); //页面打印请求应答数据
 
    if (!$AcpService->validate ($result_arr) ){
      $log->LogInfo(&#39;应答报文验签失败&#39;);
    }
    if ($result_arr["respCode"] == "00"){
      //成功
      return array(&#39;txn_time&#39;=>$time, &#39;tn&#39;=>$result_arr["tn"]);
//      echo "后续请将此tn传给手机开发,由他们用此tn调起控件后完成支付。
\n";
//      echo "手机端demo默认从仿真获取tn,仿真只返回一个tn,如不想修改手机和后台间的通讯方式,【此页面请修改代码为只输出tn】。
\n";
    } else {
      //其他应答码做以失败处理
      return array(&#39;txn_time&#39;=>$time, &#39;tn&#39;=>0);
      //echo "失败:" . $result_arr["respMsg"] . "。
\n";
 
    }
  }

#在此註意txnTime格式不要傳錯,測試環境下應該不會出現什麼問題,將得到的tn返回APP進行付款即可

三、非同步通知處理以及訂單交易狀態查詢

這一步主要作用為處理銀聯交易成功訊息,並盡可能避免回呼未處理導致問題。


先說非同步通知處理,此步驟為訂單狀態修改的主要依據。無實際困難,保證相關參數無問題即可

/**
   * 银联回调
   *
   * @param Request $request
   * @return array|Response
   */
  public function unionPayCallBackAction(Request $request)
  {
    if ($request->get(&#39;type&#39;) == 1){//前台通知-进行订单状态查询
      $query = $this->unionPayQuery($request, array(), 1);
 
      return new JsonResponse($query);
    }
 
    require_once dirname(dirname(dirname(__FILE__))) . "/Model/unionpay-sdk/sdk/acp_service.php";
    $log = LogUtil::getLogger();
    $AcpService = new AcpService();
 
 
    if ($request->request->has(&#39;signature&#39;) && $AcpService->validate($_POST)) {
      $order_no = $request->request->get(&#39;orderId&#39;);
      $respCode = $request->request->get(&#39;respCode&#39;);
      $total = $request->request->get(&#39;txnAmt&#39;); // 交易金额
      if ($respCode === &#39;00&#39; || $respCode === &#39;A6&#39;) {
        $trade_no = $request->request->get(&#39;origQryId&#39;)?:&#39;UN&#39; . date(&#39;YmdHis&#39;, time()) . substr(implode(NULL, array_map(&#39;ord&#39;, str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
        $this->dispose($order_no, $trade_no, 4);//订单交易处理-请根据实际情况自行编写
      }
    } else {
      if (!$request->request->has(&#39;signature&#39;)) {
        $log->LogInfo(&#39;签名为空&#39;);
      } else {
        $log->LogInfo(&#39;验签失败&#39;);
      }
    }
 
    exit;
  }

#訂單交易狀態查詢

   do{//循环查询,直到获取到退款订单的queryID
      sleep($number * 2);
      $query = $this->unionPayQuery(&#39;&#39;, $orders);
      $number += 1;
    }while($query[&#39;errorCode&#39;] != 0 || empty($query[&#39;result_arr&#39;]["queryId"]));
 
public function unionPayQuery($request, $orders)
  {
    require_once dirname(dirname(dirname(__FILE__))) . "/Model/unionpay-sdk/sdk/acp_service.php";
    $config = new SDKConfig();
    $AcpService = new AcpService();
    $log = LogUtil::getLogger();
    $params = array(
      //以下信息非特殊情况不需要改动
      &#39;version&#39; => $config->getSDKConfig()->version,    //版本号
      &#39;encoding&#39; => &#39;utf-8&#39;,     //编码方式
      &#39;signMethod&#39; => $config->getSDKConfig()->signMethod,     //签名方法
      &#39;txnType&#39; => &#39;00&#39;,       //交易类型
      &#39;txnSubType&#39; => &#39;00&#39;,     //交易子类
      &#39;bizType&#39; => &#39;000000&#39;,     //业务类型
      &#39;accessType&#39; => &#39;0&#39;,    //接入类型
      &#39;channelType&#39; => &#39;07&#39;,     //渠道类型
 
      //TODO 以下信息需要填写
      &#39;orderId&#39; => $orders[&#39;order_no&#39;],  //请修改被查询的交易的订单号,8-32位数字字母,不能含“-”或“_”
      &#39;merId&#39; => $this->getParameter(&#39;mer_id&#39;),   //商户代码,请改自己的测试商户号
      &#39;txnTime&#39; => date(&#39;YmdHis&#39;, time()), //请修改被查询的交易的订单发送时间,格式为YYYYMMDDhhmmss
    );
 
    $AcpService->sign ( $params ); // 签名
    $url = $config->getSDKConfig()->singleQueryUrl;
 
    $result_arr = $AcpService->post ( $params, $url);
    if(count($result_arr)<=0) { //没收到200应答的情况 $log->LogInfo(&#39;没收到200应答的情况&#39;);
    }
 
    if (!$AcpService->validate ($result_arr) ){
      $log->LogInfo(&#39;应答报文验签失败&#39;);
    }
    if ($result_arr["respCode"] == "00"){
      if ($result_arr["origRespCode"] == "00"){
        //交易成功
        $trade_no = &#39;UN&#39; . date(&#39;YmdHis&#39;, time()) . substr(implode(NULL, array_map(&#39;ord&#39;, str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
        $this->dispose($orders[&#39;order_no&#39;], $trade_no, 4);
        $result = array(&#39;errorCode&#39;=>0, &#39;message&#39;=>&#39;交易成功&#39;, &#39;result_arr&#39;=>$result_arr);
 
      } else if ($result_arr["origRespCode"] == "03"
        || $result_arr["origRespCode"] == "04"
        || $result_arr["origRespCode"] == "05"){
        //后续需发起交易状态查询交易确定交易状态
 
        $result = array(&#39;errorCode&#39;=>2, &#39;message&#39;=>&#39;交易处理中&#39;, &#39;result_arr&#39;=>$result_arr);
 
      } else {
        //其他应答码做以失败处理
 
        echo "交易失败:" . $result_arr["origRespMsg"] . "。
\n";
 
        $result = array(&#39;errorCode&#39;=>1, &#39;message&#39;=>"交易失败:" . $result_arr["origRespMsg"] . ".", &#39;result_arr&#39;=>$result_arr);
      }
    } else if ($result_arr["respCode"] == "03"
      || $result_arr["respCode"] == "04"
      || $result_arr["respCode"] == "05" ){
      //后续需发起交易状态查询交易确定交易状态
 
      $result = array(&#39;errorCode&#39;=>2, &#39;message&#39;=>"处理超时,请稍后查询.", &#39;result_arr&#39;=>$result_arr);
    } else {
      //其他应答码做以失败处理
 
 
      $result = array(&#39;errorCode&#39;=>1, &#39;message&#39;=>"失败:" . $result_arr["respMsg"] . ".", &#39;result_arr&#39;=>$result_arr);
    }
 
    return $result;
  }

到此為止,若是項目沒有訂單線上退款就完成了。

訂單退款相關

public function refundUnionPay($orders)
  {
    require_once(dirname(dirname(__FILE__)) . "/Model/unionpay-sdk/sdk/acp_service.php");
 
    set_time_limit(100);
 
    $config = new SDKConfig();
    $AcpService = new AcpService();
    $log = LogUtil::getLogger();
    $number = 0;
    do{//循环查询,直到获取到退款订单的queryID
      sleep($number * 2);
      $query = $this->unionPayQuery(&#39;&#39;, $orders);
      $number += 1;
    }while($query[&#39;errorCode&#39;] != 0 || empty($query[&#39;result_arr&#39;]["queryId"]));
   
 
    if ($query[&#39;errorCode&#39;] != 0) {
      return array(&#39;errorCode&#39;=>1, &#39;message&#39;=>&#39;订单未成交,无法退款&#39;);
    }
    $params = array(
 
      //以下信息非特殊情况不需要改动
      &#39;version&#39; => $config->getSDKConfig()->version,      //版本号
      &#39;encoding&#39; => &#39;utf-8&#39;,       //编码方式
      &#39;signMethod&#39; => $config->getSDKConfig()->signMethod,       //签名方法
      &#39;txnType&#39; => &#39;04&#39;,         //交易类型
      &#39;txnSubType&#39; => &#39;00&#39;,       //交易子类
      &#39;bizType&#39; => &#39;000201&#39;,       //业务类型
      &#39;accessType&#39; => &#39;0&#39;,      //接入类型
      &#39;channelType&#39; => &#39;07&#39;,       //渠道类型
      &#39;backUrl&#39; => $config->getSDKConfig()->backUrl, //后台通知地址
 
      //TODO 以下信息需要填写
      &#39;orderId&#39; => "T" . $orders[&#39;order_no&#39;],   //商户订单号,8-32位数字字母,不能含“-”或“_”,可以自行定制规则,重新产生-此处为在退款订单前拼接 T
      &#39;merId&#39; => $this->getParameter(&#39;mer_id&#39;),     //商户代码,请改成自己的商户号
      &#39;origQryId&#39; => $query[&#39;result_arr&#39;]["queryId"], //原消费的queryId,可以从查询接口或者通知接口中获取
      &#39;txnTime&#39; => date(&#39;YmdHis&#39;, time()),    //订单发送时间,格式为YYYYMMDDhhmmss,重新产生,不同于原消费
      &#39;txnAmt&#39; => $orders[&#39;total_price&#39;] * 100,   //交易金额,退货总金额需要小于等于原消费
    );
 
    $AcpService->sign ( $params ); // 签名
    $url = $config->getSDKConfig()->backTransUrl;
 
    $result_arr = $AcpService->post ( $params, $url);
    if(count($result_arr)<=0) { //没收到200应答的情况 return array(&#39;errorCode&#39;=>1, &#39;message&#39;=>"没收到应答.");
    }
 
    if (!$AcpService->validate ($result_arr) ){
      return array(&#39;errorCode&#39;=>1, &#39;message&#39;=>"应答报文验签失败.");
    }
 
    if ($result_arr["respCode"] == "00"){
      //交易已受理,等待接收后台通知更新订单状态,如果通知长时间未收到也可发起交易状态查询
      return array(&#39;errorCode&#39;=>0, &#39;message&#39;=>"受理成功.");
 
    } else if ($result_arr["respCode"] == "03"
      || $result_arr["respCode"] == "04"
      || $result_arr["respCode"] == "05" ){
      //后续需发起交易状态查询交易确定交易状态
      return array(&#39;errorCode&#39;=>1, &#39;message&#39;=>"处理超时,请稍微查询.");
    } else {
      //其他应答码做以失败处理
 
      return array(&#39;errorCode&#39;=>1, &#39;message&#39;=>"失败:" . $result_arr["respMsg"] . ".");
    }
  }

依據傳回狀態值進行相關操作即可,實際邏輯程式碼請自行實作

切換生產環境

專案關係暫無法進行-後續補充


未完待續。 。 。 。


相關推薦:

PHP後端銀聯支付及退款實例詳解

##PHP後端

銀聯支付及退款實例

#銀聯支付開發_html/css_WEB-ITnose

##

以上是PHP實現後端銀聯支付及退款實例詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

倉庫:如何復興隊友
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具