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

CKEditor 文件上傳重命名、按日期分目錄存儲與圖片水印完整配置指南

     編輯:PHP 相關知識

CKEditor 作為主流富文本編輯器,其文件上傳功能默認配置往往無法滿足生產環境需求。本文系統講解如何實現上傳文件按年月分目錄存儲、隨機重命名防衝突、中文文件名亂碼解決,以及服務端圖片水印添加的完整集成方案。

一、按日期自動分目錄存儲

修改 editor/filemanager/connectors/php/config.php:

<?php
// 原配置
$Config['UserFilesPath'] = '/userfiles/';

// 修改為按年月分目錄
$Config['UserFilesPath'] = '/uploadfiles/' . date("Ym") . "/";

// 同步修改物理路徑
$Config['UserFilesAbsolutePath'] = $_SERVER['DOCUMENT_ROOT'] . $Config['UserFilesPath'];
?>

效果:上傳文件自動存入 /uploadfiles/202401/ 等目錄,便於管理與性能優化。

二、文件隨機重命名(防衝突、防中文亂碼)

修改 editor/filemanager/connectors/php/io.php 中的 SanitizeFileName 函數:

<?php
function SanitizeFileName($sNewFileName) {
    global $Config;
    $sNewFileName = stripslashes($sNewFileName);
    
    // 保留最後一個點號作為擴展名分隔
    if ($Config['ForceSingleExtension']) {
        $sNewFileName = preg_replace('/\.(?![^.]*$)/', '_', $sNewFileName);
    }
    
    // 移除危險字符
    $sNewFileName = preg_replace('/[\\\|\/|\:|\?|\*|"|<|>]/', '_', $sNewFileName);
    
    // 核心:生成唯一文件名
    $sExtension = substr($sNewFileName, strrpos($sNewFileName, '.') + 1);
    $sNewFileName = my_setfilename() . '.' . $sExtension;
    
    return $sNewFileName;
}

function my_setfilename() {
    $gettime = explode(' ', microtime());
    $string = 'abcdefghijklmnopqrstuvwxyz0123456789';
    $rand = '';
    for ($x = 0; $x < 12; $x++) {
        $rand .= substr($string, mt_rand(0, strlen($string) - 1), 1);
    }
    // 格式:年月日時分秒 + 微秒後6位 + 12位隨機字符
    return date("ymdHis") . substr($gettime[0], 2, 6) . $rand;
}
?>

命名規則示例: 240115143022_123456_a1b2c3d4e5f6.jpg,極低衝突概率。

三、FCKEditor 兼容性補充(舊版本項目)

修改 editor/filemanager/connectors/php/commands.php 中 FileUpload 函數:

<?php
// 在獲取擴展名後添加
$sExtension = substr($sFileName, (strrpos($sFileName, '.') + 1));
$sExtension = strtolower($sExtension);

// 重命名邏輯
$sFileName = rand(0, 100) . "." . $sExtension; // 可替換為更複雜的命名策略

// 或使用 iconv 解決中文亂碼(不解決重名)
// $sFileName = iconv("UTF-8", "GBK", $sFileName);
?>

四、圖片水印核心函數(支持圖片/文字雙模式)

<?php
/**
 * 給圖片添加水印
 * @param string $imgSrc 目標圖片路徑
 * @param string $markImg 水印圖片路徑(圖片模式時)
 * @param string $markText 水印文字(文字模式時)
 * @param string $TextColor 文字顏色 RGB,如 "255,0,0"
 * @param int $markPos 位置 0-9(0=隨機,1-9=九宮格)
 * @param string $fontType 字體文件路徑(文字模式必需)
 * @param string $markType 'img' 或 'text'
 */
function setWater($imgSrc, $markImg, $markText, $TextColor, $markPos, $fontType, $markType) {
    $srcInfo = @getimagesize($imgSrc);
    if (!$srcInfo) return;
    
    $srcImg_w = $srcInfo[0];
    $srcImg_h = $srcInfo[1];
    
    // 創建源圖像資源
    switch ($srcInfo[2]) {
        case 1: $srcim = imagecreatefromgif($imgSrc); break;
        case 2: $srcim = imagecreatefromjpeg($imgSrc); break;
        case 3: $srcim = imagecreatefrompng($imgSrc); break;
        default: die("不支持的圖片類型");
    }
    
    // 處理水印圖片
    if ($markType == "img") {
        if (!file_exists($markImg) || empty($markImg)) return;
        $markImgInfo = @getimagesize($markImg);
        if ($srcImg_w < $markImgInfo[0] || $srcImg_h < $markImgInfo[1]) return;
        
        switch ($markImgInfo[2]) {
            case 1: $markim = imagecreatefromgif($markImg); break;
            case 2: $markim = imagecreatefromjpeg($markImg); break;
            case 3: $markim = imagecreatefrompng($markImg); break;
            default: die("不支持的水印圖片類型");
        }
        $logow = $markImgInfo[0];
        $logoh = $markImgInfo[1];
    }
    
    // 處理水印文字
    if ($markType == "text") {
        $fontSize = 16;
        if (empty($markText) || !file_exists($fontType)) return;
        $box = @imagettfbbox($fontSize, 0, $fontType, $markText);
        $logow = max($box[2], $box[4]) - min($box[0], $box[6]);
        $logoh = max($box[1], $box[3]) - min($box[5], $box[7]);
    }
    
    // 計算水印位置(九宮格)
    if ($markPos == 0) $markPos = rand(1, 9);
    switch ($markPos) {
        case 1: $x = 5; $y = 5; break;           // 左上
        case 2: $x = ($srcImg_w - $logow) / 2; $y = 5; break;     // 上中
        case 3: $x = $srcImg_w - $logow - 5; $y = 5; break;       // 右上
        case 4: $x = 5; $y = ($srcImg_h - $logoh) / 2; break;     // 左中
        case 5: $x = ($srcImg_w - $logow) / 2; $y = ($srcImg_h - $logoh) / 2; break; // 中心
        case 6: $x = $srcImg_w - $logow - 5; $y = ($srcImg_h - $logoh) / 2; break; // 右中
        case 7: $x = 5; $y = $srcImg_h - $logoh - 5; break;       // 左下
        case 8: $x = ($srcImg_w - $logow) / 2; $y = $srcImg_h - $logoh - 5; break; // 下中
        case 9: $x = $srcImg_w - $logow - 5; $y = $srcImg_h - $logoh - 5; break; // 右下
        default: die("不支持的位置");
    }
    
    // 創建目標畫布並合成
    $dst_img = @imagecreatetruecolor($srcImg_w, $srcImg_h);
    imagecopy($dst_img, $srcim, 0, 0, 0, 0, $srcImg_w, $srcImg_h);
    
    if ($markType == "img") {
        imagecopy($dst_img, $markim, $x, $y, 0, 0, $logow, $logoh);
        imagedestroy($markim);
    }
    
    if ($markType == "text") {
        $rgb = explode(',', $TextColor);
        $color = imagecolorallocate($dst_img, $rgb[0], $rgb[1], $rgb[2]);
        imagettftext($dst_img, $fontSize, 0, $x, $y, $color, $fontType, $markText);
    }
    
    // 保存覆蓋原圖
    switch ($srcInfo[2]) {
        case 1: imagegif($dst_img, $imgSrc); break;
        case 2: imagejpeg($dst_img, $imgSrc, 90); break; // 可設置質量
        case 3: imagepng($dst_img, $imgSrc); break;
    }
    
    imagedestroy($dst_img);
    imagedestroy($srcim);
}
?>

五、集成到 CKEditor 上傳流程

在 commands.php 的 FileUpload 函數中,文件保存成功後調用:

<?php
// 圖片水印集成示例
if (in_array(strtolower($sExtension), ['jpg', 'jpeg', 'png', 'gif'])) {
    $uploadedFile = $Config['UserFilesAbsolutePath'] . $sFileName;
    
    // 圖片水印模式
    setWater($uploadedFile, 'mark/logo.png', '', '', 9, '', 'img');
    
    // 或文字水印模式
    // setWater($uploadedFile, '', '© MySite.com', '255,255,255', 5, '/fonts/simhei.ttf', 'text');
}
?>

六、關鍵注意事項

  • GD 庫依賴:需啟用 php_gd2 擴展,文字水印額外需 freetype 支持
  • 透明度處理:imagecreatetruecolor 創建黑色背景,PNG/GIF 透明圖需額外處理透明通道
  • 性能考量:大圖水印消耗內存大,建議異步隊列處理或限制上傳尺寸
  • 權限設置:上傳目錄需 Web 服務器寫入權限(Linux 下通常 755 + 所有者 www-data)
  • 安全驗證:務必驗證 MIME 類型、文件頭、限制擴展名白名單,防止腳本上傳

通過以上配置,可構建企業級的 CKEditor 文件上傳系統,滿足歸檔管理、版權保護、安全合規等多重需求。

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