<?php
/**
* Connect by cURL with
* FTP with Implicit SSL/TLS
* or Explicit SFTP.
*
* Simple wrapper for cURL functions to transfer a file.
*/
class Curl_Connect {
private $ch;
private $url;
public function __construct($protocol, $implicit, $server, $port = 990, $username, $password, $remote_path = '', $passive_mode = false) {
// check for blank protocol
if (!$protocol)
throw new Exception('Protocol is blank.');
// check for blank username
if (!$username)
throw new Exception('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.');
// set host/initial path
$this->url = $protocol.'://'.$server.'/'.$remote_path;
// setup connection
$this->ch = curl_init();
// check for successful connection
if (!$this->ch)
throw new Exception('Could not initialize cURL.');
// connection options
$options = [
CURLOPT_USERPWD => $username.':'.$password,
CURLOPT_PORT => $port,
CURLOPT_TIMEOUT => 30,
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)
];
// 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] = '-';
// If implicit mode
if ($implicit) {
$options[CURLOPT_SSL_VERIFYPEER] = false;
$options[CURLOPT_SSL_VERIFYHOST] = false;
} else { // No implicit mode
$options[CURLOPT_SSL_VERIFYPEER] = true;
$options[CURLOPT_SSL_VERIFYHOST] = true;
}
// 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->ch, $option_name, $option_value))
throw new Exception(sprintf('Could not set cURL option: %s', $option_name));
}
}
public function upload($remote_file, $local_file) {
curl_setopt($this->ch, CURLOPT_UPLOAD, true);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, false);
// set file name
if (!curl_setopt($this->ch, CURLOPT_URL, $this->url.$remote_file))
throw new Exception ("Could not set cURL file name: $remote_file");
// open memory stream for writing
$stream = fopen('php://temp', 'w+');
// check for valid stream handle
if (!$stream)
throw new Exception('Could not open php://temp for writing.');
// write file into the temporary stream
fwrite($stream, file_get_contents($local_file));
// rewind the stream pointer
rewind($stream);
// set the file to be uploaded
if (!curl_setopt($this->ch, CURLOPT_INFILE, $stream))
throw new Exception("Could not load file $remote_file");
// upload file
if (!curl_exec($this->ch))
throw new Exception(sprintf('Could not upload file. cURL Error: [%s] - %s', curl_errno($this->ch), curl_error($this->ch)));
// close the stream handle
fclose($stream);
}
public function download($remote_file, $local_file)
{
curl_setopt($this->ch, CURLOPT_UPLOAD, false);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
// set file name
if (!curl_setopt($this->ch, CURLOPT_URL, $this->url.$remote_file))
throw new Exception("Could not set cURL file name: $remote_file");
$content = curl_exec($this->ch);
$file_handle = fopen($local_file, "w+");
fputs($file_handle, $content);
fclose($file_handle);
}
public function __destruct() {
@curl_close($this->ch);
}
}