含Unicode字符的PDF文件上传后无法访问(404错误)问题
I see exactly what's going on here—your upload works fine, but when the filename includes Unicode characters (like non-English letters, emojis, or special symbols), the server can't locate the file later due to mismatched URL encoding. Let's break down the problem and fix it step by step.
The Root Cause
Your current code only handles space-to-hyphen conversion and lowercase formatting, but it completely ignores Unicode characters. When you upload a file with a Unicode name, it gets saved to your server with the raw Unicode filename. However, when you try to access it via a URL, browsers automatically encode those Unicode characters into UTF-8 percent-encoding (e.g., "中文.pdf" becomes "%E4%B8%AD%E6%96%87.pdf"). If your server isn't properly mapping this encoded URL back to the actual Unicode filename stored on disk, it throws a 404 "Object not found" error.
Fixes to Implement
Here are two reliable solutions to resolve this issue:
Solution 1: Use URL-Safe Encoding for Filenames
Modify your filename handling code to convert Unicode characters into URL-safe percent-encoding, so the stored filename matches what the browser sends when accessing the file:
$maxsize = 10485760; $format = array('application/pdf'); if ($_FILES['file']['size'] >= $maxsize) { $error_1 = 'File Size too large upload files less than 10MB'; echo '<script>alert("'.$error_1. '")</script>'; ?> <script>window.location = "add_files_dev.php";</script> <?php } elseif($_FILES['file']['size']==0){ $error_2='Invalid File'; echo '<script>alert("'.$error_2.'")</script>'; } elseif(!in_array($_FILES['file']['type'],$format)){ $error_3='Format Not Supported.Only .PDF files are accepted'; echo '<script>alert("'.$error_3.'")</script>'; ?> <script>window.location = "add_files_dev.php";</script> <?php } else { // Encode the original filename to make it URL-safe $safe_original_name = rawurlencode($_FILES['file']['name']); // Keep your random prefix, replace encoded spaces with hyphens if preferred $file = rand(1000, 100000). "-". $safe_original_name; $file_loc = $_FILES['file']['tmp_name']; $folder = "uploads/"; // Convert to lowercase and replace %20 (encoded spaces) with hyphens $final_file = str_replace('%20', '-', strtolower($file)); } move_uploaded_file($file_loc, $folder.$final_file);
This ensures the filename stored on disk uses the same percent-encoding that browsers use in URLs, so the server can match them correctly every time.
Solution 2: Generate a Pure ASCII Filename (Most Reliable)
If you want to avoid encoding issues entirely, generate a unique ASCII filename using a hash of the file content plus a random prefix. This also prevents filename collisions:
$maxsize = 10485760; $format = array('application/pdf'); if ($_FILES['file']['size'] >= $maxsize) { $error_1 = 'File Size too large upload files less than 10MB'; echo '<script>alert("'.$error_1. '")</script>'; ?> <script>window.location = "add_files_dev.php";</script> <?php } elseif($_FILES['file']['size']==0){ $error_2='Invalid File'; echo '<script>alert("'.$error_2.'")</script>'; } elseif(!in_array($_FILES['file']['type'],$format)){ $error_3='Format Not Supported.Only .PDF files are accepted'; echo '<script>alert("'.$error_3.'")</script>'; ?> <script>window.location = "add_files_dev.php";</script> <?php } else { // Extract the file extension from the original name $file_ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION); // Generate a unique ASCII filename using MD5 hash of the file + random prefix $unique_filename = rand(1000, 100000) . "-" . md5_file($_FILES['file']['tmp_name']) . "." . $file_ext; $file_loc = $_FILES['file']['tmp_name']; $folder = "uploads/"; $final_file = strtolower($unique_filename); } move_uploaded_file($file_loc, $folder.$final_file);
With this approach, you never have to deal with Unicode filenames on the server—all files have safe, unique ASCII names. Just make sure to store the original filename in your database if you need to display it to users later.
Additional Notes
- Ensure your server's file system supports UTF-8 encoding (most modern systems like Linux ext4 do, but Windows may need additional configuration).
- Double-check that your
uploads/directory has correct write permissions for the server process. - When generating download links for users, make sure the link uses the same filename format you stored (either encoded or the hash-based name).
内容的提问来源于stack exchange,提问作者manjoo

