Cmb.class.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584
  1. <?php
  2. /**
  3. * 招行银行一网通测试类
  4. * 1.测试查询协议
  5. * 2.测试取消协议
  6. */
  7. class Cmb
  8. {
  9. const pfx_path = BASE_DATA_PATH . "/api/cmbpay/m000001269.pfx";
  10. /**
  11. * 初始化方法
  12. * 加载配置文件
  13. */
  14. public function __construct()
  15. {
  16. $this->config = self::config();
  17. }
  18. static public function config()
  19. {
  20. return array(
  21. 'CMCX_URL' => 'http://58.61.30.110/CmbBank_B2B/UI/DIDI/DoBusiness.ashx', //签约协议查询接口
  22. 'NTBNBR' => 'P0026365',//协议商户企业编号 //请填写自己的商户企业编号
  23. 'MchNo' => 'P0026365',//协议商户企业编号 //请填写自己的商户企业编号
  24. 'pfxFile' => self::pfx_path, //pfx格式证书 通过jks转换 用于openssl签名
  25. 'password' => '12345678',//pfx证书密码
  26. 'BranchID' => '0021',//开户分行号 4位 请自己配置
  27. 'CoNo' => '000140', //商户号 6位 请自己配置
  28. 'singKey' => '',//签名密钥 查询单笔订单需要 测试环境为空
  29. 'DirectRequestX' => 'http://218.17.27.197/netpayment/basehttp.dll?DirectRequestX',//查询订单接口
  30. 'RefundNoDupOperator' => '9999',//退款操作员编号
  31. 'RefundNoDupPassword' => '000140', //测试环境密码和商户号相同
  32. );
  33. }
  34. /**
  35. * 支付协议查询
  36. * 查询成功 BUSDATA 字段返回数据描述
  37. * merch_date String 8 可选 商户交易日期(YYYYMMDD), 成功交易返回
  38. * merch_time String 6 可选 商户交易时间(HHmmSS), 成功交易返回
  39. * merch_serial String 24 必填 商户交易流水号
  40. * respcod String 7 必填 交易结果 CMBMB99表示成功,其他为失败
  41. * respmsg String 80 必填 返回交易信息
  42. * cust_argno String 32 可选 客户协议号,成功交易返回
  43. * bank_name String 40 可选 签约银行名称,成功交易返回
  44. * open_time String 14 可选 签约时间 YYYYMMDD HHmmSS,成功交易返回
  45. * cust_open_d_pay String 1 可选 保留使用:”N”,成功交易返回
  46. * cust_pidty String 1 可选 证件类型 目前只有’1’,表示身份证,成功交易返回
  47. * cust_pid_v String 30 可选 证件号映射的30位hash值,成功交易返回
  48. */
  49. public function cmcx($data)
  50. {
  51. $xmlBusData = "<xml><merch_date>{$data['merch_date']}</merch_date><merch_time>{$data['merch_time']}</merch_time><merch_serial>{$data['merch_serial']}</merch_serial><cust_argno>{$data['cust_argno']}</cust_argno></xml>";
  52. $BUSDAT = base64_encode($xmlBusData);//业务数据包 报文数据必须经过base64编
  53. $NTBNBR = $this->config['NTBNBR'];//企业网银编号
  54. $TRSCOD = 'CMCX';//交易码
  55. $DATLEN = strlen($BUSDAT);// 字段BUSDAT长度
  56. $COMMID = date("YmdHis",time()).mt_rand(100000, 999999);//返回的报文头会包含该信息,仅用作单次通讯的请求和响应报文的对应。银行业务数据不存储该ID。
  57. $SIGTIM = date("YmdHis",time()).'0000';//签名时间
  58. $signOrigin = "NTBNBR={$NTBNBR}&TRSCOD={$TRSCOD}&COMMID={$COMMID}&SIGTIM={$SIGTIM}&BUSDAT={$BUSDAT}";
  59. $SIGDAT = $this->opensslSign($signOrigin);
  60. $requestData = array(
  61. 'NTBNBR' => $NTBNBR,
  62. 'TRSCOD' => $TRSCOD,
  63. 'COMMID' => $COMMID,
  64. 'DATLEN' => $DATLEN,
  65. 'BUSDAT' => $BUSDAT,
  66. 'SIGTIM' => $SIGTIM,
  67. 'SIGDAT' => $SIGDAT,
  68. );
  69. $jsonData = json_encode($requestData);
  70. $url = $this->config['CMCX_URL'];
  71. $postArray = array();
  72. $postArray[0] = $url;
  73. $postArray[1]['data'] = array('RequestData' => $jsonData);
  74. $json = $this->execCurl("post",$postArray);
  75. $cmcxData = json_decode($json,true);
  76. $xml = base64_decode($cmcxData['BUSDAT']);
  77. $xmlArray = (array)simplexml_load_string($xml);
  78. //查询协议日志
  79. $dateTime = date("Y-m-d H:i:s",time());
  80. $logContent = "日志时间:{$dateTime} 请求原文JSON:{$jsonData} 请求XML:{$xmlBusData} 响应原文json:{$json} 响应XML:{$xml}".PHP_EOL.PHP_EOL;
  81. $this->writeLog('cmcx',$logContent);
  82. return $xmlArray;
  83. }
  84. /**
  85. * 获取查询协议数据
  86. * 模拟查询协议用的数据
  87. * 查询不同的协议请使用不同的数据进行模拟
  88. * 这些模拟数据都是真实存在银行系统内的数据不能乱写
  89. */
  90. public function getTestCmcxInfo()
  91. {
  92. $data = array();
  93. $data['merch_date'] = '20160811';//签约协议日期 年月日
  94. $data['merch_time'] = '154021';//签约协议时间 时分秒
  95. $data['merch_serial'] = '2016081143751'; //签约协议流水号
  96. $data['cust_argno'] = '20160811154059441120';//协议号
  97. return $data;
  98. }
  99. /**
  100. * 支付协议查询
  101. * 查询成功 BUSDATA 字段返回数据描述
  102. * merch_date String 8 必填 商户交易日期(YYYYMMDD)
  103. * merch_time String 6 必填 商户交易时间(HHmmSS)
  104. * merch_serial String 24 必填 商户交易流水号,全局唯一
  105. * bank_serial String 30 必填 银行交易流水号,全局唯一
  106. * respcod String 7 必填 交易结果 CMBMB99表示成功,其他为失败
  107. * respmsg String 80 必填 返回交易信息
  108. */
  109. public function cmqx($data)
  110. {
  111. $xmlBusData = "<xml><merch_date>{$data['merch_date']}</merch_date><merch_time>{$data['merch_time']}</merch_time><merch_serial>{$data['merch_serial']}</merch_serial><cust_argno>{$data['cust_argno']}</cust_argno></xml>";
  112. $BUSDAT = base64_encode($xmlBusData);//业务数据包 报文数据必须经过base64编
  113. $NTBNBR = $this->config['NTBNBR'];//企业网银编号
  114. $TRSCOD = 'CMQX';//交易码
  115. $DATLEN = strlen($BUSDAT);// 字段BUSDAT长度
  116. $COMMID = date("YmdHis",time()).mt_rand(100000, 999999);//返回的报文头会包含该信息,仅用作单次通讯的请求和响应报文的对应。银行业务数据不存储该ID。
  117. $SIGTIM = date("YmdHis",time()).'0000';//签名时间
  118. $signOrigin = "NTBNBR={$NTBNBR}&TRSCOD={$TRSCOD}&COMMID={$COMMID}&SIGTIM={$SIGTIM}&BUSDAT={$BUSDAT}";
  119. $SIGDAT = $this->opensslSign($signOrigin);
  120. $requestData = array(
  121. 'NTBNBR' => $NTBNBR,
  122. 'TRSCOD' => $TRSCOD,
  123. 'COMMID' => $COMMID,
  124. 'DATLEN' => $DATLEN,
  125. 'BUSDAT' => $BUSDAT,
  126. 'SIGTIM' => $SIGTIM,
  127. 'SIGDAT' => $SIGDAT,
  128. );
  129. $jsonData = json_encode($requestData);
  130. $url = $this->config['CMCX_URL'];//查询和取消走的都是同一个接口
  131. $postArray = array();
  132. $postArray[0] = $url;
  133. $postArray[1]['data'] = array('RequestData' => $jsonData);
  134. $json = $this->execCurl("post",$postArray);
  135. $cmcxData = json_decode($json,true);
  136. $xml = base64_decode($cmcxData['BUSDAT']);
  137. $xmlArray = (array)simplexml_load_string($xml);
  138. //取消协议日志
  139. $dateTime = date("Y-m-d H:i:s",time());
  140. $logContent = "日志时间:{$dateTime} 请求原文JSON:{$jsonData} 请求XML:{$xmlBusData} 响应原文json:{$json} 响应XML:{$xml}".PHP_EOL.PHP_EOL;
  141. $this->writeLog('cmqx',$logContent);
  142. return $xmlArray;
  143. }
  144. /**
  145. * 获取查询协议数据
  146. * 模拟查询协议用的数据
  147. * 如果提供的数据不存在于银行系统内,返回错误提示
  148. */
  149. public function getTestCmqxInfo()
  150. {
  151. $data = array();
  152. $data['merch_date'] = '20160811';//签约协议日期 年月日
  153. $data['merch_time'] = '151709';//签约协议时间 时分秒
  154. $data['merch_serial'] = '2016081132532'; //签约协议流水号
  155. $data['cust_argno'] = '20160811151403121298';//协议号
  156. return $data;
  157. }
  158. /**
  159. * 查询支付协议签名
  160. * php基于sha1withRSA算法的签名(pfx证书)
  161. * @param type $data
  162. * @return type
  163. */
  164. public function opensslSign($data)
  165. {
  166. $certs = array();
  167. //其中password为证书密码
  168. openssl_pkcs12_read(file_get_contents($this->config['pfxFile']), $certs, $this->config['password']);
  169. if(!$certs) return ;
  170. $signature = '';
  171. openssl_sign($data, $signature, $certs['pkey']);
  172. return base64_encode($signature);//返回base64编码的密钥
  173. }
  174. /**
  175. * 获取银行订单信息
  176. */
  177. public function getOneOrderInfo($data)
  178. {
  179. $startTime = strtotime("2000-01-01 00:00:00");
  180. $currentTime = time();
  181. $diffTime = $currentTime - $startTime;
  182. $BranchNo = $this->config['BranchID'];//开户分行号
  183. $MerchantNo = $this->config['CoNo'];//商户号
  184. $TimeStamp = $diffTime * 1000;//请求发起的时间,精确到毫秒
  185. $Date = $data['Date'];//商户定单日期 年月日 YYYYMMDD
  186. $BillNo = $data['BillNo'];//订单号 6位或10位订单号
  187. $singKey = $this->config['singKey'];//签名密钥 测试情况下为空
  188. //SHA1 哈希签名
  189. $HashOrigin = "{$singKey}<BranchNo>{$BranchNo}</BranchNo><MerchantNo>{$MerchantNo}</MerchantNo><TimeStamp>{$TimeStamp}</TimeStamp><Command>QuerySingleOrder</Command><Date>{$Date}</Date><BillNo>{$BillNo}</BillNo>";
  190. $Hash = sha1($HashOrigin);//使用sha1加密
  191. //单笔订单请求报文
  192. $postData = "<Request><Head><BranchNo>{$BranchNo}</BranchNo><MerchantNo>{$MerchantNo}</MerchantNo><TimeStamp>{$TimeStamp}</TimeStamp><Command>QuerySingleOrder</Command></Head><Body><Date>{$Date}</Date><BillNo>{$BillNo}</BillNo></Body><Hash>{$Hash}</Hash></Request>";
  193. //接口地址
  194. $array = array();
  195. $array[0] = $this->config['DirectRequestX'];
  196. $array[1]['data'] = array(
  197. 'Request' => $postData,
  198. );
  199. $xmlString = $this->execCurl('post',$array);
  200. //查询单笔订单日志
  201. $dateTime = date("Y-m-d H:i:s",time());
  202. $logContent = "日志时间:{$dateTime} 请求原文:{$postData} 响应原文:{$xmlString}".PHP_EOL.PHP_EOL;
  203. $this->writeLog('singleOrder',$logContent);
  204. $xmlArray = simplexml_load_string($xmlString);
  205. return $this->objectToArray($xmlArray);
  206. }
  207. /**
  208. * 模拟获取订单信息
  209. */
  210. public function getTestOneOrder()
  211. {
  212. $BillNo = '0003041211'; //银行订单号
  213. $Date = '20160812'; //订单日期
  214. return array('BillNo'=>$BillNo,'Date'=>$Date);
  215. }
  216. /**
  217. * 订单查询 共用接口 该方法可以接受三个接口参数调用
  218. * 通过Command字段区分调用
  219. * 1.商户入账查询接口 QueryTransact
  220. * 2.按商户日期查询已结账订单接口 QuerySettledOrderByMerchantDate
  221. * 3.按结账日期查询已结账订单接口 QuerySettledOrderBySettledDate
  222. */
  223. public function getQueryOrderData($data)
  224. {
  225. $startTime = strtotime("2000-01-01 00:00:00");
  226. $currentTime = time();
  227. $diffTime = $currentTime - $startTime;
  228. $BranchNo = $this->config['BranchID'];//开户分行号
  229. $MerchantNo = $this->config['CoNo'];//商户号
  230. $TimeStamp = $diffTime * 1000;//请求发起的时间,精确到毫秒
  231. $BeginDate = $data['BeginDate'];//起始日期
  232. $EndDate = $data['EndDate'];//结束日期
  233. $Count = $data['Count'];//查询条数
  234. $Operator = $data['Operator'];//操作员号
  235. $pos = $data['Pos']; //续传包
  236. $singKey = $this->config['singKey'];//签名密钥 测试情况下为空
  237. $Command = $data['Command']; //接口名称 说明见注释
  238. //SHA1 哈希签名
  239. $HashOrigin = "{$singKey}<BranchNo>{$BranchNo}</BranchNo><MerchantNo>{$MerchantNo}</MerchantNo><TimeStamp>{$TimeStamp}</TimeStamp><Command>{$Command}</Command><BeginDate>{$BeginDate}</BeginDate><EndDate>{$EndDate}</EndDate><Count>{$Count}</Count><Operator>{$Operator}</Operator><pos>{$pos}</pos>";
  240. $Hash = sha1($HashOrigin);
  241. //商户入账查询请求报文
  242. $postData = "<Request><Head><BranchNo>{$BranchNo}</BranchNo><MerchantNo>{$MerchantNo}</MerchantNo><TimeStamp>{$TimeStamp}</TimeStamp><Command>{$Command}</Command></Head><Body><BeginDate>{$BeginDate}</BeginDate><EndDate>{$EndDate}</EndDate><Count>{$Count}</Count><Operator>{$Operator}</Operator><pos>{$pos}</pos></Body><Hash>{$Hash}</Hash></Request>";
  243. //接口地址
  244. $array = array();
  245. $array[0] = $this->config['DirectRequestX'];
  246. $array[1]['data'] = array(
  247. 'Request' => $postData,
  248. );
  249. $xmlString = $this->execCurl('post',$array);
  250. //接口命令
  251. $CommandArray = array(
  252. 'QuerySettledOrderByMerchantDate' => '商户日期查询已结账订单接口',
  253. 'QuerySettledOrderBySettledDate' => '结账日期查询已结账订单接口',
  254. 'QueryTransact' => '商户入账查询接口',
  255. );
  256. //入账 已结账日志
  257. $dateTime = date("Y-m-d H:i:s",time());
  258. $logContent = "日志时间:{$dateTime} 请求命令:{$Command} 接口名称:{$CommandArray[$Command]} 请求原文:{$postData} 响应原文:{$xmlString}".PHP_EOL.PHP_EOL;
  259. $this->writeLog('querySettledOrder',$logContent);
  260. $xmlArray = simplexml_load_string($xmlString);
  261. return $this->objectToArray($xmlArray);
  262. }
  263. /**
  264. * 模拟获取商户入账数据
  265. * 模拟测试数据 生产环境请用正式数据代替
  266. */
  267. public function getTestQueryTransact()
  268. {
  269. $BeginDate = '20150923';//起始日期
  270. $EndDate = '20160924';//结束日期
  271. $Count = '10';//查询条数
  272. $Operator = '9999';//操作员号
  273. $pos = ''; //续传包
  274. $Command = 'QueryTransact';//接口命令 不同的命令
  275. $data = array(
  276. 'BeginDate' => $BeginDate,
  277. 'EndDate' => $EndDate,
  278. 'Count' => $Count,
  279. 'Operator' => $Operator,
  280. 'pos' => $pos,
  281. 'Command' => $Command,
  282. );
  283. return $data;
  284. }
  285. /**
  286. * 按结账日期查询已结账订单接口
  287. * 模拟测试数据 生产环境请用正式数据代替
  288. */
  289. public function getTestQuerySettledOrderBySettledDate()
  290. {
  291. $BeginDate = '20160801';//起始日期
  292. $EndDate = '20160810';//结束日期
  293. $Count = '20';//查询条数
  294. $Operator = '9999';//操作员号
  295. $pos = ''; //续传包
  296. $Command = 'QuerySettledOrderBySettledDate';//接口命令 不同的命令
  297. $data = array(
  298. 'BeginDate' => $BeginDate,
  299. 'EndDate' => $EndDate,
  300. 'Count' => $Count,
  301. 'Operator' => $Operator,
  302. 'pos' => $pos,
  303. 'Command' => $Command,
  304. );
  305. return $data;
  306. }
  307. /**
  308. * 按商户日期查询已结账订单接口
  309. * 模拟测试数据 生产环境请用正式数据代替
  310. */
  311. public function getTestQuerySettledOrderByMerchantDate()
  312. {
  313. $BeginDate = '20150923';//起始日期
  314. $EndDate = '20160924';//结束日期
  315. $Count = '10';//查询条数
  316. $Operator = '9999';//操作员号
  317. $pos = ''; //续传包
  318. $Command = 'QuerySettledOrderByMerchantDate';//接口命令 不同的命令
  319. $data = array(
  320. 'BeginDate' => $BeginDate,
  321. 'EndDate' => $EndDate,
  322. 'Count' => $Count,
  323. 'Operator' => $Operator,
  324. 'pos' => $pos,
  325. 'Command' => $Command,
  326. );
  327. return $data;
  328. }
  329. /**
  330. * 执行退款操作
  331. */
  332. public function getRefundNoDupData($data)
  333. {
  334. $startTime = strtotime("2000-01-01 00:00:00");
  335. $currentTime = time();
  336. $diffTime = $currentTime - $startTime;
  337. $BranchNo = $this->config['BranchID'];//开户分行号
  338. $MerchantNo = $this->config['CoNo'];//商户号
  339. $TimeStamp = $diffTime * 1000;//请求发起的时间,精确到毫秒
  340. $Date = $data['Date'];//原订单日期
  341. $BillNo = $data['BillNo']; //原订单号
  342. $RefundNo = $data['RefundNo'];//退款流水号
  343. $Operator = $this->config['RefundNoDupOperator'];//操作员号
  344. $Password = $this->config['RefundNoDupPassword'];//操作员密码
  345. $Amount = $data['Amount'];//退款金额
  346. $Desc = $data['Desc'];//退款描述
  347. $singKey = $this->config['singKey'];//签名密钥 测试情况下为空
  348. $Command = 'Refund_No_Dup'; //接口名称 说明见注释
  349. //SHA1 哈希签名
  350. $HashOrigin = "{$singKey}<BranchNo>{$BranchNo}</BranchNo><MerchantNo>{$MerchantNo}</MerchantNo><Operator>{$Operator}</Operator><Password>{$Password}</Password><TimeStamp>{$TimeStamp}</TimeStamp><Command>{$Command}</Command><Date>{$Date}</Date><BillNo>{$BillNo}</BillNo><RefundNo>{$RefundNo}</RefundNo><Amount>{$Amount}</Amount><Desc>{$Desc}</Desc>";
  351. $Hash = sha1($HashOrigin);
  352. //商户入账查询请求报文
  353. $postData = "<Request><Head><BranchNo>{$BranchNo}</BranchNo><MerchantNo>{$MerchantNo}</MerchantNo><Operator>{$Operator}</Operator><Password>{$Password}</Password><TimeStamp>{$TimeStamp}</TimeStamp><Command>{$Command}</Command></Head><Body><Date>{$Date}</Date><BillNo>{$BillNo}</BillNo><RefundNo>{$RefundNo}</RefundNo><Amount>{$Amount}</Amount><Desc>{$Desc}</Desc></Body><Hash>{$Hash}</Hash></Request>";
  354. //接口地址
  355. $array = array();
  356. $array[0] = $this->config['DirectRequestX'];
  357. $array[1]['data'] = array(
  358. 'Request' => $postData,
  359. );
  360. $xmlString = $this->execCurl('post',$array);
  361. //入账 已结账日志
  362. $dateTime = date("Y-m-d H:i:s",time());
  363. $logContent = "日志时间:{$dateTime} 请求命令:Refund_No_Dup 接口名称:直连退款 请求原文:{$postData} 响应原文:{$xmlString}".PHP_EOL.PHP_EOL;
  364. $this->writeLog('refundNoDup',$logContent);
  365. $xmlArray = simplexml_load_string($xmlString);
  366. return $this->objectToArray($xmlArray);
  367. }
  368. /**
  369. * 模拟退款数据
  370. */
  371. public function getTestRefundNoDup()
  372. {
  373. $Date = '20160812';//订单日期
  374. $BillNo = '0001416027';//订单号
  375. $RefundNo = 'TK'.date("YmdHis",time()). mt_rand(1000,9999);//退款流水号
  376. $Amount = '98.00';//退款金额
  377. $Desc = 'tuikuan desc';//
  378. $data = array(
  379. 'Date' => $Date,
  380. 'BillNo' => $BillNo,
  381. 'RefundNo' => $RefundNo,
  382. 'Amount' => $Amount,
  383. 'Desc' => $Desc,
  384. );
  385. return $data;
  386. }
  387. /**
  388. * 递归转换XML为数组
  389. * @param type $data
  390. * @return type
  391. */
  392. public function objectToArray($e)
  393. {
  394. $_arr = is_object($e) ? get_object_vars($e) : $e;
  395. foreach ($_arr as $key => $val) {
  396. $val = (is_array($val) || is_object($val)) ? $this->objectToArray($val) : $val;
  397. $arr[$key] = !$val ? (string)$val : $val;
  398. }
  399. return $arr;
  400. }
  401. /**
  402. * CURL函数
  403. * @param type $method
  404. * @param type $args
  405. * @return type
  406. * @throws \Exception
  407. */
  408. public function execCurl($method, $args)
  409. {
  410. //解析参数
  411. $url = isset($args[0]) ? $args[0] : "";
  412. $multi = isset($args[1]['multi']) ? $args[1]['multi'] : "";
  413. $data = isset($args[1]['data']) ? $args[1]['data'] : "";
  414. $ajax = isset($args[1]['ajax']) ? $args[1]['ajax'] : "";
  415. $timeout = isset($args[1]['timeout']) ? $args[1]['timeout'] : 30;
  416. $files = isset($args[1]['files']) ? $args[1]['files'] : "";
  417. $referer = isset($args[1]['referer']) ? $args[1]['referer'] : "";
  418. $proxy = isset($args[1]['proxy']) ? $args[1]['proxy'] : "";
  419. $headers = isset($args[1]['headers']) ? $args[1]['headers'] : "";
  420. //如果环境变量的浏览器信息不存在,就是用手动设置的浏览器信息
  421. $userAgent = isset($_SERVER['HTTP_USER_AGENT'])?
  422. $_SERVER['HTTP_USER_AGENT']:
  423. 'Mozilla/5.0 (Windows NT 6.2; WOW64; rv:23.0)
  424. Gecko/20100101 Firefox/23.0';
  425. //检测url必须参数 不能为空
  426. if (!$url) {
  427. throw new \Exception("错误:curl请求地址不能为空");
  428. }
  429. //设置curl选项
  430. $options = array(
  431. CURLOPT_URL => $url, //目标url
  432. CURLOPT_TIMEOUT => $timeout, //超时
  433. CURLOPT_RETURNTRANSFER => 1, //输出数据流
  434. CURLOPT_FOLLOWLOCATION => 1, //自动跳转追踪
  435. CURLOPT_AUTOREFERER => 1, //自动设置来路信息
  436. CURLOPT_SSL_VERIFYPEER => 0, //认证证书检查
  437. CURLOPT_SSL_VERIFYHOST => 0, //检查SSL加密算法
  438. CURLOPT_HEADER => 0, //禁止头文件输出
  439. CURLOPT_NOSIGNAL => 1, //忽略所有传递的信号
  440. CURLOPT_USERAGENT => $userAgent,//浏览器环境字符串
  441. CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4, //ipv4寻址方式
  442. CURLOPT_ENCODING => 'gzip', //解析使用gzip压缩的网页
  443. );
  444. //设置代理 必须是数组并且非空
  445. if (is_array($proxy) && !empty($proxy)) {
  446. $options[CURLOPT_PROXY] = $proxy['host'];
  447. $options[CURLOPT_PROXYPORT] = $proxy['port'];
  448. $options[CURLOPT_PROXYUSERPWD] =
  449. $proxy['user'] . ':' . $proxy['pass'];
  450. }
  451. //检测是否未启用自定义urlencode编码
  452. if (!isset($args[1]['build'])) {
  453. if ($data && $method == "post" && is_array($data)) {
  454. $data = http_build_query($data, '', '&');
  455. }
  456. }
  457. //检测是否含有上传文件
  458. if ($files && $method == "post" && is_array($files)) {
  459. foreach ($files as $k => $v) {
  460. $files[$k] = '@' . $v;
  461. }
  462. parse_str($data, $data);
  463. $data = $data + $files;
  464. }
  465. //检测判断是否是post请求
  466. if ($method == 'post') {
  467. //发送一个常规的POST请求
  468. $options[CURLOPT_POST] = 1;
  469. //使用HTTP协议中的"POST"操作来发送数据,支持键值对数组定义
  470. $options[CURLOPT_POSTFIELDS] = $data;
  471. }
  472. //初始化header数组
  473. $headerOptions = array();
  474. //检测是否是ajax提交
  475. if ($ajax) {
  476. $headerOptions['X-Requested-With'] = 'XMLHttpRequest';
  477. }
  478. //设置来路
  479. if ($referer) {
  480. $options[CURLOPT_REFERER] = $referer;
  481. }
  482. //合并header
  483. if (!empty($headers) && is_array($headers)) {
  484. foreach ($headers as $k => $v) {
  485. $headerOptions[$k] = $v;
  486. }
  487. }
  488. //转换header选项为浏览器header格式
  489. if (!empty($headerOptions) && is_array($headerOptions)) {
  490. $array = array();
  491. foreach($headerOptions as $k => $v) {
  492. $array[] = $k . ": " . $v;
  493. }
  494. $options[CURLOPT_HTTPHEADER] = $array;
  495. }
  496. //创建curl句柄
  497. $ch = curl_init();
  498. //设置curl选项
  499. curl_setopt_array($ch, $options);
  500. //获取返回内容
  501. $content = curl_exec($ch);
  502. //关闭curl句柄
  503. curl_close($ch);
  504. //返回内容
  505. return $content;
  506. }
  507. /**
  508. * 写日志
  509. * @param type $fileName 文件名
  510. * @param type $filePath 文件路径
  511. * @param type $logContent 日志内容
  512. */
  513. public function writeLog($dirName, $logContent)
  514. {
  515. $currentPath = dirname(__FILE__) .'/log/' . $dirName ;
  516. if (!file_exists($currentPath)) {
  517. @mkdir($currentPath,0777,true);
  518. }
  519. $filename = date("dmY",time()) . '.log';
  520. $writeFileName = $currentPath . '/' . $filename;
  521. file_put_contents($writeFileName, $logContent,FILE_APPEND);
  522. }
  523. }