首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

CKEditor 4 / 5 上傳圖片檔案大小限制完整設定指南

     編輯:PHP 相關知識

兩層限制策略:伺服端 + 客戶端

檔案上傳大小限制必須在「伺服端」強制執行(客戶端可繞過)。完整防護包含三層:

  1. PHP 設定:upload_max_filesize、post_max_size、memory_limit
  2. Web Server 設定:Nginx client_max_body_size、Apache LimitRequestBody
  3. 應用層邏輯:CKEditor 連接器 / 自訂上傳端點驗證檔案大小

第一層:PHP.ini 核心設定

; php.ini
file_uploads = On
upload_max_filesize = 10M        ; 单个文件上限
post_max_size = 12M              ; POST 總資料上限(需 > upload_max_filesize)
memory_limit = 128M              ; 腳本記憶體上限
max_file_uploads = 20            ; 同時上傳檔案數
max_execution_time = 300         ; 大檔上傳需較長執行時間
; 開發環境建議開啟錯誤顯示
display_errors = On
error_reporting = E_ALL

注意:修改後必須重啟 PHP-FPM / Apache 生效。若使用共享主機無法改 php.ini,可嘗試 .user.ini 或 ini_set()(僅限非系統級指令)。

第二層:Web Server 設定

Nginx

# nginx.conf / site.conf
http {
  client_max_body_size 12M;  # 需 >= post_max_size
  # 其他優化
  client_body_timeout 60s;
  client_header_timeout 60s;
}

Apache

# httpd.conf / .htaccess
LimitRequestBody 12582912  # 12M (bytes)
# 或在 VirtualHost 內

  LimitRequestBody 12582912

第三層:CKEditor 4 連接器 (PHP) 自訂大小限制

CKEditor 4 使用 editor/filemanager/connectors/php/ 作為預設上傳端點。

1. 設定檔 config.php

<?php
// editor/filemanager/connectors/php/config.php
$Config['Enabled'] = true;
$Config['UserFilesPath'] = '/userfiles/';
$Config['UserFilesAbsolutePath'] = '/var/www/html/userfiles/';

// 自訂最大檔案大小(單位:KB)
$Config['MaxImageSize'] = 2048;      // 2MB 圖片
$Config['MaxFileSize']  = 10240;     // 10MB 一般檔案

2. 核心邏輯 commands.php 攔截超大檔案

<?php
// editor/filemanager/connectors/php/commands.php
// 在 FileUpload 函式內,安全驗證區塊後加入:
if (isset($Config['MaxImageSize']) && $resourceType === 'Image') {
  $sizeKB = round($oFile['size'] / 1024);
  if ($sizeKB > $Config['MaxImageSize']) {
    $sErrorNumber = '204'; // 自訂錯誤代碼:圖片過大
  }
}
if (isset($Config['MaxFileSize']) && $resourceType === 'File') {
  $sizeKB = round($oFile['size'] / 1024);
  if ($sizeKB > $Config['MaxFileSize']) {
    $sErrorNumber = '205'; // 一般檔案過大
  }
}

// 重要:移除原本的 else { $sErrorNumber = '202'; } 區塊,
// 否則自訂錯誤會被覆蓋為通用「無效副檔名」錯誤。

3. 前端錯誤訊息對應 fck_image.js / fck_file.js

// editor/dialog/fck_image/fck_image.js
// 在 OnUploadCompleted 函式的 switch (errorNumber) 中新增:
case 204:
  alert('圖片檔案過大,限制 2MB 以內');
  return;
case 205:
  alert('檔案過大,限制 10MB 以內');
  return;

CKEditor 5 現代上傳適配器實作(推薦)

CKEditor 5 採用「上傳適配器」架構,完全可自訂上傳邏輯。

簡易 Base64 上傳適配器(含大小限制)

// MyCustomUploadAdapter.js
class MyCustomUploadAdapter {
  constructor(loader) {
    this.loader = loader;
  }

  upload() {
    return this.loader.file
      .then(file => new Promise((resolve, reject) => {
        // 客戶端預檢(使用者體驗,非安全邊界)
        const MAX_SIZE = 2 * 1024 * 1024; // 2MB
        if (file.size > MAX_SIZE) {
          reject('圖片不可超過 2MB');
          return;
        }

        const data = new FormData();
        data.append('upload', file);

        fetch('/api/upload-image', {
          method: 'POST',
          body: data,
          credentials: 'same-origin'
        })
        .then(response => response.json())
        .then(result => {
          if (result.error) {
            reject(result.error.message);
          } else {
            resolve({ default: result.url });
          }
        })
        .catch(err => reject('上傳失敗:' + err.message));
      }));
  }

  abort() { /* 可選:中止上傳 */ }
}

// 在 CKEditor 設定中註冊
ClassicEditor
  .create(document.querySelector('#editor'), {
    extraPlugins: [MyCustomUploadAdapterPlugin],
    // 其他設定...
  })
  .catch(console.error);

後端 API /api/upload-image (PHP)

<?php
// api/upload-image.php
header('Content-Type: application/json; charset=utf-8');

$maxSize = 2 * 1024 * 1024; // 2MB
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
$uploadDir = __DIR__ . '/../public/uploads/images/';

if (!is_dir($uploadDir)) mkdir($uploadDir, 0755, true);

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
  http_response_code(405);
  echo json_encode(['error' => ['message' => 'Method Not Allowed']]);
  exit;
}

if (!isset($_FILES['upload']) || $_FILES['upload']['error'] !== UPLOAD_ERR_OK) {
  http_response_code(400);
  echo json_encode(['error' => ['message' => '無效的上傳檔案']]);
  exit;
}

$file = $_FILES['upload'];

// 伺服端二次驗證(安全邊界)
if ($file['size'] > $maxSize) {
  http_response_code(413);
  echo json_encode(['error' => ['message' => '檔案過大,限制 2MB']]);
  exit;
}

// MIME 偵測(比副檔名可靠)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);

if (!in_array($mime, $allowedTypes, true)) {
  http_response_code(415);
  echo json_encode(['error' => ['message' => '不支援的檔案類型']]);
  exit;
}

// 產生唯一檔名
$ext = ['image/jpeg'=>'jpg','image/png'=>'png','image/gif'=>'gif','image/webp'=>'webp'][$mime];
$newName = bin2hex(random_bytes(16)) . '.' . $ext;
$dest = $uploadDir . $newName;

if (!move_uploaded_file($file['tmp_name'], $dest)) {
  http_response_code(500);
  echo json_encode(['error' => ['message' => '檔案儲存失敗']]);
  exit;
}

// 回傳公開 URL
echo json_encode(['url' => '/uploads/images/' . $newName]);
?>

常見問題排查表

現象可能原因解決方向
上傳大檔直接報 413 / 500Nginx client_max_body_size 過小調整 nginx.conf 並 reload
PHP $_FILES 為空post_max_size < 上傳總大小調大 post_max_size (>= upload_max_filesize + 表單其他欄位)
CKEditor 4 回傳錯誤代碼 202自訂錯誤被預設 else 覆蓋移除 commands.php 中的 else 區塊
前端 alert 顯示亂碼JS 檔案編碼非 UTF-8確保 .js 檔案以 UTF-8 儲存
上傳成功但圖片顯示不出來回傳 URL 路徑錯誤 / 權限問題檢查 UserFilesPath、實體路徑權限、Nginx static location

總結

CKEditor 檔案大小限制必須「三層同步」:PHP.ini、Web Server、應用層邏輯。CKEditor 4 需修改連接器原始碼;CKEditor 5 建議自寫上傳適配器,掌控完整流程。生產環境務必在後端以 finfo 驗證 MIME、以隨機檔名儲存、限制執行權限,防止惡意檔案上傳執行。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved