
本文介绍如何在wordpress插件中修改现有pdf生成逻辑,实现在用户下载快递标签pdf的同时,将同一份pdf文件自动保存至服务器指定目录,避免重复请求第三方api。
要在生成DPD快递标签PDF时同时保存到服务器(而不仅限于响应客户端下载),关键是在get_labels_output()函数中,在输出PDF内容给浏览器之前,先将其写入服务器磁盘。当前代码通过echo $pdf直接将二进制PDF流发送至HTTP响应,随后调用die终止脚本——我们只需在echo前插入文件写入逻辑即可。
✅ 推荐实现方式(安全、可维护)
private function get_labels_output( $pdf, $file_name = 'dpdLabels' ) {
$name = $file_name . '-' . date( 'Y-m-d-His' ) . '.pdf'; // 增加秒级时间戳,避免同日重名
$upload_dir = wp_upload_dir(); // 推荐使用WordPress标准上传目录
$save_path = $upload_dir['path'] . '/' . $name; // 如:/wp-content/uploads/2024/06/dpdLabels-2024-06-15-143022.pdf
// ✅ 安全写入:确保目录可写且路径合法
if ( ! is_writable( $upload_dir['path'] ) ) {
error_log( "PDF save failed: upload directory not writable — {$upload_dir['path']}" );
// 可选:降级处理或抛出用户提示(需配合前端)
} else {
$bytes_written = file_put_contents( $save_path, $pdf );
if ( $bytes_written === false ) {
error_log( "PDF save failed: unable to write file — {$save_path}" );
}
}
// ? 保持原有下载行为不变
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/pdf' );
header( 'Content-Disposition: attachment; filename="' . $name . '"' );
header( 'Content-Transfer-Encoding: binary' );
header( 'Connection: Keep-Alive' );
header( 'Expires: 0' );
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
header( 'Pragma: public' );
echo $pdf;
die;
}⚠️ 注意事项与最佳实践
- 路径安全性:避免硬编码相对路径(如../pathToSaveYourPdfFiles/),易受路径遍历或权限问题影响;优先使用 wp_upload_dir() 获取受控、可写的标准目录。
- 文件名唯一性:添加 H:i:s 时间戳(而非仅日期),防止高频调用时覆盖同名文件。
- 错误处理:file_put_contents() 返回 false 表示失败,应记录错误日志便于排查(如磁盘满、SELinux限制、open_basedir 限制等)。
- 权限与备份:确保Web服务器用户(如 www-data)对目标目录有写权限;生产环境建议定期归档或清理旧PDF,避免占用过多空间。
- 合规性提醒:若PDF含客户敏感信息(如收件人地址),需确保服务器存储符合GDPR/PIPL等数据保护要求,必要时加密或设置访问控制。
通过以上改造,每次调用 print_order_parcel_label() 生成标签时,PDF既会触发浏览器下载,也会静默持久化至服务器,为后续审计、重发或批量导出提供可靠数据源。










