2010年3月19日 星期五

將WEB上傳的檔案轉存到FTP-ColdFusion

一般來說,使用ColdFusion指令讓使用者上傳檔案,並不是什麼大難題,你可以下個指令就可以完成了。

<cffile action="upload" filefield="upfile" destination="C:\InetPub\wwwroot\uploads" >

假如,除了WEB伺服器外你還有FTP伺服器提供給客戶使用不同方式上傳檔案的話,當客戶習慣於不同場合由不同伺服器上傳檔案,這樣你會很難將客戶的檔案統一管理,你必須頻於WEB伺服器與FTP伺服器間處理客戶上傳的檔案,這時如果又有另一部(或多部)WEB伺服器加入戰局,你可以想像要管理分散在各處的客戶上傳檔案,會是相當惱人的了。因此簡單的作法是將客戶上傳的檔案全部導向同一部伺服器上,以減少分散的管理問題。



此時,就可以利用ColdFusion的FTP指令了,建議的方式是由FTP伺服器來統籌接受客戶的檔案,利用ColdFusion上傳檔案後轉傳FTP即可了。

舉例設計一個表單讓使用者上傳一個檔案:


<form id="upform" name="upform" method="post" action="uploads.cfm" enctype="multipart/form-data">
    <div>
        檔案:<input name="upFile" type="File" size="40" />
        <!--- 使用者帳號已驗證過的 --->
        <input name="custID" type="hidden" value="A0128565" />
    </div>
    <input name="btnUpload" type="button" value="上  傳" onclick="fmSubmit();">
</form>


而接受檔案的uploads.cfm:


<cfif isDefined("upFile") and isDefined("custID") >
  <cfset dirpath = "C:\InetPub\wwwroot\temp" >


  <cfif DirectoryExists(dirpath)>
    <!--- 上傳檔案 --->
    <cffile action="upload" filefield="upFile" destination="#dirpath#">
    <!--- 檢查上傳檔案是否成功 --->
    <cfif cffile.fileWasSaved IS "YES">
      <cfset file1 = cffile.clientFile>
      <cfset file2 = cffile.serverFile>
      <cfset lclfile = dirpath & "\" & file2>
      <cfset rmtdir = custID >
        <!--- 上傳到FTP --->
        <cfftp connection="ftpc" action="open" server="ftp.domain.com" username="ftpadmin" password="ftpadminpassword" stoponerror="yes">
        <cfif cfftp.Succeeded IS "YES">
          <!--- 登入FTP --->
          <!--- 檢查資料夾 --->
          <cfftp connection="ftpc" action="existsdir" directory="#rmtdir#">
          <cfif cfftp.ReturnValue IS "NO">
            <!--- 資料夾不存在就建立 --->
            <cfftp connection="ftpc" action="createdir" directory="#rmtdir#">
          </cfif>
          <!--- 切換到客戶資料夾 --->
          <cfftp connection="ftpc" action="changedir" directory="#rmtdir#">
          <cfif cfftp.Succeeded IS "YES">
            <!--- 檢查檔案是否已經存在 --->
            <cfftp connection="ftpc" action="existsfile" remotefile="#file1#">
            <cfif cfftp.ReturnValue IS "YES">
              <cfset resmsg = "上傳失敗,檔案已經存在主機上">
            <cfelse>
              <cfftp connection="ftpc" action="putfile" localfile="#lclfile#" remotefile="#file1#" transfermode="binary">
              <cfif cfftp.Succeeded IS "YES">
                <cfset resmsg = "檔案上傳成功">
              <cfelse>
                 <cfset resmsg = "上傳失敗,檔案轉送過程失敗">
              </cfif>
            </cfif>
          <cfelse>
            <!--- 資料夾切換失敗 --->
            <cfset resmsg = "上傳失敗,使用者帳戶變更失敗">
          </cfif>
          <!--- 登出FTP --->
          <cfftp connection="ftpc" action="close" stoponerror="yes">
        <cfelse>
          <!--- 登入FTP失敗 --->
          <cfset resmsg = "上傳失敗,主機連線遺失">
        </cfif>
        <!--- 刪除暫存檔 --->
        <cffile action="delete" file="#lclfile#">
    <cfelse>
      <cfset resmsg = "上傳失敗,檔案無法暫存">
    </cfif>
  <cfelse>
    <cfset resmsg = "上傳失敗,檔案無法暫存">
  </cfif>
</cfif>


原理並不難,首先檔案按照原本上傳接收方式上傳到WEB伺服器,然後由ColdFusion將該檔案轉送到FTP伺服器以後,再將WEB伺服器上的檔案刪除即可。

這段程式碼要注意的是cffile這個物件,
其中cffile.clientfile指的是檔案上傳前的檔案名稱,
而cffile.serverfile指的是檔案上傳後存檔的名稱,
在這個範例中這兩的變數的內容是相同的,

但是如果您使用的上傳指令加上 nameconflict="makeunique" 之後就可能會不一樣了

<cffile action="upload" filefield="upfile" destination="#dirpath#" nameconflict="makeunique">

這代表如果#dirpath#路徑下有著相同名稱的檔案時,
上傳的檔案將會由ColdFusion隨機產生一個檔案名稱以便存檔。
如此實際上儲存的檔案名稱便會存在cffile.serverfile中,
而與原來的客戶上傳檔案名稱cffile.clientfile不一樣了。

注意:這些範例並沒有將HTML標籤完整包含(如<HEAD>、<BODY>等等),僅顯示重點程式碼。

0 個回應: