You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 20:55:55