Curl을 이용한 FTP 요청/처리 PHP 클래스 파일 > 그누보드5 팁자료실

그누보드5 팁자료실

Curl을 이용한 FTP 요청/처리 PHP 클래스 파일 정보

Curl을 이용한 FTP 요청/처리 PHP 클래스 파일

본문

외부 업체와 계약하여 뉴스 컨텐츠를 수급하는데, 뉴스 데이타 저장소로 FTP를 사용하기로 하였습니다. 
PHP 에는 ftp_xxx 로 시작하는 ftp 처리용 함수들이 준비되어 있어 이걸 쓰면 쉽게 끝나겠구나 생각햇었는데, 
위의 함수들을 이용했을때 ftp  서버 접속후 명령어 처리가  미묘하게 동작이 안되는 경우가 생겼습니다. 
(개발용 서버는 잘되고, 운영서버는 안되는 그런 상황) 



네트웍 환경이나, 방화벽 설정에 따른 영향일것으로 추정은 되지만, 이걸 찾는건 너무 귀찮은 작업이 될것 같아 다른 방법을 찾아보니, curl 을 통해서도 ftp 파일전송이 가능하다는걸 알게되었습니다. 
 

(PHP 5.3 이하 환경에서(5.4나 5.5도 발생할 가능성이 있음) NAT 로 내부 아이피가 변경되는 경우 pass 모드 오류가 발생하는것으로 확인되었습니다. 오류함수는 ftp_pasv 을 포함하여 몇개. 대표적인 환경이 AWS 입니다. AWS 에서 FTP 서버를 구축하는 경우 php 5.3 이하 버전에서 ftp_xxx 함수 사용시 오류가 발생할수 있습니다. 이 경우 아래 코드를 사용하세요.)

 

테스트한 코드들이 아까워서 좀더 범용적으로 사용할수 있도록 class 화 시켰습니다. 
php 의 ftp_xxxx() 함수들  때문에 고통 받는 사람들에게 도움이 되면 좋겠네요. 

미구현된 기능이 몇가지 있는데, 아직 쓰는 경우가 없어서 구현하지 않았습니다.

 


<?php
/**
 * Class CurlFTP
 */
 
class CurlFTP
{
 
    private $ftp_host = ""; //ftp 서버 호스트 주소
    private $ftp_port = 21; //ftp 서버 호스트 포트
    private $ftp_userid = ""; //ftp 서버 접속 계정아이디
    private $ftp_userpass = ""; //ftp 서버 접속 계정비밀번호
    private $is_debug_output = false;
 
    private $ftp_url = null;
    private $ftp_userpwd = null;
 
    public function __construct($host, $port = 21, $userid = "", $userpass = "") {
 
        $this->ftp_host = $host;
        $this->ftp_port = $port;
        $this->ftp_userid = $userid;
        $this->ftp_userpass = $userpass;
 
        $this->ftp_url = "ftp://{$this->ftp_host}:{$this->ftp_port}";
        if($this->ftp_userid) {
            $this->ftp_userpwd = "{$this->ftp_userid}:{$this->ftp_userpass}";
        }
    }
 
    public function __destruct() {
 
    }
 
    public function setDebug($debug) {
        $this->is_debug_output = !!$debug;
    }
 
    /**
     * ftp 파일목록을 조회한다.
     * @param $dir 디렉토리 경로, 루트폴더부터의 경로이며, 루트로 지정하는 경우는 파라메타를 공백으로 넘김
     * @return 기본 경로에 있는 파일 목록
     */
    function getList($dir) {
 
        $result = array();
 
        $ftp_url =  $this->ftp_url;
        if($dir) $ftp_url.= "$dir";
 
        $curl = curl_init();
        try {
            curl_setopt($curl, CURLOPT_URL, $ftp_url);
            curl_setopt($curl, CURLOPT_USERPWD, $this->ftp_userpwd);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_FTPLISTONLY,true);
 
            $ftp_result = curl_exec($curl);
            if(curl_errno($curl) > 0) {
                throw new Exception(curl_error($curl), curl_errno($curl));
            }
            $file_list = explode("\n", $ftp_result);
 
            foreach($file_list as $filename) {
                if(trim($filename)) {
                    $result[] = trim($filename);
                }
            }
 
            curl_close($curl);
        } catch(Exception $e) {
            $this->debugOutput($e);
        }
 
        return $result;
    }
 
 /**
     * 대상 파일을 ftp 서버에 업로드한다.
     * @param $filepathname  업로드할 대상 파일의 fullpathname
     * @param $ftp_filepathname  업로드할 ftp 서버 fullpathname
     * @return boolean 업로드 성공시 true, 실패시 false
     */
    public function putFtpFile($filepathname, $ftp_filepathname) {
        $ftp_url =  $this->ftp_url.$ftp_filepathname;
        $curl = curl_init();
        try {
            $fp = fopen($filepathname, 'r');
            $filesize = filesize($filepathname);
            curl_setopt($curl, CURLOPT_URL, $ftp_url);
            curl_setopt($curl, CURLOPT_USERPWD, $this->ftp_userpwd);
            curl_setopt($curl, CURLOPT_UPLOAD, true);
            curl_setopt($curl, CURLOPT_TIMEOUT, true);
            curl_setopt($curl, CURLOPT_INFILE, $fp);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_INFILESIZE, $filesize);
            curl_exec($curl);
            if(curl_errno($curl) > 0) {
                throw new Exception(curl_error($curl), curl_errno($curl));
            }
            fclose($fp);
            curl_close($curl);
        } catch(Exception $e) {
            $this->debugOutput($e);
        }
    }
 
    /**
     * ftp 파일 내용을 읽어서 반환한다.
     * @param $filepathname  ftp 서버내 파일 full 경로(root 부터 시작)
     * @return 파일내용, 읽기가 실패하면 null을 리턴.
     */
    public function getFtpFileContent($filepathname) {
 
        $ftp_url =  $this->ftp_url.$filepathname;
 
        $curl = curl_init();
 
        try {
 
            curl_setopt($curl, CURLOPT_URL, $ftp_url);
            curl_setopt($curl, CURLOPT_USERPWD, $this->ftp_userpwd);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt( $curl, CURLOPT_BINARYTRANSFER, true );
            curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 10 ); //용량이 큰 파일은 timeout을 늘려준다.
 
            $ftp_result = curl_exec($curl);
            if(curl_errno($curl) > 0) {
                throw new Exception(curl_error($curl), curl_errno($curl));
            }
 
            curl_close($curl);
 
            return $ftp_result;
        } catch(Exception $e) {
            $this->debugOutput($e);
        }
 
        return null;
    }
 
    /**
     * ftp 에서 지정된 파일을 다운로드한다.
     * @param $filename 다운로드할 파일
     * @param $download_filepath 다운로드후 저장할 파일 경로
     * @return bool 다운로드 성공 : true, 다운로드 실패 : false
     */
    public function downloadFile($filepathname, $download_filepath) {
 
        $ftp_url =  $this->ftp_url.$filepathname;
 
        $curl = curl_init();
 
        try {
            $download_dir = dirname($download_filepath);
 
            if(!file_exists($download_dir)) {
                throw new Exception("file directory not found!!");
            }
 
            $file = fopen($download_filepath, "w");
            curl_setopt($curl, CURLOPT_URL, $ftp_url);
            curl_setopt($curl, CURLOPT_USERPWD, $this->ftp_userpwd);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);
            curl_setopt( $curl, CURLOPT_BINARYTRANSFER, true );
            curl_setopt( $curl, CURLOPT_CONNECTTIMEOUT, 10 ); //용량이 큰 파일은 timeout을 늘려준다.
            curl_setopt( $curl, CURLOPT_FILE, $file );
 
            curl_exec ($curl);
 
            fclose($file);
 
            if(curl_errno($curl) > 0) {
                throw new Exception(curl_error($curl), curl_errno($curl));
            }
 
            curl_close($curl);
            return true;
        } catch(Exception $e) {
            $this->debugOutput($e);
        }
 
        return false;
    }
 
    /**
     * ftp 서버내 파일을 삭제한다.
     * 디렉토리는 삭제되지 않는다.
     *
     * @param $filepathname ftp 서버내 파일 full 경로(root 부터 시작)
     * @return bool
     */
    function deleteFile($filepathname) {
 
        $curl = curl_init();
 
        try {
            curl_setopt($curl, CURLOPT_URL, $this->ftp_url);
            curl_setopt($curl, CURLOPT_USERPWD, $this->ftp_userpwd);
            curl_setopt($curl, CURLOPT_POSTQUOTE, array("dele $filepathname"));
            curl_exec ($curl);
 
            if(curl_errno($curl) > 0) {
                throw new Exception(curl_error($curl), curl_errno($curl));
            }
 
            curl_close($curl);
            return true;
        } catch(Exception $e) {
            $this->debugOutput($e);
        }
 
        return false;
    }
 
 
 
    /**
     * ftp 파일 내용을 읽어서 반환한다.
     * curl을 사용하지 않는 방식
     *
     * @param $filepathaname  ftp 서버내 파일 full 경로(root 부터 시작)
     * @return null|string
     */
    function getURLFileContent($filepathaname) {
 
        $ftp_url = "ftp://{$this->ftp_userid}:{$this->ftp_userpass}@{$this->ftp_host}:{$this->ftp_port}{$filepathaname}";
 
        echo $ftp_url."\n";
 
        try {
            $contents = file_get_contents($ftp_url);
 
            /* 아래와 같이 파일스트림으로도 처리가능
            $handle = fopen($ftp_url, "r");
            $contents = "";
            while ($line = fread($handle, 1024)) {
                $contents .= $line;
            }
            fclose($handle);
            */
            return $contents;
        } catch(Exception $e) {
            $this->debugOutput($e);
        }
 
        return null;
    }
 
    /**
     * ftp 서버내 디렉토리를 삭제한다.
     * @param $pathname
     */
    function deleteDirectory($pathname) {
        //미구현
    }
 
    /**
     * ftp 서버내 디렉토리를 생성한다.
     * @param $pathname
     */
    function createDirectory($pathname) {
        //미구현
    }
 
    /**
     * ftp 서버내 파일을 특정 디렉토리로 복사한다.
     * @param $filepathname
     * @param $target_directory
     */
    function copy($filepathname, $target_directory) {
        //미구현
    }
 
    /**
     * ftp 서버내 파일을 특정 디렉토리로 이동한다.
     * @param $filepathname
     * @param $target_directory
     */
    function move($filepathname, $target_directory) {
        //미구현
    }
 
    private function debugOutput($e) {
        if($this->is_debug_output) {
            echo "ftp_url : ".$this->ftp_url."\n";
            echo "ftp_userpwd : ".$this->ftp_userpwd."\n";
            echo "errorCode : ".$e->getCode().", errorMessage : ".$e->getMessage()."\n";
        }
 
    }
 
}
추천
7

댓글 15개

전체 30 |RSS
그누보드5 팁자료실 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT