如何在上传至数据库和移动目录前去除/替换文件名特殊字符?
Got it, let's fix the issue of handling special characters in filenames before uploading to your server and database. Special characters can cause broken file paths, database storage glitches, or even security risks like path traversal—so sanitizing filenames is a crucial step. Here's how you can adjust your code properly:
Step 1: Create a Reusable Filename Sanitization Function
First, let's build a function that cleans up filenames by removing/replacing unsafe characters, while preserving the file extension and handling edge cases (like filenames that are all special characters):
function sanitizeFilename($filename) { // Split the filename into base name and extension $extension = pathinfo($filename, PATHINFO_EXTENSION); $fileBaseName = pathinfo($filename, PATHINFO_FILENAME); // Replace all non-safe characters with underscores // Allow letters, numbers, underscores, and hyphens—adjust the regex if you need more allowed chars $cleanBaseName = preg_replace('/[^a-zA-Z0-9_\-]/', '_', $fileBaseName); // Fallback to a default name if the cleaned name is empty (e.g., original name was all special chars) if (empty($cleanBaseName)) { $cleanBaseName = 'uploaded_pdf'; } // Reconstruct the full cleaned filename return $cleanBaseName . '.' . $extension; }
Step 2: Modify Your Upload Code to Use the Sanitized Filename
Now update your main upload logic to use this function, plus add safeguards like duplicate filename handling and directory checks:
$images = array(); $upload_dir = "pdfs/"; // Define the upload directory once for efficiency // Ensure the upload directory exists (prevents move_uploaded_file failures) if (!is_dir($upload_dir)) { mkdir($upload_dir, 0755, true); } foreach ($_FILES['images']['name'] as $key => $val) { $originalFilename = $_FILES['images']['name'][$key]; $sanitizedFilename = sanitizeFilename($originalFilename); // Handle duplicate filenames to avoid overwriting existing files $finalFilename = $sanitizedFilename; $counter = 1; while (file_exists($upload_dir . $finalFilename)) { $base = pathinfo($finalFilename, PATHINFO_FILENAME); $ext = pathinfo($finalFilename, PATHINFO_EXTENSION); $finalFilename = $base . '_' . $counter . '.' . $ext; $counter++; } $upload_image = $upload_dir . $finalFilename; if (move_uploaded_file($_FILES['images']['tmp_name'][$key], $upload_image)) { $images[] = $upload_image; // Connect to DB (move this outside the loop for better performance with multiple files) $objetPdo = new PDO('mysql:host=localhost:3306;dbname=ifsi', 'root', ''); $pdoStat1 = $objetPdo->prepare('INSERT INTO pdfpublic VALUES(NULL ,:nomPdf,:pdf_file,:dateUpload)'); $pdoStat1->bindValue(':nomPdf', $_POST['NomPDF'], PDO::PARAM_STR); $pdoStat1->bindValue(':pdf_file', $finalFilename, PDO::PARAM_STR); // Store the cleaned filename in DB $pdoStat1->bindValue(':dateUpload', date("Y-m-d H:i:s"), PDO::PARAM_STR); $pdoStat1->execute(); } }
Key Details & Extra Security Tips
- Adjust Allowed Characters: If you need to support non-English filenames (e.g., accented letters), update the regex in
sanitizeFilenameto[^a-zA-Z0-9_\-À-ÖØ-öø-ÿ]to include those characters. - DB Connection Optimization: Move the PDO connection outside the loop (connect once, not per file) to reduce overhead when uploading multiple files.
- Validate File Type: For extra safety, confirm the uploaded file is actually a PDF using the
finfoextension:$finfo = new Finfo(FILEINFO_MIME_TYPE); $mime = $finfo->file($_FILES['images']['tmp_name'][$key]); if ($mime !== 'application/pdf') { // Skip invalid files or show an error message continue; }
内容的提问来源于stack exchange,提问作者user7398216

