異步的文件上傳是在現代的AJAX實現的Web應用裡面經常要遇到,必須解決的問題。但是標准的AJAX類(XmlHttpRequest)無法實現傳輸文件的功能。因此,這裡討論的內容就是如何在AJAX的技術的基礎之上構建異步的文件上傳功能。在這個功能當中需要使用到內置的框及(IFRAME)來傳輸文件。這個功能實現的效果是頁面在上傳文件的時候,用戶還可以使用該頁面並且填寫文件描述。
這個例子是我們引用AJAX的經典案例進行分析的。
系統環境
· 較新版本的浏覽器。例如Opera,Firefox或者 Internet Explorer。
· PHP 4.3.0 或更高版本
· PHP 5 版本
· PHP 中的 'short_open_tag' 選項開啟(否則會發生解析錯誤)。
功能分析
通過內置的IFRAME(框架)進行文件上傳。具備包括三個部分組成。
· 在頁面中間有一個簡單的控件。這個表單的目標鏈接就是一個隱藏得IFRAME(通過 CSS的風格" display: none;"實現)並且表單裡面唯一一個控件的OnChange事件用來觸發JavaScript函數。這個函數的作用是檢查用戶提交的擴展名,然後提交表單。
· 在服務器端用PHP編寫了一個處理過程(用FILEFRAME坐注釋了)。這個處理過程用來把從客戶端上傳的文件進行檢查後保存在服務器,並且通過Javascript代碼的形式返回給用戶。返回給用戶的Javascript腳本通過"parent.window.document"更改了用戶現在正在查看的頁面,設置了文件的名稱並啟用了讓用戶提交表單的按鈕。啟用按鈕的操作是通過getElementById函數實現的。
· 在主頁面還有一個表單,它包含了用戶提交的描述和隱藏的文件名。用戶可以在文件上傳的同時填寫文件的描述。當文件上傳結束以後,用戶點擊按鈕,就可以看上傳以後返回給用戶的文件信息了。(通過返回來的文件名和用戶輸入的描述構成文件信息)。
可能你會說這麼操作不符合常理:文件在用戶確認之前就已經被提交了。如果用戶沒有提交的話,情況會如何呢。你可以自己在擴展處理被用戶放棄的文件。
這個例子把文件存儲在一個文件系統的目錄下。你需要在腳本開始運行的時候配置下這個目錄,具體的包含這個目錄信息的變量是$upload_dir 和$web_upload_dir。這裡有一個對目錄是否可寫的權限檢查。
這裡我們用到了以下幾個PHP函數:
· move_uploaded_file - 轉移一經上傳到服務器的文件
· fopen - 打開文件
· fwrite - 把內容寫入文件
· fclose - 關閉文件
· str_replace - 替換字符串
· filesize - 返回文件大小
· filemtime - 返回處理時間
你可以通過手冊查到這些函數如果使用。請注意要把HTM(<, >, &)標記替換為(<, > 和 &).
源代碼
$upload_dir = "/var/www/anyexample/aeu"; // 文件存儲的路徑
$web_upload_dir = "/aeu"; // 文件在Web目錄下的路徑
$tf = $upload_dir.'/'.md5(rand()).".test";
$f = @fopen($tf, "w");
if ($f == false)
die("Fatal error! {$upload_dir} is not writable. Set 'chmod 777 {$upload_dir}'
or something like this");
fclose($f);
unlink($tf);
//處理上傳的文件
if (isset($_POST['fileframe']))
{
$result = 'ERROR';
$result_msg = 'No FILE field found';
if (isset($_FILES['file'])) // 從浏覽器接受文件
{
if ($_FILES['file']['error'] == UPLOAD_ERR_OK) // 沒有錯誤
{
$filename = $_FILES['file']['name']; // 文件名
move_uploaded_file($_FILES['file']['tmp_name'], $upload_dir.'/'.$filename);
// 處理的主過程-轉移文件到 $upload_dir
$result = 'OK';
}
elseif ($_FILES['file']['error'] == UPLOAD_ERR_INI_SIZE)
$result_msg = 'The uploaded file exceeds the upload_max_filesize directive in php.ini';
else
$result_msg = 'Unknown error';
}
echo '';
echo '