PHP中如何获取上传文件的真实绝对路径,解决fakepath虚假路径问题
问题核心原因
你无法通过PHP获取客户端上传文件的真实本地绝对路径,这是现代浏览器的安全限制,和后端语言无关:
- 为了避免泄露用户本地文件系统的隐私信息,所有浏览器都会自动隐藏文件的真实本地路径,将
input[type=file]的路径替换为C:\fakepath\文件名的格式,该信息不会被发送到服务端,服务端不可能直接拿到客户端的原始路径。
现有代码的错误
- 前后端字段名不匹配:HTML中input的name属性为
dirpath,但PHP中读取的是$_FILES['dir'],字段名不一致会导致根本拿不到上传的文件信息。 - 逻辑错误:
$_FILES['dir']['tmp_name']是文件上传到服务端后的临时存储路径,调用file_get_contents()读取的是文件本身的内容,不是任何路径信息。
可选解决方案
如果你只是需要保留上传文件夹的层级结构(不需要真实的客户端绝对路径,只需要知道文件在上传文件夹中的相对位置),可以通过前端获取HTML5提供的webkitRelativePath属性,和文件一起提交到后端:
前端示例代码
<input type="file" name="dirpath[]" id="dirname" webkitdirectory directory multiple> <button id="uploadBtn">上传</button> <script> document.getElementById('uploadBtn').addEventListener('click', function() { const fileInput = document.getElementById('dirname'); const formData = new FormData(); // 遍历所有选中的文件 for (let i = 0; i < fileInput.files.length; i++) { const file = fileInput.files[i]; formData.append('files[]', file); // 传递文件在原文件夹中的相对路径 formData.append('relative_paths[]', file.webkitRelativePath); } // 提交请求 fetch('upload.php', { method: 'POST', body: formData }).then(res => res.text()).then(data => console.log(data)); }); </script>
后端PHP(upload.php)示例代码
<?php if (isset($_FILES['files']) && isset($_POST['relative_paths'])) { $files = $_FILES['files']; $relativePaths = $_POST['relative_paths']; $saveRoot = './upload/'; // 服务端存储上传文件的根目录 for ($i = 0; $i < count($files['name']); $i++) { $tmpPath = $files['tmp_name'][$i]; $relativePath = $relativePaths[$i]; $savePath = $saveRoot . $relativePath; // 自动创建对应的文件夹层级 $saveDir = dirname($savePath); if (!is_dir($saveDir)) { mkdir($saveDir, 0755, true); } // 移动临时文件到指定路径 move_uploaded_file($tmpPath, $savePath); echo "文件已保存到服务端路径:" . $savePath . "\n"; echo "原客户端相对路径:" . $relativePath . "\n"; } } ?>
如果你确实需要获取客户端的真实绝对路径,没有任何实现方案,该需求违背浏览器的安全设计,无法实现。
内容的提问来源于stack exchange,提问作者Sagar
相关产品推荐
相关产品推荐

