PHP中通过cURL POST请求接收并保存PDF文件的问题排查
在PHP中通过cURL POST请求接收并保存PDF文件的解决方案
现有代码的核心问题
- cURL请求头设置错误:你用
CURLOPT_HEADER来设置Content-Type是错的,这个选项是控制是否返回响应头的,正确做法是用CURLOPT_HTTPHEADER指定请求头。 - XML响应格式无效:
- 标签大小写不匹配:
<pdfContent>对应的闭合标签是小写的</pdfcontent>,XML是大小写敏感的,这直接导致解析失败。 - 二进制内容直接写入XML:PDF是二进制文件,里面可能包含
<、>、&等XML特殊字符,直接放入会破坏结构;而且你只是写了file_get_contents('xyz.pdf')字符串,并没有实际执行这个函数获取内容。
- 标签大小写不匹配:
解决方案一:直接返回PDF二进制数据(推荐,更高效)
这种方式跳过XML中转,Api.php生成PDF后直接输出二进制内容,request.php接收后直接保存文件。
修改后的request.php代码
$post = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <request> <stmt_no>123456</stmt_no> <from_date>01/05/2023</from_date> <to_date>18/05/2023</to_date> </request>'; $target_url = "http://example.com/stmt/Api.php"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $target_url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); // 正确设置请求头为text/xml curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml']); // 不返回响应头,只获取响应体 curl_setopt($ch, CURLOPT_HEADER, 0); // 设置返回结果保存到变量,而非直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $result = curl_exec($ch); $info = curl_getinfo($ch); // 检查响应是否为PDF类型 if ($info['content_type'] === 'application/pdf') { // 保存PDF到本地 file_put_contents('received.pdf', $result); echo "PDF文件保存成功"; } else { echo "请求失败或未获取到PDF: " . $result; } curl_close($ch);
修改后的Api.php代码
// 接收并解析XML请求数据 $xml = simplexml_load_string(file_get_contents('php://input')); $stmt_no = (string)$xml->stmt_no; $from_date = (string)$xml->from_date; $to_date = (string)$xml->to_date; // 这里是你生成xyz.pdf的业务代码(假设已完成) // generate_xyz_pdf($stmt_no, $from_date, $to_date); // 设置响应头为PDF类型 header('Content-Type: application/pdf'); header('Content-Disposition: inline; filename="xyz.pdf"'); // 直接输出PDF二进制内容 readfile('xyz.pdf'); exit;
解决方案二:通过Base64编码在XML中传递PDF(适合需同时返回其他业务数据的场景)
如果需要在响应中同时返回stmt_no等数据,可以将PDF内容Base64编码后放入XML,避免破坏XML结构。
修改后的Api.php代码
// 接收解析请求XML $xml = simplexml_load_string(file_get_contents('php://input')); $stmt_no = (string)$xml->stmt_no; // ... 其他参数处理逻辑 // 生成PDF后读取内容并Base64编码 $pdf_content = base64_encode(file_get_contents('xyz.pdf')); // 输出格式正确的XML响应 header('Content-Type: text/xml; charset=utf-8'); echo '<?xml version="1.0" encoding="utf-8"?> <response> <stmt_no>' . $stmt_no . '</stmt_no> <pdfContent>' . $pdf_content . '</pdfContent> </response>'; exit;
修改后的request.php代码
$post = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?> <request> <stmt_no>123456</stmt_no> <from_date>01/05/2023</from_date> <to_date>18/05/2023</to_date> </request>'; $target_url = "http://example.com/stmt/Api.php"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $target_url); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: text/xml']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); $result = curl_exec($ch); curl_close($ch); // 解析XML响应 $response_xml = simplexml_load_string($result); if ($response_xml) { $pdf_base64 = (string)$response_xml->pdfContent; // 解码并保存PDF file_put_contents('received.pdf', base64_decode($pdf_base64)); echo "PDF保存成功,对应单号:" . $response_xml->stmt_no; } else { echo "XML解析失败:" . libxml_get_last_error()->message; }
内容的提问来源于stack exchange,提问作者user1414232
相关产品推荐
相关产品推荐

