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

PHP MVC框架编辑时未选新图却自动变为默认图的问题

Fix: Keep Original Image Unless New One is Selected in MVC Industry Edit Form

Hey there, let's tackle this issue where your industry image gets reset to the default even when you don't pick a new one. The core problem is in how your controller handles the file upload check and how the form tracks the original image value. Here's how to fix it step by step:

1. Adjust the HTML View

First, let's ensure the form properly retains the original image path and cleans up unnecessary inputs:

<form id="form-category" class="form-horizontal" action="<?php $_SERVER['PHP_SELF']; ?>" method="POST" enctype="multipart/form-data">
    <div class="form-group">
        <label class="col-sm-2 control-label">Image</label>
        <div class="col-sm-10">
            <a href="" id="thumb-image" data-toggle="image" class="img-thumbnail">
                <img src="<?php echo HTTP_HOST; ?>/image/<?php echo $data['industry_image']; ?>" alt="<?php echo $data['industry_name']; ?>" title="<?php echo $data['industry_name']; ?>" data-placeholder="<?php echo HTTP_HOST; ?>/image/<?php echo $data['placeholder']; ?>" width="100" height="100">
            </a>
            <!-- Hidden input to store original image path -->
            <input type="hidden" name="original_industry_image" value="<?php echo $data['industry_image']; ?>">
            <input type="file" class="hidden" name="industry_image" id="input-image" onchange="readURL(this);">
        </div>
    </div>
</form>

Update the Image Preview jQuery

Tweak the popover logic to ensure clearing the image explicitly sets the placeholder, and doesn't break the original image retention:

// Preview selected image
function readURL(input) {
    if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = function (e) {
            $('#thumb-image').children('img').attr('src', e.target.result);
        }
        reader.readAsDataURL(input.files[0]);
    }
}

// Bootstrap image popover handler
$(document).on('click', 'a[data-toggle=\'image\']', function(e) {
    var $element = $(this);
    var $popover = $element.data('bs.popover');
    e.preventDefault();

    // Destroy existing popovers
    $('a[data-toggle="image"]').popover('destroy');
    if ($popover) return;

    $element.popover({
        html: true,
        placement: 'right',
        trigger: 'manual',
        content: function() {
            return '<button type="button" id="button-image" class="btn btn-primary"><i class="fa fa-pencil"></i></button> <button type="button" id="button-clear" class="btn btn-danger"><i class="fa fa-trash-o"></i></button>';
        }
    }).popover('show');

    // Trigger file selection
    $('#button-image').on('click', function() {
        $('#input-image').trigger('click');
        $element.popover('destroy');
    });

    // Clear image to placeholder
    $('#button-clear').on('click', function() {
        const placeholder = $element.find('img').attr('data-placeholder');
        $('input[name="original_industry_image"]').val(placeholder.split('/').pop()); // Update hidden input to placeholder filename
        $element.find('img').attr('src', placeholder);
        $('#input-image').val(''); // Clear file input
        $element.popover('destroy');
    });
});

2. Fix the Controller Logic

This is the main culprit—your original code overwrote the image with the default whenever no file was uploaded. Let's adjust it to keep the original image unless a new one is selected:

// Initialize data with original image value
$originalImage = $_POST['original_industry_image'] ?? 'no-image.png';
$data = [
    'industry_name' => $_POST['industry_name'],
    'industry_description' => $_POST['industry_description'],
    'sort_order' => $_POST['sort_order'],
    'status' => $_POST['status'],
    'industry_image' => $originalImage // Default to original image
];

// Only process file upload if a file was actually selected
if (!empty($_FILES['industry_image']['size'])) {
    $file = $_FILES['industry_image'];
    $fileName = $file['name'];
    $fileTmpName = $file['tmp_name'];
    $fileSize = $file['size'];
    $fileError = $file['error'];
    $fileExt = explode('.', $fileName);
    $fileActualExt = strtolower(end($fileExt));
    
    $allowed = ['gif', 'jpg', 'jpeg', 'png'];
    $allowedFileSize = 2000000;

    if (in_array($fileActualExt, $allowed)) {
        if ($fileError === 0) {
            if ($fileSize < $allowedFileSize) {
                $fileNameNew = strtolower($data['industry_name']) . "." . $fileActualExt;
                $fileDestination = DIR_IMAGE . 'industries/' . $fileNameNew;
                $filePath = 'industries/' . $fileNameNew;

                // Delete old image only if it's not the placeholder
                if ($originalImage !== 'no-image.png' && file_exists(DIR_IMAGE . $originalImage)) {
                    unlink(DIR_IMAGE . $originalImage);
                }

                if (move_uploaded_file($fileTmpName, $fileDestination)) {
                    $data['industry_image'] = $filePath;
                } else {
                    echo "Error: File Upload Failed. Try again.";
                    exit;
                }
            } else {
                flash("file_alert alert-danger", "File size is $fileSize, maximum allowed is $allowedFileSize");
            }
        } else {
            flash("file_alert alert-danger", "Error uploading the file");
        }
    } else {
        $allowedExts = implode(', ', array_map(function($ext) { return "<b>$ext</b>"; }, $allowed));
        flash("file_alert alert-danger", "Please upload only $allowedExts extensions");
    }
}

// Update industry and redirect
if ($this->model->editIndustry($industry_id, $data)) {
    redirect("catalog/industries");
} else {
    redirect("catalog/industries_form", $data);
}

Key Controller Fixes:

  • Starts with the original image value instead of defaulting to the placeholder
  • Only overrides the image path if a valid new file is uploaded
  • Fixes old image deletion logic to use the correct file path
  • Cleans up the allowed extensions error message

3. Complete the Model's editIndustry Method

Make sure your model actually updates the industry_image field in the database—your original code was missing this critical part:

public function editIndustry($industry_id, $data) {
    // Update query including industry_image
    $this->db->query("UPDATE industry SET 
        industry_name = :industry_name, 
        industry_description = :industry_description, 
        sort_order = :sort_order, 
        status = :status,
        industry_image = :industry_image 
        WHERE industry_id = :industry_id");

    // Bind all values
    $this->db->bind(':industry_name', $data['industry_name']);
    $this->db->bind(':industry_description', $data['industry_description']);
    $this->db->bind(':sort_order', $data['sort_order']);
    $this->db->bind(':status', $data['status']);
    $this->db->bind(':industry_image', $data['industry_image']);
    $this->db->bind(':industry_id', $industry_id);

    return $this->db->execute();
}

How It Works Now:

  • The edit form loads with the original image and stores its path in a hidden input
  • If you submit without selecting a new image, the controller uses the original image value
  • If you select a new image, it uploads it, replaces the old image (if it's not the placeholder), and updates the database
  • If you click "Clear", it sets the image to the placeholder and updates the hidden input so the database gets the placeholder path

内容的提问来源于stack exchange,提问作者Leo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:21:41