<form action="handler.php" method="POST" enctype="multipart/form-data">
<input type="text" name="username">
<input type="password" name="pwd">
<select name="role[]" multiple>
<option value="admin">管理員</option>
<option value="editor">編輯</option>
</select>
<input type="file" name="avatar">
<button type="submit">送出</button>
</form>
| 超全域陣列 | 來源 | 典型用途 |
|---|---|---|
| `$_GET` | URL 查詢字串 | 搜尋關鍵字、分頁頁碼、篩選參數 |
| `$_POST` | POST Body (urlencoded) | 登入、註冊、設定儲存 |
| `$_REQUEST` | GET+POST+COOKIE (順序可配) | **不建議直接使用**,來源模糊易導致安全漏洞 |
| `$_FILES` | multipart/form-data | 檔案上傳元資訊 |
<!-- HTML -->
<input type="checkbox" name="tags[]" value="php">
<input type="checkbox" name="tags[]" value="js">
<select name="roles[]" multiple>...</select>
<?php
// PHP 端
$tags = $_POST['tags'] ?? []; // ['php', 'js']
$roles = $_POST['roles'] ?? []; // ['admin', 'editor']
// 安全:確保為陣列
$tags = (array)($tags ?? []);
// 過濾空值
$tags = array_filter($tags, 'strlen');
?>
<?php
// upload.php
$uploadDir = __DIR__ . '/uploads/';
$maxSize = 2 * 1024 * 1024; // 2MB
$allowed = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
http_response_code(405);
exit('Method Not Allowed');
}
$file = $_FILES['avatar'] ?? null;
if (!$file || $file['error'] !== UPLOAD_ERR_OK) {
$msg = $file['error'] ?? 'No file';
exit("Upload error: $msg");
}
// 1. 檢查大小
if ($file['size'] > $maxSize) exit('File too large');
// 2. 檢查 MIME (不要信任瀏覽器提供的 type)
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($file['tmp_name']);
if (!in_array($mime, $allowed, true)) exit('Invalid file type');
// 3. 安全檔名
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
$name = bin2hex(random_bytes(16)) . '.' . $ext;
$dest = $uploadDir . $name;
// 4. 移動 (跨分區自動複製+刪除)
if (!move_uploaded_file($file['tmp_name'], $dest)) {
exit('Move failed');
}
// 5. 設定權限 (僅擁有者可讀寫)
chmod($dest, 0600);
echo json_encode(['success' => true, 'path' => '/uploads/' . $name]);
?>
// 使用 nyholm/psr7-server + laminas/laminas-httphandlerrunner
$request = ServerRequestFactory::fromGlobals();
$name = $request->getParsedBody()['username'] ?? '';
$files = $request->getUploadedFiles();
$avatar = $files['avatar'] ?? null;
if ($avatar && $avatar->getError() === UPLOAD_ERR_OK) {
$avatar->moveTo($uploadDir . $newName);
}
優點:可測試、可遷移至 Swoole/RoadRunner、統一介面處理 CLI/HTTP 請求。