WordPress自定义文章类型无法保存上传的PDF文件
WordPress自定义文章类型PDF上传失败排查与修复
问题概述
创建了名为"Samples"的自定义文章类型,并添加PDF上传字段,但上传操作后,文件未保存到指定目录,文件名也未存入数据库,且无任何错误提示。完整代码如下:
// Register Custom Post Type function custom_samples_post_type() { $labels = array( 'name' => 'Samples', 'singular_name' => 'Sample', 'menu_name' => 'Samples', 'all_items' => 'All Samples', 'add_new' => 'Add New', 'add_new_item' => 'Add New Sample', 'edit_item' => 'Edit Sample', 'new_item' => 'New Sample', 'view_item' => 'View Sample', 'search_items' => 'Search Samples', 'not_found' => 'No samples found', 'not_found_in_trash' => 'No samples found in Trash', ); $args = array( 'label' => 'Samples', 'labels' => $labels, 'description' => 'A custom post type for uploading PDF samples.', 'public' => true, 'menu_position' => 5, 'menu_icon' => 'dashicons-media-document', // Change the menu icon as needed 'supports' => array('title', 'editor'), 'has_archive' => true, 'rewrite' => array('slug' => 'samples'), ); register_post_type('sample', $args); } add_action('init', 'custom_samples_post_type'); // Add PDF File Upload Field to Sample Post Type function add_pdf_upload_field() { add_meta_box('pdf_upload', 'Upload PDF', 'render_pdf_upload_field', 'sample', 'normal', 'high'); } add_action('add_meta_boxes', 'add_pdf_upload_field'); function render_pdf_upload_field($post) { $pdf_url = get_post_meta($post->ID, 'pdf_url', true); ?> <label for="pdf_url">Upload PDF:</label> <input type="file" name="pdf_file" id="pdf_file" accept=".pdf" /> <?php if ($pdf_url) : ?> <p>Current PDF: <a href="<?php echo esc_url($pdf_url); ?>" target="_blank"><?php echo esc_html(basename($pdf_url)); ?></a></p> <?php endif; ?> <input type="hidden" name="pdf_url" id="pdf_url" value="<?php echo esc_url($pdf_url); ?>" /> <?php } function save_pdf_upload_field($post_id) { if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id; if (isset($_FILES['pdf_file']) && !empty($_FILES['pdf_file']['name'])) { $pdf_file = $_FILES['pdf_file']; $upload_dir = wp_upload_dir(); $pdf_dir = trailingslashit($upload_dir['path']) . 'samples/'; $pdf_url = trailingslashit($upload_dir['url']) . 'samples/' . sanitize_file_name($pdf_file['name']); if (!file_exists($pdf_dir)) wp_mkdir_p($pdf_dir); $pdf_path = trailingslashit($pdf_dir) . sanitize_file_name($pdf_file['name']); if (move_uploaded_file($pdf_file['tmp_name'], $pdf_path)) { update_post_meta($post_id, 'pdf_url', esc_url($pdf_url)); } } } add_action('save_post', 'save_pdf_upload_field');
核心问题与修复步骤
1. 补充表单enctype属性
WordPress默认文章编辑表单没有multipart/form-data属性,而文件上传必须依赖这个属性。添加以下代码修复:
// 给文章编辑表单添加文件上传所需的enctype属性 function add_form_enctype() { echo ' enctype="multipart/form-data"'; } add_action('post_edit_form_tag', 'add_form_enctype');
2. 完善安全验证逻辑
当前保存函数缺少权限检查和文章类型验证,容易导致逻辑失效或安全问题,修改save_pdf_upload_field函数:
function save_pdf_upload_field($post_id) { // 自动保存时跳过处理 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id; // 验证用户编辑权限 if (!current_user_can('edit_post', $post_id)) return $post_id; // 仅处理"sample"自定义文章类型 if (get_post_type($post_id) !== 'sample') return $post_id; // 原有文件处理逻辑... }
3. 增加错误日志排查
添加错误捕获和日志记录,方便定位问题:
function save_pdf_upload_field($post_id) { // ... 上述安全验证代码 ... if (isset($_FILES['pdf_file']) && !empty($_FILES['pdf_file']['name'])) { $pdf_file = $_FILES['pdf_file']; // 检查上传是否出现错误 if ($pdf_file['error'] !== UPLOAD_ERR_OK) { error_log('PDF上传错误代码: ' . $pdf_file['error']); return $post_id; } $upload_dir = wp_upload_dir(); $pdf_dir = trailingslashit($upload_dir['path']) . 'samples/'; $pdf_url = trailingslashit($upload_dir['url']) . 'samples/' . sanitize_file_name($pdf_file['name']); // 检查目录创建是否成功 if (!file_exists($pdf_dir)) { if (!wp_mkdir_p($pdf_dir)) { error_log('无法创建目标目录: ' . $pdf_dir); return $post_id; } } $pdf_path = trailingslashit($pdf_dir) . sanitize_file_name($pdf_file['name']); // 检查文件移动是否成功 if (!move_uploaded_file($pdf_file['tmp_name'], $pdf_path)) { error_log('无法将上传文件移动到目标路径: ' . $pdf_path); } else { update_post_meta($post_id, 'pdf_url', esc_url($pdf_url)); } } }
4. 处理文件名重复问题
避免同名文件覆盖,给文件名添加唯一标识:
// 替换原有文件名处理部分 $file_name = sanitize_file_name($pdf_file['name']); $file_parts = pathinfo($file_name); // 生成唯一文件名(原文件名+唯一ID+扩展名) $unique_file_name = $file_parts['filename'] . '-' . uniqid() . '.' . $file_parts['extension']; $pdf_path = trailingslashit($pdf_dir) . $unique_file_name; $pdf_url = trailingslashit($upload_dir['url']) . 'samples/' . $unique_file_name;
5. 验证目录权限
确保wp-content/uploads/目录及子目录有正确的写入权限(通常设置为755或775,具体根据服务器配置调整)。
完整修正代码
// Register Custom Post Type function custom_samples_post_type() { $labels = array( 'name' => 'Samples', 'singular_name' => 'Sample', 'menu_name' => 'Samples', 'all_items' => 'All Samples', 'add_new' => 'Add New', 'add_new_item' => 'Add New Sample', 'edit_item' => 'Edit Sample', 'new_item' => 'New Sample', 'view_item' => 'View Sample', 'search_items' => 'Search Samples', 'not_found' => 'No samples found', 'not_found_in_trash' => 'No samples found in Trash', ); $args = array( 'label' => 'Samples', 'labels' => $labels, 'description' => 'A custom post type for uploading PDF samples.', 'public' => true, 'menu_position' => 5, 'menu_icon' => 'dashicons-media-document', 'supports' => array('title', 'editor'), 'has_archive' => true, 'rewrite' => array('slug' => 'samples'), ); register_post_type('sample', $args); } add_action('init', 'custom_samples_post_type'); // Add PDF File Upload Field to Sample Post Type function add_pdf_upload_field() { add_meta_box('pdf_upload', 'Upload PDF', 'render_pdf_upload_field', 'sample', 'normal', 'high'); } add_action('add_meta_boxes', 'add_pdf_upload_field'); // 给文章编辑表单添加文件上传所需的enctype属性 function add_form_enctype() { echo ' enctype="multipart/form-data"'; } add_action('post_edit_form_tag', 'add_form_enctype'); function render_pdf_upload_field($post) { $pdf_url = get_post_meta($post->ID, 'pdf_url', true); ?> <label for="pdf_url">Upload PDF:</label> <input type="file" name="pdf_file" id="pdf_file" accept=".pdf" /> <?php if ($pdf_url) : ?> <p>Current PDF: <a href="<?php echo esc_url($pdf_url); ?>" target="_blank"><?php echo esc_html(basename($pdf_url)); ?></a></p> <?php endif; ?> <input type="hidden" name="pdf_url" id="pdf_url" value="<?php echo esc_url($pdf_url); ?>" /> <?php } function save_pdf_upload_field($post_id) { // 自动保存时跳过处理 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id; // 验证用户编辑权限 if (!current_user_can('edit_post', $post_id)) return $post_id; // 仅处理"sample"自定义文章类型 if (get_post_type($post_id) !== 'sample') return $post_id; if (isset($_FILES['pdf_file']) && !empty($_FILES['pdf_file']['name'])) { $pdf_file = $_FILES['pdf_file']; // 检查上传是否出现错误 if ($pdf_file['error'] !== UPLOAD_ERR_OK) { error_log('PDF上传错误代码: ' . $pdf_file['error']); return $post_id; } $upload_dir = wp_upload_dir(); $pdf_dir = trailingslashit($upload_dir['path']) . 'samples/'; // 检查目录创建是否成功 if (!file_exists($pdf_dir)) { if (!wp_mkdir_p($pdf_dir)) { error_log('无法创建目标目录: ' . $pdf_dir); return $post_id; } } // 生成唯一文件名避免覆盖 $file_name = sanitize_file_name($pdf_file['name']); $file_parts = pathinfo($file_name); $unique_file_name = $file_parts['filename'] . '-' . uniqid() . '.' . $file_parts['extension']; $pdf_path = trailingslashit($pdf_dir) . $unique_file_name; $pdf_url = trailingslashit($upload_dir['url']) . 'samples/' . $unique_file_name; // 检查文件移动是否成功 if (!move_uploaded_file($pdf_file['tmp_name'], $pdf_path)) { error_log('无法将上传文件移动到目标路径: ' . $pdf_path); } else { update_post_meta($post_id, 'pdf_url', esc_url($pdf_url)); } } } add_action('save_post', 'save_pdf_upload_field');
内容的提问来源于stack exchange,提问作者Senior Thesis
相关产品推荐
相关产品推荐

