PHP接口通信的几种方式

不同项目组之间经常使用接口通信,整理常用的几种方式如下。

一 . Curl模拟Http请求

最常用的通信方式,可以获取或改动少量数据,也可以让对方进行某种操作,响应时间限制很短。

接口文档:
在这里插入图片描述
调用代码:

  /**
   * @brief   调用在线培训接口
   * @note  
   * @author  jichenghan
   * @param   $p_aInput
   * @date    2020-11-05
   * @return  array
   */
 public function getApi($p_aInput)
 {
    $aApiParams = [];
    $aApiParams['userid']     = $p_aInput['userid'];
    $aApiParams['campids']    = $p_aInput['campids'];
    $aApiParams['timespan']   = time();  
    ksort($aApiParams);
    $sApiValue = '';
    foreach ($aApiParams as $sValue)
    {
        $sApiValue .= $sValue;
    }

    /* 生成签名和参数 */
    $aApiParams['key']= MD5(MD5($sApiValue.KEY));
    $aRequest = [
        'type'   => 1,
        'url'    => URL,
        'method' => 'POST',
        'param'  => $aApiParams
    ];

    $sResult = $this->oHttpRequest->send($aRequest);
    $aResult = json_decode($sResult, true);
    return $aResult;
 }

基类代码:

    $this->oCurl = curl_init();
    $sQuery = http_build_query($p_aInput['param']);
    //设置参数
    curl_setopt($this->oCurl, CURLOPT_URL, $p_aInput['url']);
    curl_setopt($this->oCurl, CURLOPT_POST, true);
    curl_setopt($this->oCurl, CURLOPT_HEADER, 0);
    curl_setopt($this->oCurl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($this->oCurl, CURLOPT_POSTFIELDS, $sQuery);
    $mResult = curl_exec($this->oCurl));
    curl_close($this->oCurl);
    return $mResult;

二. Socket通讯

一般用于传参数量很多和返回结果量很大、响应时间较长的情况,如下调用大数据接口返回搜索结果。
在这里插入图片描述
调用代码:

  /**
   * @brief  调用大数据接口 通用方法
   * @note
   * @author jichenghan
   * @date   2021-01-15
   * @param  array       $p_aInput      参数数组
   * @return string                     返回结果
   */
  protected function getResultFromBigData($p_aInput)
  {
      $sOprType    = chr(26);  //间隔字符
      $sFieldchar  = '|';        //操作符

      $sSendStr = '';
      foreach ($p_aInput as $aSendvalue)
      {
          $sSendStr .= $sOprType;

          if (is_array($aSendvalue))
          {
              $sSendStr .= implode($sFieldchar, $aSendvalue);
          }
          else
          {
              $sSendStr .= $aSendvalue;
          }
      }

      $sSendStr = substr($sSendStr, 1);
      $iBuflen  = mb_strlen($sSendStr, '8bit');//byte字节长度
      $sBreqlen = pack('N', $iBuflen);   //int转字节(大端)

      $sSocketSendParams = [];
      $sSocketSendParams['sendstr']    = $sBreqlen . $sSendStr;
      $sSocketSendParams['serverip']   = IP;
      $sSocketSendParams['serverport'] = PORT;
      $sSocketSendParams['resultlen']  = 4;

      $sSearchResult = $this->oSocket->getResultFromSocket($sSocketSendParams);
      $aSearchResult = unpack('N*', $sSearchResult);
      return $aSearchResult;
  }

基类代码:

 /*创建socket*/
 $rSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
 try 
 {
     /*判断socket是否创建成功*/
     if ($rSocket)
     {
         /*设置超时*/
         socket_set_option($rSocket, SOL_SOCKET, SO_RCVTIMEO, ['sec' => 10, 'usec' => 0]);
         socket_set_option($rSocket, SOL_SOCKET, SO_SNDTIMEO, ['sec' => 10, 'usec' => 0]);
         /*设置关闭时立即关闭,不等待*/
         $aSetLinger  = [];
         $aSetLinger['l_onoff']   = 1;
         $aSetLinger['l_linger']  = 0;
         socket_set_option($rSocket, SOL_SOCKET, SO_LINGER, $aSetLinger);

         /*连接socket*/
         $bSocketConnect = @socket_connect($rSocket, $sServerIp, $sServerPort);
         if ($bSocketConnect)
         {
             /*发送*/
             $iSent = socket_write($rSocket, $sSendStr, strlen($sSendStr));            
             /*返回字符串*/
             $sReceiveStr = '';    
             /*发送失败*/
             if ($iSent === false)
             {
                 $q_sFailMsg = '发送失败';
             }
             else
             {
                 $sReceiveStr = socket_read($rSocket, $sResultLen);
                 if ($p_iReadType == 2)
                 {
                     $iReturnLength = unpack('N', $sReceiveStr)[1];//获取有用信息字符串长度
                     $sReceiveStr = '';
                     $iLength = $iReturnLength;     
                     /* 设置for循环,防止进入死循环 */
                     for ($iLoop=0; $iLength> 0 && $iLoop < 1000; $iLoop++)
                     {
                         $sReceiveStrTmp = @socket_read($rSocket, 1024);
                         $sReceiveStr .= $sReceiveStrTmp;
                         $iLength -= strlen($sReceiveStrTmp);
                     }
                     $sReceiveStr=  substr($sReceiveStr, 0, $iReturnLength);
                 }
                 elseif ($p_iReadType == 3)
                 {
                     $sReceiveStrTmp = '';
                     while ($sReceiveStrTmp = socket_read($rSocket, $sResultLen))
                     {
                         $sReceiveStr .= $sReceiveStrTmp;
                     }
                 }
                 elseif ($p_iReadType == 4)
                 {
                     $iReturnLength = unpack('V', $sReceiveStr)[1];//小端字节序
                     $sReceiveStr = '';
                     $iLength = $iReturnLength;
                     /* 设置for循环,防止进入死循环 */
                     for ($iLoop=0; $iLength> 0 && $iLoop < 1000; $iLoop++)
                     {
                         $sReceiveStrTmp = @socket_read($rSocket, 1024);
                         $sReceiveStr .= $sReceiveStrTmp;
                         $iLength -= strlen($sReceiveStrTmp);
                     }
                     $sReceiveStr = substr($sReceiveStr, 0, $iReturnLength);
                     if (strlen($sReceiveStr) != $iReturnLength)
                     {
                         $sReceiveStr = false;
                         $q_sFailMsg = '返回字节长度不正确';
                     }
                 }
                 /*关闭socket*/
                 socket_close($rSocket);
                 /* 操作成功,返回结果 */
                 return $sReceiveStr;
             }
         }
         /*连接失败*/
         else
         {
             $q_sFailMsg = '连接失败';
         }
     }
     /*socket创建失败*/
     else
     {
         $q_sFailMsg = 'socket创建失败';
     }
 }
 catch (Exception $e)
 {
     $q_sFailMsg = 'Caught exception:' . $e->getMessage();
 }

二. 生成XML文件

多用于数据量较大但改动很少的场景,比如页面显示列表,类似于缓存的作用。

 public function getXML()
 {
     $xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n";
     $xml .= "<Report date=\".date("Y-m-d").\">\r\n";
     $space = "  ";
     foreach ($Arr as $ptypekey => $ptype) 
     {
         $xml .= $space."<PTYPE$ptypekey>\r\n";
         foreach ($ptype as $num => $ptypevalue) 
         {
             $xml .= $space.$space."<Record>\r\n";
             foreach ($ptypevalue as $key => $value) 
             {
                 if ($key == 'id') 
                 {
                     continue;
                 }
                 $value = iconv("gbk", "utf-8//IGNORE", $value);
                 $xml .= $space.$space.$space."<$key>".($value)."</$key>\r\n";
             }
             $xml .= $space.$space."</Record>\r\n";
         }
         $xml .= $space."</PTYPE$ptypekey>\r\n";
     }
     $xml .= "</Report>";

     $filedir = PATH;
     if (!is_dir($filedir)) {
         mkdir($filedir,0777,true); // 如果不存在则创建
     }
     $fileName = $filedir."/ehire.xml";
     $myfile = @fopen($fileName, 'w');
     $Result = fwrite($myfile, $xml);
     fclose($myfile);
     if ($Result === false) {
         return '写文件失败';
     }
     $fileNameTmp = $filedir."/ehire".date("YmdHis").".xml";
     copy($fileName, $fileNameTmp);
     return '成功';       
 }

生成xml文件:
在这里插入图片描述

四. 定时任务

操作同一张表,A项目组下任务,B项目组定时读取,进行操作同时改变状态。

定时任务 Mission.sh:

#!/bin/sh
. /etc/profile
procNum=$(ps -ef|grep Mission.php|grep -v grep |wc -l)
if [ "$procNum" -lt "1" ];then
/user/bin/php /www/shell/mission/Mission.php >> /www/shell/mission/log.out
fi

调用文件 Mission.php:

set_time_limit( 0 );
@ini_set('memory_limit','500M');
//操作代码

五. 消息队列

比方法四有更好的实时性和容错性,这个后面我单独详解。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值