如何在Woocommerce中下载Moloni发票PDF前验证文件有效性?
Moloni发票PDF有效性预检查方案
针对你遇到的「Moloni发票未生成时,PDF链接返回错误HTML导致保存无效内容」的问题,以下是几个可靠的预检查方案:
1. 优先调用Moloni发票详情API验证状态
这是最准确的方案,直接通过官方API获取发票的生成状态,避免盲目下载链接:
- 先调用Moloni的
documents/get接口(具体接口以官方文档为准),获取发票的详细信息,其中会包含发票的生成状态字段(比如status或document_status)。 - 只有当状态标识为「已生成」(比如对应值为
generated)时,再去获取并下载PDF链接。
$invoiceId = 1234; // 目标发票ID $accessToken = "YOUR_MOLONI_TOKEN"; $companyId = "YOUR_COMPANY_ID"; // 调用发票详情API $apiUrl = "https://api.moloni.eu/v1/documents/get?access_token={$accessToken}&company_id={$companyId}&document_id={$invoiceId}"; $response = file_get_contents($apiUrl); $invoiceData = json_decode($response, true); // 验证发票生成状态(字段和值需参考Moloni API文档) if (isset($invoiceData['status']) && $invoiceData['status'] === 'generated') { $pdfUrl = $invoiceData['pdf_url']; // 额外验证响应头确保是PDF $headers = get_headers($pdfUrl, 1); if (strpos($headers['Content-Type'], 'application/pdf') !== false) { file_put_contents('/path/to/save/invoice_' . $invoiceId . '.pdf', file_get_contents($pdfUrl)); } } else { error_log("发票 {$invoiceId} 尚未生成,跳过下载"); }
2. 检查PDF链接的HTTP响应头
如果无法调用详情API,可以先获取PDF链接的响应头,通过Content-Type和HTTP状态码判断是否为有效PDF:
$pdfUrl = "YOUR_MOLONI_PDF_LINK"; $headers = get_headers($pdfUrl, 1); // 验证状态码和内容类型 if (strpos($headers[0], '200 OK') !== false && strpos($headers['Content-Type'], 'application/pdf') !== false) { file_put_contents('/path/to/save.pdf', file_get_contents($pdfUrl)); } else { error_log("无效的PDF链接:{$pdfUrl}"); }
注:若服务器不支持get_headers,可以用cURL设置CURLOPT_NOBODY为true来获取响应头。
3. 下载前验证文件魔法数
PDF文件开头固定包含%PDF-标识,可以先下载前几百字节内容验证,避免下载完整错误页面:
$pdfUrl = "YOUR_MOLONI_PDF_LINK"; $ch = curl_init($pdfUrl); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_RANGE, '0-100'); // 仅下载前101字节 $partialContent = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); // 验证HTTP状态和PDF标识 if ($httpCode === 200 && strpos($partialContent, '%PDF-') === 0) { file_put_contents('/path/to/save.pdf', file_get_contents($pdfUrl)); } else { error_log("链接返回非PDF内容:{$pdfUrl}"); }
为什么之前的方法无效?
file_exists()仅适用于本地文件,对远程URL无法准确判断资源有效性;- 直接匹配页面内容容易受页面更新、编码差异影响,稳定性差。
内容的提问来源于stack exchange,提问作者Jaime Matos
相关产品推荐
相关产品推荐

