Skip to content

Commit ce25f07

Browse files
committed
New version
Added better error handling and exception throwing for critical parts. Used array syntax for defining options array for readability. Cleaned up redundant checks and improved comments for clarity. Enhanced method names and parameter names for better understanding. Added error handling for file operations like opening local files for writing. Improved readability and formatting for better code maintainability
1 parent c121d46 commit ce25f07

File tree

1 file changed

+180
-0
lines changed

1 file changed

+180
-0
lines changed

FTP_Implicit_SSL.php

+180
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
<?php
2+
/**
3+
* FTP with Implicit SSL/TLS Class
4+
*
5+
* Simple wrapper for cURL functions to transfer an ASCII file over FTP with implicit SSL/TLS
6+
*
7+
* @category Class
8+
* @author Damith Jayasinghe
9+
* @since 1.8
10+
*/
11+
12+
class FTP_Implicit_SSL {
13+
14+
/** @var resource cURL resource handle */
15+
private $curl_handle;
16+
17+
/** @var string cURL URL for upload */
18+
private $url;
19+
20+
/**
21+
* Connect to FTP server over Implicit SSL/TLS
22+
*
23+
* @param string $username
24+
* @param string $password
25+
* @param string $server
26+
* @param int $port
27+
* @param string $initial_path
28+
* @param bool $passive_mode
29+
* @throws Exception
30+
*/
31+
public function __construct($username, $password, $server, $port = 990, $initial_path = '', $passive_mode = false) {
32+
33+
// Check for blank username, password, and server
34+
if (empty($username) || empty($server)) {
35+
throw new Exception('FTP Username or Server is blank.');
36+
}
37+
38+
// Set host/initial path
39+
$this->url = "ftps://{$server}/{$initial_path}";
40+
41+
// Initialize cURL handle
42+
$this->curl_handle = curl_init();
43+
44+
// Check for successful connection
45+
if (!$this->curl_handle) {
46+
throw new Exception('Could not initialize cURL.');
47+
}
48+
49+
// Connection options
50+
$options = [
51+
CURLOPT_USERPWD => "$username:$password",
52+
CURLOPT_SSL_VERIFYPEER => false, // Don't verify SSL
53+
CURLOPT_SSL_VERIFYHOST => false,
54+
CURLOPT_FTP_SSL => CURLFTPSSL_ALL, // Require SSL for both control and data connections
55+
CURLOPT_FTPSSLAUTH => CURLFTPAUTH_DEFAULT, // Let cURL choose the FTP authentication method (either SSL or TLS)
56+
CURLOPT_UPLOAD => true,
57+
CURLOPT_PORT => $port,
58+
CURLOPT_TIMEOUT => 30,
59+
];
60+
61+
// Enable active mode if passive mode is disabled
62+
if (!$passive_mode) {
63+
$options[CURLOPT_FTPPORT] = '-';
64+
}
65+
66+
// Set connection options individually to catch errors
67+
foreach ($options as $option_name => $option_value) {
68+
if (!curl_setopt($this->curl_handle, $option_name, $option_value)) {
69+
throw new Exception("Could not set cURL option: $option_name");
70+
}
71+
}
72+
}
73+
74+
/**
75+
* Upload file to FTP server
76+
*
77+
* @param string $file_name
78+
* @param string $file
79+
* @throws Exception
80+
*/
81+
public function upload($file_name, $file) {
82+
// Set file name
83+
if (!curl_setopt($this->curl_handle, CURLOPT_URL, $this->url . $file_name)) {
84+
throw new Exception("Could not set cURL file name: $file_name");
85+
}
86+
87+
// Open memory stream for writing
88+
$stream = fopen('php://temp', 'w+');
89+
90+
// Check for valid stream handle
91+
if (!$stream) {
92+
throw new Exception('Could not open php://temp for writing.');
93+
}
94+
95+
// Write file into the temporary stream
96+
fwrite($stream, $file);
97+
98+
// Set the file to be uploaded
99+
curl_setopt($this->curl_handle, CURLOPT_INFILE, $stream);
100+
101+
// Upload file
102+
if (!curl_exec($this->curl_handle)) {
103+
throw new Exception(sprintf('Could not upload file. cURL Error: [%s] - %s', curl_errno($this->curl_handle), curl_error($this->curl_handle)));
104+
}
105+
106+
// Close the stream handle
107+
fclose($stream);
108+
}
109+
110+
/**
111+
* Get list of files on FTP server
112+
*
113+
* @return array
114+
* @throws Exception
115+
*/
116+
public function ftpfilelist() {
117+
curl_setopt($this->curl_handle, CURLOPT_URL, $this->url);
118+
curl_setopt($this->curl_handle, CURLOPT_UPLOAD, false);
119+
curl_setopt($this->curl_handle, CURLOPT_FTPLISTONLY, 1);
120+
curl_setopt($this->curl_handle, CURLOPT_RETURNTRANSFER, 1);
121+
$result = curl_exec($this->curl_handle);
122+
if ($result === false) {
123+
throw new Exception("Failed to retrieve file list. Error: " . curl_error($this->curl_handle));
124+
}
125+
return explode("\n", trim($result));
126+
}
127+
128+
/**
129+
* Download file from FTP server
130+
*
131+
* @param string $file_name
132+
* @param string $local_path
133+
* @return string
134+
* @throws Exception
135+
*/
136+
public function download($file_name, $local_path = '/') {
137+
$file = fopen("$local_path$file_name", "w");
138+
if (!$file) {
139+
throw new Exception("Failed to open local file for writing: $local_path$file_name");
140+
}
141+
curl_setopt($this->curl_handle, CURLOPT_URL, $this->url . $file_name);
142+
curl_setopt($this->curl_handle, CURLOPT_UPLOAD, false);
143+
curl_setopt($this->curl_handle, CURLOPT_FOLLOWLOCATION, 1);
144+
curl_setopt($this->curl_handle, CURLOPT_RETURNTRANSFER, 1);
145+
curl_setopt($this->curl_handle, CURLOPT_FILE, $file);
146+
if (!curl_exec($this->curl_handle)) {
147+
throw new Exception(sprintf('Failed to download file. cURL Error: [%s] - %s', curl_errno($this->curl_handle), curl_error($this->curl_handle)));
148+
}
149+
fclose($file);
150+
return "Download successful: $file_name";
151+
}
152+
153+
/**
154+
* Get remote file size
155+
*
156+
* @param string $file_name
157+
* @return int
158+
* @throws Exception
159+
*/
160+
public function remote_file_size($file_name) {
161+
curl_setopt($this->curl_handle, CURLOPT_URL, $this->url . $file_name);
162+
curl_setopt($this->curl_handle, CURLOPT_UPLOAD, false);
163+
curl_setopt($this->curl_handle, CURLOPT_RETURNTRANSFER, true);
164+
curl_setopt($this->curl_handle, CURLOPT_HEADER, true);
165+
curl_setopt($this->curl_handle, CURLOPT_NOBODY, true);
166+
$data = curl_exec($this->curl_handle);
167+
if ($data === false) {
168+
throw new Exception("Failed to get remote file size for: $file_name. Error: " . curl_error($this->curl_handle));
169+
}
170+
return curl_getinfo($this->curl_handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
171+
}
172+
173+
/**
174+
* Close cURL handle
175+
*/
176+
public function __destruct() {
177+
curl_close($this->curl_handle);
178+
}
179+
}
180+
?>

0 commit comments

Comments
 (0)