770 likes | 892 Views
伺服器端的檔案處理. 讀取檔案 - file_get_contents (). 語法: file_get_contents (filename) f ilename: 檔案路徑與名稱 讀取 成功,會 以 字串型態 傳回 讀取內容,失敗則 傳回 FALSE 。 ( 只能讀取文字型態檔案 ) 範例: $filename = "read me.txt"; $ fcontents = file_get_contents ($filename); if($ fcontents ){ $ msg =$ fcontents ; } else {
E N D
讀取檔案 - file_get_contents() • 語法:file_get_contents(filename) • filename: 檔案路徑與名稱 • 讀取成功,會以字串型態傳回讀取內容,失敗則傳回 FALSE。(只能讀取文字型態檔案) • 範例: $filename = "read me.txt"; $fcontents = file_get_contents($filename); if($fcontents){ $msg=$fcontents; } else { $msg='讀取失敗'; }
路徑符號 "/" 與 "\" 的不同 • Windows 中, 路徑符號為反斜線 "\", 例如『c:\www\test.php』。 • Unix / Linux 系統中, 路徑符號則為一般的斜線 "/", 如『/tmp/test.txt』。 • 由於 “\” 使用上比較麻煩,建議使用 “/”。如『c:/www/test.php』或是 『../dir2/test.php』。可避免特殊字元問題,程式也較具可攜性,可同時在 Windows 與 Linux 系統上運作。
寫入檔案 - file_put_contents() • 語法:file_put_contents(filenae, data, flags) • filename: 檔案路徑與名稱,若檔案不存在,會自動建立,若已存在,預設會覆寫。 • data: 欲寫入的資料(可以是字串或陣列) • flags: • 不存在,表示執行預設覆寫動作 • FILE_APPEND ,新內容會附加到舊內容之後 • LOCK_EX,鎖定該檔案,讓其他程序無法進行寫入,避免同時寫入的狀況 • file_put_contents() 寫入成功會傳回寫入長度,失敗則傳回 FALSE • 網頁程式可能多人同時存取,若正在寫入檔案時,另一個程序也同時寫入同一個檔案,會造成該檔案毀損。 • 範例 if($num= file_put_contents('output.txt', '測試資料', LOCK_EX)){ echo "共寫入 $num個位元組"; } else{ echo "寫入失敗"; }
標準檔案存取 • 開啟檔案:$fh = fopen(檔案名稱, 開啟模式) • 讀取/寫入資料:使用相關函式, 透過檔案代碼讀寫資料。 • 關閉檔案:fclose($fh)
一次讀取一行資料 - fgets() • 語法:fgets($fh) • 範例: $fh= fopen('/tmp/readfile.txt', "r"); if ( ! $fh) { die(‘無法開啟檔案’); } $str = ‘’; while (!feof($fh)) { $contents = fgets($fh); str = $str . $contents . “<br/>”; } fclose($fh);
分割字串 - explode() • 將字串依分字元進行分割,並將結果以字串陣列傳回 • explode(delimiter, string) • delimiter: 分割字元 • string: 被分割的字串 • 範例:生日為 “71 / 12 / 03”,如果想各別取出年、月、日,便需要將這個字串進行分割。 • $birthday = “71/12/03”; • $birtharray = explode(“/”, $birthday); • 結果:{‘71’, ‘12’, ‘03’}
寫入檔案 - fputs() • 語法:fputs($fh, $string) • 範例: $fh= fopen('/tmp/readfile.txt', “w"); if ( ! $fh) { die(‘無法開啟檔案’); } if (fputs($fh, ‘高雄應用科技大學’)) { echo ‘成功寫入’; } else{ echo ‘寫入失敗’; } fclose($handle);
檔案與目錄屬性 • 檢查檔案與目錄的屬性 • 練習:訪客計數器
檔案與目錄列表 • 語法:scandir(directory, sorting_order) • directory: 要讀取的目錄 • sorting_order: 排序方式 • 不存在是升冪排序 • 1是降冪排序 • scandir()會取得 directory目錄下的檔案與子目錄名稱,並以陣列傳回。 • 範例 <?php header("content-type:text/html; charset=utf8"); $dirlist = scandir('/'); foreach($dirlist as $key => $name){ echo "\$dirlist[$key] = $name <br/>"; } ?>
檔案與目錄管理 • 切換目錄:chdir(directory) • Ex: chdir(‘/home’); • 複製檔案:copy(來源檔, 目的檔) • 重新命名檔案:rename(舊檔案名稱, 新檔案名稱) • 搬移檔案: rename(舊目錄/檔案, 新目錄/檔案) • 刪除檔案:unlink(檔案名稱) • 傳回目前目錄:getcwd()
檔案上傳 • 檔案上傳的流程 • 上傳表單 • 在 PHP 中取得暫存檔的資訊 • 處理上傳檔案 • 處理多個上傳檔案 • 檔案上傳的相關設定 • 在上傳表單中設定檔案最大容量
檔案上傳的流程 • (1) 使用者透過上傳表單選擇要上傳的檔案, 然後送出檔案給伺服器。 • (2) 伺服器收到檔案後, 會將上傳的檔案儲存為暫存檔。 • (3) PHP 程式將暫存檔搬移到存放上傳檔案的目錄。 暫存檔 上傳表單 伺服器 目的位址
上傳表單 • 下面是一個簡單的上傳表單:
上傳表單 • 執行結果:
上傳表單 • (A) 表單的 action 屬性指定要處理上傳檔案的 PHP 程式。 • (B) 上傳表單一定要使用 POST 方法傳送資料, 而且務必加上 enctype = "multipart / form-data" 屬性, 才能正確上傳檔案。 • (C) INPUT 欄位的 type 屬性設定為 file, 表示此欄位可以讓使用者輸入或選擇要上傳的檔案。 • 另外, name 屬性所設定的名稱為 PHP 處理檔案上傳的依據, 所以請記得此處所設定的名稱。
上傳表單 • 上面是建立檔案上傳表單的 3 個重點, 一定要設定正確, 檔案上傳表單才能正常運作。 • 如果想要讓使用者可以一次上傳多個檔案, 只需要放置多個 INPUT 欄位即可:
上傳表單 • 執行結果:
在 PHP 中取得暫存檔的資訊 • 前面提到當使用者藉由上傳表單將檔案傳送給伺服器後, 伺服器會將檔案儲存成為暫存檔, 然後依照表單的 action 屬性, 呼叫 PHP 程式檔案來進行處理。 • 所以在 PHP 程式中, 只需要將暫存檔搬移到我們想要存放的目錄即可。 • 要搬移暫存檔, 自然必須先取得暫存檔的資訊。 • PHP 會用內建變數 $_FILES 儲存上傳暫存檔的相關屬性, 供我們運用。
在 PHP 中取得暫存檔的資訊 • 我們再來看一下前面 Ch07-07.htm 所輸出的表單: • 上面表單設定上傳檔案會由 Ch07-09.php 處理 (action 屬性), 而檔案欄位的名稱為 UpFile。
在 PHP 中取得暫存檔的資訊 • 所以在 Ch07-09.php 中, 可以藉由內建變數 $_FILES 取得的暫存檔資訊如下:
在 PHP 中取得暫存檔的資訊 • 下表列出 $_FILES['UpFile']['error'] 中可能出現的錯誤代碼:
在 PHP 中取得暫存檔的資訊 • 程式中可以藉由錯誤代碼判斷上傳是否成功。 • 如果成功, 便可以將 $_FILES['UpFile']['tmp_name'] 搬移到我們想要存放上傳檔案的目錄, 若失敗, 亦可分辨是那一種問題, 提供給使用者相關訊息。
處理上傳檔案 • 瞭解如何取得暫存檔資訊, 以及判斷是否上傳成功後, 便可以使用 PHP 來處理上傳檔案了。 • PHP 提供了 move_uploaded_file() 函式, 可以將暫存檔案搬移到指定的目錄, 並且將其更改為您想要使用的檔名。 • move_uploaded_file() 的語法如下:
處理上傳檔案 • move_uploaded_file() 會判斷 filename 參數指定的檔案是否為使用者上傳的檔案, 如果是, 則會將暫存檔搬移到 destination 參數指定的路徑與檔名。 • 成功後, 會回傳 TRUE, 否則將回傳 FALSE。 • 下面範例會處理透過 Ch07-07.htm 表單上傳的檔案:
處理上傳檔案 • 執行結果:
處理多個上傳檔案 • 前面 Ch07-08.htm 的上傳表單可以讓使用者一次上傳多個檔案:
處理多個上傳檔案 • 上面所有檔案欄位都命名 UpFile[], 故 PHP 會將其視為陣列, 由上到下分別為 UpFile[0]、UpFile[1]、UpFile[2]。 • 這些檔案欄位與上傳後暫存檔的對應關係如下:
處理多個上傳檔案 • 上面是以欄位的角度來看 $_FILES 陣列, 不過在 PHP 內部的結構中, $_FILES 陣列應該如下。
處理多個上傳檔案 • 所以我們使用 PHP 處理多個上傳檔案時, 應該先用迴圈取得一組資訊。
處理多個上傳檔案 • 例如使用 foreach 迴圈逐筆讀取 $_FILES['UpFile']['error'] 陣列, 取得其全部索引:0、1、2, 然後再使用這些索引去讀取其他資訊。 • 下面程式就是利用上述步驟, 來處理 Ch07-08.htm 表單所上傳的檔案:
處理多個上傳檔案 • 執行結果:
檔案上傳的相關設定 • 在 php.ini 的設定中, 下面幾項和檔案上傳有關係: • file_uploads:預設值是『On』時, 允許用戶端用 HTTP 協定上傳檔案。 • upload_tmp_dir:上傳檔案暫存目錄, 在 wamp5 中, 此項目的預設值是 『c:/wamp/tmp』。 • upload_max_filesize:上傳檔案可允許的最大容量, 預設值是 2 (MB)。
檔案上傳的相關設定 • 實際運用時, 此設定值可能會太小, 您可視需要自行調整。 • max_execution_time:每個 PHP 程式執行時間的最大值, 預設值為 30 秒。 • 如果您允許用戶上傳比較大的檔案, 也建議放寬此設定值, 否則當執行時間達到最大值, 不論檔案是否上傳完成, 程式都會自動結束, 導致上傳失敗。 • 更改過 php.ini 的設定後, 請記得重新啟動 Apache 伺服器, 才能讓新設定生效。
檔案上傳的相關設定 • 除了 php.ini 的設定外, 用來儲存上傳檔案的上傳目錄必須開放適當的寫入權限, 否則程式可能無法儲存檔案。 • 通常在 Windows 中, 使用者皆可寫入大多數目錄, 所以沒有這樣的權限問題。 • 但是在 Linux 剛好相反, 大多數目錄都不允許非擁有者寫入, 此時必須用 chmod 指令設定適當的權限。
在上傳表單中設定檔案最大容量 • 要設定上傳檔案的最大容量, 除了利用 php.ini 中的 upload_max_filesize 之外, 也可以在表單中利用隱藏的 input 欄位設定。 • 要製作這樣的欄位, 必須設定下面 3 項屬性: • type = "hidden" • name = "MAX_FILE_SIZE" • value = "要設定的最大值"
在上傳表單中設定檔案最大容量 • 舉例來說, 下面的 input 欄位設定上傳檔案的最大限制為 10 M 位元: • 表單欄位與 php.ini 的 upload_max_filesize 兩種設定方式如果大小不同時, 會以較小的設定為準。
7 - 5 實戰演練 - 網站伺服器檔案總管 • 利用本章介紹的技巧, 可以撰寫一個簡易的網站伺服器檔案總管。 • 使用者可透過瀏覽器瀏覽或重新命名所有的子目錄, 也可對檔案進行刪除、複製與更名 3 種操作。
程式功能 • 我們要製作的網站伺服器檔案總管具有下列功能。 • 顯示目錄列表
程式功能 • 更改目錄或檔案名稱 • 在目錄列表中, 按目錄或檔案右邊的更名連結, 會出現如下表單以便更改檔案名稱:
程式功能 • 複製檔案 • 按檔案右邊的複製連結可複製檔案:
程式功能 • 刪除檔案 • 按檔案右邊的刪除連結可刪除檔案:
程式功能 • 上傳檔案 • 按上傳檔案連結可以將檔案上傳到目前目錄:
程式架構 • 檔案總管的架構如下:
程式架構 • 切換目錄、檔案複製 / 刪除 / 更名等操作, 都是利用 GET 傳遞的 op 參數來判斷: • 當使用者在各目錄間切換時, 我們會以 $_SESSION['cwd'] 記錄目前的目錄。