Skip to content

Instantly share code, notes, and snippets.

@nalindaDJ
Forked from maxrice/class-ftp-implicit-ssl-tls.php
Last active February 15, 2023 05:02
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save nalindaDJ/63dea19f07dcfbbf3d33 to your computer and use it in GitHub Desktop.
Save nalindaDJ/63dea19f07dcfbbf3d33 to your computer and use it in GitHub Desktop.
<?php
/**
* FTP with Implicit SSL/TLS Class
*
* Simple wrapper for cURL functions to transfer an ASCII file over FTP with implicit SSL/TLS
*
* @category Class
* @author Max Rice / Damith Jayasinghe
* @since 1.0
*/
class FTP_Implicit_SSL {
/** @var resource cURL resource handle */
private $curl_handle;
/** @var string cURL URL for upload */
private $url;
private $err;
/**
* Connect to FTP server over Implicit SSL/TLS
*
*
* @access public
* @since 1.0
* @param string $username
* @param string $password
* @param string $server
* @param int $port
* @param string $initial_path
* @param bool $passive_mode
* @throws Exception - blank username / password / port
* @return \FTP_Implicit_SSL
*/
public function __construct( $username, $password, $server, $port = 990, $initial_path = '', $passive_mode = false ) {
// check for blank username
if ( ! $username )
throw new Exception( 'FTP Username is blank.' );
// don't check for blank password (highly-questionable use case, but still)
// check for blank server
if ( ! $server )
throw new Exception( 'FTP Server is blank.' );
// check for blank port
if ( ! $port )
throw new Exception ( 'FTP Port is blank.', WC_XML_Suite::$text_domain );
// set host/initial path
$this->url = "ftps://{$server}/{$initial_path}";
// setup connection
$this->curl_handle = curl_init();
// check for successful connection
if ( ! $this->curl_handle )
throw new Exception( 'Could not initialize cURL.' );
// connection options
$options = array(
CURLOPT_USERPWD => $username . ':' . $password,
CURLOPT_SSL_VERIFYPEER => false, // don't verify SSL
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_FTP_SSL => CURLFTPSSL_ALL, // require SSL For both control and data connections
CURLOPT_FTPSSLAUTH => CURLFTPAUTH_DEFAULT, // let cURL choose the FTP authentication method (either SSL or TLS)
CURLOPT_UPLOAD => true,
CURLOPT_PORT => $port,
CURLOPT_TIMEOUT => 30,
);
// cURL FTP enables passive mode by default, so disable it by enabling the PORT command and allowing cURL to select the IP address for the data connection
if ( ! $passive_mode )
$options[ CURLOPT_FTPPORT ] = '-';
// set connection options, use foreach so useful errors can be caught instead of a generic "cannot set options" error with curl_setopt_array()
foreach ( $options as $option_name => $option_value ) {
if ( ! curl_setopt( $this->curl_handle, $option_name, $option_value ) )
throw new Exception( sprintf( 'Could not set cURL option: %s', $option_name ) );
}
}
/**
* Write file into temporary memory and upload stream to remote file
*
* @access public
* @since 1.0
* @param string $file_name - remote file name to create
* @param string $file - file content to upload
* @throws Exception - Open remote file failure or write data failure
*/
public function upload( $file_name, $file ) {
// set file name
curl_setopt( $this->curl_handle, CURLOPT_URL, $this->url . $file_name );
// set the file to be uploaded
$fp = fopen ($file, "r");
curl_setopt( $this->curl_handle, CURLOPT_INFILE, $fp);
curl_setopt($this->curl_handle, CURLOPT_INFILESIZE, filesize($file));
// upload file
if ( ! curl_exec( $this->curl_handle ) )
throw new Exception( sprintf( 'Could not upload file. cURL Error: [%s] - %s', curl_errno( $this->curl_handle ), curl_error( $this->curl_handle ) ) );
}
/**
* @return array array of file names
* @throws Exception
*/
public function ftplist(){
if ( ! curl_setopt( $this->curl_handle, CURLOPT_URL, $this->url))
throw new Exception ("Could not set cURL directory: $this->url");
curl_setopt( $this->curl_handle, CURLOPT_UPLOAD, false);
curl_setopt( $this->curl_handle,CURLOPT_FTPLISTONLY,1);
curl_setopt( $this->curl_handle, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($this->curl_handle);
$files = explode("\n",trim($result));
if( count($files) ){
return $files;
} else {
return array();
}
//or die ($this->err = curl_error( $this->curl_handle ));
}
/**
* Download file from FTPS default directory
*
* @param $file_name
* @return string
*/
public function download($file_name,$local_path='/'){
$file = fopen("$local_path$file_name", "w");
curl_setopt( $this->curl_handle, CURLOPT_URL, $this->url . $file_name);
curl_setopt( $this->curl_handle, CURLOPT_UPLOAD, false);
curl_setopt( $this->curl_handle, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt( $this->curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $this->curl_handle, CURLOPT_FILE, $file);
$result = curl_exec($this->curl_handle);
fclose($file);
if( strlen($result) ){
return $result;
} else {
return "";
}
}
public function remote_file_size($file_name){
curl_setopt( $this->curl_handle, CURLOPT_URL, $this->url . $file_name);
curl_setopt( $this->curl_handle, CURLOPT_UPLOAD, false);
curl_setopt( $this->curl_handle, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt( $this->curl_handle, CURLOPT_HEADER, TRUE);
curl_setopt( $this->curl_handle, CURLOPT_NOBODY, TRUE);
$data = curl_exec( $this->curl_handle);
$size = curl_getinfo( $this->curl_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
return $size;
}
public function delete($file_name){
curl_setopt( $this->curl_handle, CURLOPT_URL, $this->url . $file_name);
curl_setopt( $this->curl_handle, CURLOPT_UPLOAD, false);
curl_setopt( $this->curl_handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt( $this->curl_handle, CURLOPT_HEADER, false);
//curl_setopt( $this->curl_handle, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt( $this->curl_handle, CURLOPT_QUOTE,array('DELE ' . $file_name ));
$result = curl_exec( $this->curl_handle ) or die( curl_error( $this->curl_handle ) );
$files = explode("\n",trim($result));
if( ! in_array( $file_name, $files ) ){
return $this->url . $file_name;
} else {
return 'FAILED';
}
}
/**
* Attempt to close cURL handle
* Note - errors suppressed here as they are not useful
*
* @access public
* @since 1.0
*/
public function __destruct() {
@curl_close( $this->curl_handle );
}
}
?>
@Jamb000h
Copy link

Hi! Currently if you use download() AFTER ftplist() the CURLOPT_FTPLISTONLY option is not set to false which leads to the script downloading file names instead of the actual contents.

@megadruck
Copy link

Hi

Iam using this script for transfering data via ftp through firwall. I have a problem, if there are special chars in textfile like
''
The transfer stops there and the file is missing the rest of data.

How can I fix this problem ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment