iT邦幫忙

0

(以解決)PHP 執行FTP 上傳檔案前就發生TIMEOUT 請問重新連線為甚麼會失敗?

  • 分享至 

  • xImage
<?php
class Remote_FTP_Controller {
   private $ftp_conn;
    
    public $Main_Dir;

    private $Error_Msg;

    public function __construct($ftp_server="",$ftp_username="", $ftp_password="",$ftp_ssl=false)
    {
      if(trim($ftp_server)!=""){
        $this->FTP_connect($ftp_server,$ftp_username, $ftp_password,$ftp_ssl);
      }
    }

    public function __destruct(){
      if ($this->ftp_conn) {
        ftp_close($this->ftp_conn);
      }
    }

    public function Error_Msg(){
        return $this->Error_Msg;
    }

    //FTP連線 
    //ftp_ssl true:使用SSL加密連線 , false:使用未加密連線
    public function FTP_connect($ftp_server,$ftp_username, $ftp_password,$ftp_ssl=false){
        try{
          if($ftp_ssl){
            //SSL 加密連線
            $ftp_conn=ftp_ssl_connect($ftp_server,"21");
          }else{
            //未加密連線
            $ftp_conn=ftp_connect($ftp_server);
          }

          if(!$ftp_conn){
               throw new Exception('FTP 連線失敗:請確認遠端FTP功能是否有啟用或是FTP_IP是否正確');
                
          }else{
                $this->ftp_conn= $ftp_conn;
                $this->FTP_Login($ftp_conn,$ftp_username, $ftp_password);
          }
        }catch(Exception $e){
           // $error_message = error_get_last()['message'];
            $this->Error_Msg = $e->getMessage();
        }
    }

    //設定超時
    public function FTP_TIMEOUT_SET($second){
      ftp_set_option($this->ftp_conn,FTP_TIMEOUT_SEC,$second);
    }

    //FTP登入
    private function FTP_Login($ftp_conn,$ftp_username, $ftp_password){
      try{
        $login=ftp_login($ftp_conn,$ftp_username, $ftp_password);
        if(!$login){    
          $error_message = error_get_last()['message'];  
          throw new Exception($error_message);
        }
      }catch(Exception $e){
        $this->Error_Msg = 'FTP 登入失敗:'.$e->getMessage();
      }
    }

    public function ftpConn(){
      return $this->ftp_conn;
    }

    public function FTP_Close($ftp_conn){
       ftp_close($ftp_conn);
    }

    //設定FTP連線模式 true :被動模式 ,false 主動模式
    public function Set_PASV_Mode($is_Passive=false){
        ftp_pasv($this->ftp_conn,$is_Passive);
    }

    //設定主要目錄並預設切換到主要目錄
    public function Set_Connect_Main_Dir($Dir){
          $this->Main_Dir=$Dir;
          ftp_chdir ($this->ftp_conn,$Dir);
    }


    public function FTP_List($Remote_Floder){
      $conn=$this->ftp_conn;
      $result=[];

      //切換到路徑目錄
      if(!ftp_chdir ($conn,$Remote_Floder)){

      }else{
        $folder_list = ftp_nlist($conn,".");
        if($folder_list){
          foreach ($folder_list as $folder){
            $result[]=$folder;
          }
        }
      }     
      return $result;
    }

    //資料夾上傳
    public function FTP_Folder_upload($Server_Floder,$Remote_Floder){
          $msg="";

          //若超時則重新連線
         /* if($this->Is_TIMEOUT($this->ftp_conn)){
            $this->FTP_ReConnect();
          }*/
        
          $conn=$this->ftp_conn;
      
          ftp_chdir ($conn,$this->Main_Dir);

          // 遍歷本地資料夾內的內容
          $files = scandir($Server_Floder);
        
          foreach ($files as $file) {
              if ($file === '.' || $file === '..') {
                continue;
              }
              $Servar_path=$Server_Floder."/".$file;
              $remote_path=$Remote_Floder."/".$file;
          
          if(is_dir($Servar_path)){
                // 如果是資料夾,遞迴
                $this->FTP_Folder_upload($Servar_path, $remote_path);
                $this->ftp_mkdir_recursive($remote_path);
              }else{
          
                // 如果是檔案,上傳            
                $msg=$this->FTP_upload($Remote_Floder,$Server_Floder,$file);
              }	         
          } 
          return  $msg;
    }



    //單檔(檔案)上傳
    /***
     * 
     * @param $dir: Nas路徑(不含檔名)
     * @param $Server_Path: Server檔案的路徑(不含檔名)
     * @param $File:檔名(含副檔名)
     */
    public function FTP_upload($dir,$Server_Path,$File){
      $conn=$this->ftp_conn;
      $msg="";

      $Server_file=$Server_Path."/".$File;
      if(!file_exists( $Server_file)){
        $msg = "查無此上傳路徑:(".$Server_file.")";
      }else{
          //判斷路徑是否需要新增資夾
          $this->FTP_mkdir_recursive($dir);

          //切換到路徑目錄
          ftp_chdir ($conn,$dir);

          //上傳檔案    
          $upload=ftp_put($conn, $File, $Server_file, FTP_BINARY);
          if (!$upload) {
            $error_message = error_get_last()['message'];
            //$this->Error_Msg = 'FTP 上傳失敗: ' .$error_message; 
            $msg = 'FTP 上傳失敗: ' .$error_message; 
            // $error = error_get_last();
            // $msg= $error['message'];
          } 
      }

      return $msg;
    }

    /**FTP下載資料夾
     * 遠端目錄 
     * server主要目錄
     * server資料夾(完整目錄)
     */
    public function FTP_Folder_Download($remote_folder ,$Server_Route,$Server_folder){
      $msg="";
      if($this->FTP_is_dir_exists($remote_folder)){
          //檢查Server 路徑是否存在
          if(!is_dir($Server_folder))
          {
            mkdir($Server_folder,0777,true);
          }
          
          ftp_chdir($this->ftp_conn,$remote_folder);
          
          // 獲取遠端資料夾內的檔案列表
          $files = ftp_nlist($this->ftp_conn, $remote_folder);

          foreach($files as $file){
            if ($file === '.' || $file === '..') 
            {
              continue;
            }

            $is_Floder=ftp_size($this->ftp_conn,$file);
            if($is_Floder===-1){
              // 如果是資料夾,遞迴處理
              $this->FTP_Folder_Download($file,$Server_Route,$Server_Route."/".$file);	
              //$this->FTP_Folder_Download($file,"E:/HERS"."/".$file);	
            }else{
              // 如果是檔案,下載
              $Dowlond=ftp_get($this->ftp_conn,$Server_Route."/".$file,$file,FTP_BINARY);
             
              if(!$Dowlond){
                  $error_message = error_get_last()['message'];
                  $msg =  'FTP 下載失敗: ' .$error_message;//$this->Error_Msg = 'FTP 下載失敗: ' .$error_message;     
              }

            }
          }
      }else{
        $msg="FTP查無:".$remote_folder;
      }
      return $msg;
    }

    /**FTP下載檔案
     * 遠端路徑 
     * 遠端檔名 
     * server路徑
     */
    public function FTP_File_Download($remote_file_path,$remote_file,$Server_Route){
      $file_lists = ftp_nlist($this->ftp_conn, dirname($remote_file_path));
      
      $msg ="";
      $file_exists = false;
      foreach($file_lists as $file_list){			
          $file_info = pathinfo($file_list);
      
          if($file_info["basename"] == $remote_file){
            $file_exists = true;
            break;
          }				
      }
      
      if($file_exists){
       
        $Dowlond = ftp_get($this->ftp_conn,$Server_Route,$remote_file_path,FTP_BINARY);
        if(!$Dowlond){
          $msg = "FTP下載失敗:".$remote_file_path;
        }

      }else{
        $msg = "FTP查無:".$remote_file_path;
      }
      return $msg;
  }

    //檢查遠端資料夾的大小(GB)
    public function FTP_GetFloderSize($remote_folder){       
       $ftp=$this->ftp_conn;

       $totalSize = 0;

       //獲取目錄內的所有文件和文件夾列
       $files= ftp_nlist($ftp,$remote_folder);
      
       foreach($files as $file){
          $size = ftp_size($ftp,$file);
          if($size==-1){
            //遞迴計算資料夾中的檔案
            $subfolderSize = $this->FTP_GetFloderSize($file);
            $totalSize +=$subfolderSize;
          }else{
            //文件大小
            $totalSize +=$size;
          }
       }
       //$totalSize = $totalSize !=0 ? round($totalSize /(1024*1024*1024),2):$totalSize;
       return $totalSize;
    }

    // 檢查遠端資料夾是否存在
    public function FTP_is_dir_exists($remote_dir){
        $conn=$this->ftp_conn;

        if(!ftp_chdir($conn, $remote_dir)) {
            return false;
        }
        return true;
    }

    // 新增遠端資料夾
    public function FTP_mkdir_recursive($target_path){
      $conn=$this->ftp_conn;

      //拆解目標路徑為各層資料夾
      $folders = explode('/', $target_path);
      $current_path = '';

      //切換到主到目錄
      // ftp_chdir ($conn,$this->Main_Dir);

      // 逐層檢查並新增資料夾
      foreach ($folders as $folder) {
          $current_path .= '/' . $folder;
          if(!$this->FTP_is_dir_exists($current_path)){
              $createDir = ftp_mkdir($this->ftp_conn, $current_path);
              if ($createDir) {
                //echo '成功新增資料夾: ' . $current_path;
                ftp_chdir($conn, $current_path);
              } 
              else 
              {
                // $error_message = error_get_last()['message'];
                // $this->Error_Msg = 'FTP 無法新增遠端資料夾: ' .$error_message;     
                echo 'FTP 無法新增遠端資料夾:' . $current_path;
              }
          }
      }
    }

    //刪除遠端檔案
    public function FTP_Delete($target_path){
      $conn=$this->ftp_conn;
      $msg="";
      $fileSize = ftp_size($conn, $target_path);

      if ($fileSize !== -1) {                  
            $Delete = ftp_delete($conn, $target_path);
            if(!$Delete){
              $error_message = error_get_last()['message'];
              $msg = 'FTP 刪除檔案失敗: ' . $error_message;
            }
      }
      // else{
      //   $msg = "FTP 查無此檔案:".$target_path;
      // }

      return $msg;
  }


    //刪除遠端資料夾
    public function FTP_Folder_Delete($target_path){
            $conn=$this->ftp_conn;
            $msg="";
          
            if(!$this->FTP_is_dir_exists($target_path)){
                $msg = "FTP 查無此路徑:" .$target_path;
                return  $msg;
            }
          
            // 取得資料夾內的檔案和子資料夾
            $files = ftp_nlist($conn, $target_path);
        
          foreach ($files as $file) {
              if ($file === '.' || $file === '..') 
              {
                      continue;
              }
            
            $is_Floder = ftp_size($this->ftp_conn,$file);
            if($is_Floder===-1){
                // 如果是資料夾,遞迴
              $this->FTP_Folder_Delete($file);
            }else{
              // 如果是檔案,直接刪除
              $Delete = ftp_delete($conn, $file);
                if(!$Delete){
                    $error_message = error_get_last()['message'];					
                            $msg = 'FTP 刪除檔案失敗: ' . $error_message;
                }
            }
          }
          
          if($this->FTP_is_dir_exists($target_path)){
                  // 刪除資料夾
                $Delete=ftp_rmdir($conn, $target_path);
                if(!$Delete){
                    $error_message = error_get_last()['message'];
                    $msg = 'FTP 刪除失敗: ' . $error_message;
                }
          }
          return  $msg;
    }

    //刪除Server 的檔案或資料夾
    public function Server_Delete($target_path){
      if(file_exists($target_path)){
            if(is_dir($target_path)){
              //目標路徑為資料夾
              $files = scandir($target_path);
            
              // 遍歷本地資料夾內的內容
              foreach ($files as $file) {
                  if ($file === '.' || $file === '..') {
                    continue;
                  }
                 

                  $Servar_path=$target_path."/".$file;           
                  if(is_dir($Servar_path)){
                      $this->Server_Delete( $Servar_path);
                  }else{               
                      unlink($Servar_path);
                  }	         
              } 
              rmdir($target_path);
          }else{
              //目標路徑為檔案
              unlink($target_path);
          }
      }
    }

    //刪除遠端資料夾中指定附檔名檔案
    public function FTP_FILE_EXTENSION_DEL($target_path,$target_EXTENSION){
      $conn=$this->ftp_conn;
      $msg="";

      if(!$this->FTP_is_dir_exists($target_path)){
          $msg = "FTP 查無此路徑:" .$target_path;
          return  $msg;
      }
    
      // 取得資料夾內的檔案和子資料夾
      $files = ftp_nlist($conn, $target_path);
      foreach ($files as $file) {
          if ($file === '.' || $file === '..') 
          {
                  continue;
          }
        
          $is_Floder = ftp_size($this->ftp_conn,$file);
          if($is_Floder===-1){
              // 如果是資料夾,遞迴
            $this->FTP_Folder_Delete($file);
          }else{
            //判斷附檔名,若為目標副檔名則刪除
            $file_parts = pathinfo($file);
            $extension = $file_parts["extension"];

            if(strtoupper($extension)==strtoupper($target_EXTENSION)){
              $Delete = ftp_delete($conn, $file);
              if(!$Delete){
                  $error_message = error_get_last()['message'];					
                  $msg = 'FTP 刪除檔案失敗: ' . $error_message;
              }
            }
        }
      }
    }
}

?>

測試ws

 $FTP=new Remote_FTP_Controller($this->FTP_IP, $this->FTP_USER, $this->FTP_PASSWD);
        $msg = $FTP->Error_Msg();
        if(trim($msg)==""){
            $FTP->Set_PASV_Mode(true);
            $FTP->Set_Connect_Main_Dir($this->FTP_DIR); 
           
               $msg = $FTP->FTP_Folder_upload( SerVer路徑,遠端路徑);
               if(trim($msg)==""){
                //關閉FTP連線
                    $ftpConn = $FTP->ftpConn();
                    $FTP->FTP_Close($ftpConn);
               }
       }
knvbhk iT邦新手 5 級 ‧ 2023-10-20 10:16:57 檢舉
請問可否post 你的PHP code上來呢?
qpalzm iT邦研究生 5 級 ‧ 2023-10-20 11:56:20 檢舉
以貼上
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友回答

立即登入回答