WordPress更新文章后用TCPDF生成PDF失败求助
问题排查与修复方案
核心问题分析
你的代码在save_post钩子中直接输出PDF,而WordPress在文章保存完成后默认会发送跳转响应(返回编辑页),这会导致PDF的HTTP头被覆盖,浏览器无法接收到正确的PDF内容,因此没有任何反应。此外代码还存在几个细节问题:
save_post触发场景未过滤:该钩子会在自动保存、修订版创建时触发,这些场景不需要生成PDF- 作者信息错误:
$post->post_author返回的是用户ID,不是显示名称 - 未终止后续流程:输出PDF后未停止WordPress的后续执行,会干扰PDF输出
修复步骤与代码调整
方案一:生成PDF到服务器,后台显示下载链接
避免响应头冲突,先将PDF保存到服务器,再通过后台通知告知用户下载:
require_once(WP_CONTENT_DIR . '/mu-plugins/tcpdf/tcpdf.php'); function generate_pdf_from_post($post_id) { $post = get_post($post_id); if (!$post) return false; // 应用内容过滤器,解析短代码与格式 $content = apply_filters('the_content', $post->post_content); // 获取作者显示名称 $author_name = get_the_author_meta('display_name', $post->post_author); // 创建PDF实例 $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); $pdf->SetCreator(PDF_CREATOR); $pdf->SetAuthor($author_name); $pdf->SetTitle($post->post_title); $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); $pdf->AddPage(); $pdf->writeHTML($content, true, false, true, false, ''); // 保存PDF到uploads目录 $upload_dir = wp_upload_dir(); $pdf_filename = sanitize_title($post->post_title) . '-' . time() . '.pdf'; $pdf_path = $upload_dir['path'] . '/' . $pdf_filename; $pdf->Output($pdf_path, 'F'); return $pdf_path; } function generate_pdf_on_save($post_id, $post, $update) { // 排除无效触发场景:非更新、自动保存、修订版、非目标自定义类型 if (!$update || wp_is_post_autosave($post_id) || wp_is_post_revision($post_id)) return; $custom_post_types = array('properties_for_sale', 'vacation_rentals', 'long_term_rentals'); if (!in_array($post->post_type, $custom_post_types)) return; // 生成PDF并添加后台通知 $pdf_path = generate_pdf_from_post($post_id); if ($pdf_path) { add_action('admin_notices', function() use ($pdf_path) { $download_url = str_replace(ABSPATH, site_url('/'), $pdf_path); echo '<div class="notice notice-success is-dismissible"> <p>PDF已生成:<a href="' . esc_url($download_url) . '" target="_blank">点击下载</a></p> </div>'; }); } } add_action('save_post', 'generate_pdf_on_save', 10, 3);
方案二:添加自定义按钮直接生成并下载PDF
如果希望点击按钮直接触发PDF下载,可在文章编辑页添加独立操作按钮:
require_once(WP_CONTENT_DIR . '/mu-plugins/tcpdf/tcpdf.php'); // 在编辑页添加自定义按钮 add_action('post_submitbox_misc_actions', 'add_generate_pdf_button'); function add_generate_pdf_button() { global $post; $custom_post_types = array('properties_for_sale', 'vacation_rentals', 'long_term_rentals'); if (!in_array($post->post_type, $custom_post_types)) return; echo '<div class="misc-pub-section"> <a href="' . admin_url('admin-post.php?action=generate_post_pdf&post_id=' . $post->ID) . '" class="button button-secondary">生成并下载PDF</a> </div>'; } // 处理按钮请求,输出PDF add_action('admin_post_generate_post_pdf', 'handle_generate_pdf_request'); function handle_generate_pdf_request() { // 权限验证 if (!current_user_can('edit_post', $_GET['post_id'])) { wp_die('无权限操作'); } $post_id = absint($_GET['post_id']); $post = get_post($post_id); if (!$post) wp_die('文章不存在'); $content = apply_filters('the_content', $post->post_content); $author_name = get_the_author_meta('display_name', $post->post_author); $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); $pdf->SetCreator(PDF_CREATOR); $pdf->SetAuthor($author_name); $pdf->SetTitle($post->post_title); $pdf->setPrintHeader(false); $pdf->setPrintFooter(false); $pdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT); $pdf->AddPage(); $pdf->writeHTML($content, true, false, true, false, ''); // 输出PDF到浏览器并终止流程 $pdf->Output(sanitize_title($post->post_title) . '.pdf', 'I'); exit(); }
关键修复点说明
- 过滤
save_post的无效触发场景,避免无意义的PDF生成 - 修正作者名称获取逻辑,显示正确的用户名
- 方案一通过服务器存储+后台通知的方式,绕开响应头冲突问题
- 方案二使用独立的
admin_post请求处理PDF输出,确保HTTP头正确发送 - 对文章内容应用
the_content过滤,解析短代码和格式,让PDF内容与前台显示一致
内容的提问来源于stack exchange,提问作者Gabriele Cettolin
相关产品推荐
相关产品推荐

