Yii 內建 CUploadedFile 元件封裝了 $_FILES 處理,提供安全、便利的檔案上傳介面。本文展示最小可行範例:View 表單、Controller 動作、目錄自動建立與儲存邏輯。
<body>
<form action="<?php echo $this->createUrl('/test/upload'); ?>" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="hidden" name="dir" value="test" />
<input type="submit" value="Upload Image" />
</form>
</body>
重點:enctype="multipart/form-data"、隱藏欄位 dir 指定子目錄。
class TestController extends Controller {
public function actionUpload() {
$dir = isset($_REQUEST['dir']) ? $_REQUEST['dir'] : '';
$image = CUploadedFile::getInstanceByName('file');
if (!$image) {
echo 'fail: no file';
return;
}
$basePath = Yii::getPathOfAlias('webroot') . '/images/' . $dir . '/';
if (!is_dir($basePath)) {
mkdir($basePath, 0755, true); // 遞歸建立
}
$fileName = $basePath . $image->name;
$status = $image->saveAs($fileName, true); // true = 覆蓋同名檔
echo $status ? 'success' : 'fail';
}
}
CUploadedFile::getInstanceByName('file'):依表單 name 取得上傳檔案物件。Yii::getPathOfAlias('webroot'):取得 Web 根目錄實體路徑。mkdir(..., true):遞歸建立多層目錄。saveAs($path, true):第二參數控制是否覆蓋既有檔案。in_array($image->extension, ['jpg','png','gif','pdf'])。finfo_file(fopen($image->tempName), FILEINFO_MIME_TYPE) 對照白名單。$image->size < 5 * 1024 * 1024 (5MB)。uniqid() . '.' . $image->extension 避免覆蓋與路徑遍歷。.htaccess 加入 php_flag engine off 或 Nginx location ~ \.php$ { deny all; }。request->csrfToken); ?>。https://yourdomain/test/test (對應 View)。success 即上傳成功,檔案位於 webroot/images/test/原檔名。Yii 檔案上傳核心只需幾行程式碼,但生產環境務必加上驗證、隨機命名、權限隔離等安全措施。掌握 CUploadedFile 與 Yii::getPathOfAlias 兩大關鍵類,即可快速建立穩健的上傳功能。