ftp_get_option() 函数获取FTP连接的各种运行时选项。
ftp_set_option()配合使用。
ftp_get_option(resource $ftp_stream, int $option): mixed
| 参数 | 描述 |
|---|---|
$ftp_stream |
必需。FTP连接的资源标识符,由ftp_connect()或ftp_ssl_connect()函数返回。 |
$option |
必需。要获取的选项名称。可以是以下常量:
|
false(如果给定的选项不支持,则返回false并生成警告)| 常量 | 值 | 描述 | 默认值 |
|---|---|---|---|
FTP_TIMEOUT_SEC |
0 | 网络操作的超时时间(秒)。设置FTP操作的超时时间,包括连接、数据传输等。 | 90秒 |
FTP_AUTOSEEK |
1 | 自动寻找位置。当恢复上传或下载时,是否自动寻找文件中的正确位置。 | true |
FTP_USEPASVADDRESS |
2 | 是否使用PASV命令返回的地址。有些FTP服务器在被动模式下返回错误的IP地址,可以设置为false来解决。 |
true |
获取FTP连接的各种选项:
<?php
// FTP服务器信息
$ftp_server = "ftp.example.com";
$ftp_user = "username";
$ftp_pass = "password";
// 建立FTP连接
$conn_id = ftp_connect($ftp_server);
if ($conn_id === false) {
die("无法连接到FTP服务器");
}
// 登录FTP服务器
if (!ftp_login($conn_id, $ftp_user, $ftp_pass)) {
ftp_close($conn_id);
die("FTP登录失败");
}
echo "FTP连接选项信息:\n";
echo "=====================\n";
// 获取超时设置
$timeout = ftp_get_option($conn_id, FTP_TIMEOUT_SEC);
if ($timeout !== false) {
echo "FTP_TIMEOUT_SEC: {$timeout} 秒\n";
} else {
echo "无法获取超时设置\n";
}
// 获取AUTOSEEK设置
$autoseek = ftp_get_option($conn_id, FTP_AUTOSEEK);
if ($autoseek !== false) {
echo "FTP_AUTOSEEK: " . ($autoseek ? "启用" : "禁用") . "\n";
}
// 获取USEPASVADDRESS设置
$usepasvaddress = ftp_get_option($conn_id, FTP_USEPASVADDRESS);
if ($usepasvaddress !== false) {
echo "FTP_USEPASVADDRESS: " . ($usepasvaddress ? "启用" : "禁用") . "\n";
}
// 尝试获取不支持的选项
$invalid_option = ftp_get_option($conn_id, 999);
if ($invalid_option === false) {
echo "\n不支持的选项返回: false\n";
}
// 关闭连接
ftp_close($conn_id);
?>
<?php
/**
* FTP连接诊断工具
*/
class FTPDiagnosticTool {
private $conn;
public function __construct($host, $username, $password, $port = 21, $timeout = 30) {
$this->conn = ftp_connect($host, $port, $timeout);
if (!$this->conn) {
throw new Exception("无法连接到FTP服务器");
}
if (!ftp_login($this->conn, $username, $password)) {
ftp_close($this->conn);
throw new Exception("FTP登录失败");
}
}
/**
* 获取所有选项信息
*/
public function getOptionsInfo() {
$options = [
'FTP_TIMEOUT_SEC' => FTP_TIMEOUT_SEC,
'FTP_AUTOSEEK' => FTP_AUTOSEEK,
'FTP_USEPASVADDRESS' => FTP_USEPASVADDRESS,
];
$results = [];
foreach ($options as $name => $value) {
$result = ftp_get_option($this->conn, $value);
if ($result !== false) {
if ($name === 'FTP_TIMEOUT_SEC') {
$results[$name] = $result . ' 秒';
} else {
$results[$name] = $result ? 'true' : 'false';
}
} else {
$results[$name] = '不支持';
}
}
return $results;
}
/**
* 检查连接性能
*/
public function checkPerformance() {
$start_time = microtime(true);
// 获取当前目录来测试响应时间
$pwd = ftp_pwd($this->conn);
$end_time = microtime(true);
$response_time = round(($end_time - $start_time) * 1000, 2); // 毫秒
return [
'response_time' => $response_time . ' 毫秒',
'current_dir' => $pwd
];
}
/**
* 测试被动模式
*/
public function testPassiveMode() {
// 获取当前PASV地址设置
$use_pasv_address = ftp_get_option($this->conn, FTP_USEPASVADDRESS);
// 开启被动模式
$pasv_result = ftp_pasv($this->conn, true);
// 尝试列出文件来测试被动模式
$list_result = ftp_nlist($this->conn, ".");
return [
'pasv_address_setting' => $use_pasv_address ? '使用服务器返回地址' : '使用连接地址',
'pasv_mode_enabled' => $pasv_result,
'directory_listing' => $list_result !== false ? '成功' : '失败',
'file_count' => $list_result !== false ? count($list_result) : 0
];
}
/**
* 生成诊断报告
*/
public function generateReport() {
$report = [];
$report['连接选项'] = $this->getOptionsInfo();
$report['性能测试'] = $this->checkPerformance();
$report['被动模式测试'] = $this->testPassiveMode();
$report['服务器信息'] = $this->getServerInfo();
return $report;
}
/**
* 获取服务器信息
*/
private function getServerInfo() {
$info = [];
// 尝试获取系统类型
if (function_exists('ftp_systype')) {
$info['system_type'] = ftp_systype($this->conn) ?: '未知';
}
// 获取连接状态
$info['connection_status'] = is_resource($this->conn) ? '活动' : '断开';
return $info;
}
public function close() {
if (is_resource($this->conn)) {
ftp_close($this->conn);
}
}
public function __destruct() {
$this->close();
}
}
// 使用示例
try {
$diagnostic = new FTPDiagnosticTool("ftp.example.com", "username", "password");
echo "FTP连接诊断报告\n";
echo str_repeat("=", 50) . "\n\n";
$report = $diagnostic->generateReport();
foreach ($report as $section => $data) {
echo "【{$section}】\n";
echo str_repeat("-", 30) . "\n";
if (is_array($data)) {
foreach ($data as $key => $value) {
if (is_array($value)) {
echo " {$key}:\n";
foreach ($value as $subkey => $subvalue) {
echo " {$subkey}: {$subvalue}\n";
}
} else {
echo " {$key}: {$value}\n";
}
}
}
echo "\n";
}
$diagnostic->close();
} catch (Exception $e) {
echo "诊断错误: " . $e->getMessage() . "\n";
}
?>
<?php
/**
* 智能FTP连接管理器
*/
class SmartFTPManager {
private $conn;
private $options = [];
private $performance_log = [];
public function __construct($host, $username, $password) {
$this->conn = ftp_connect($host);
if (!$this->conn) {
throw new Exception("无法连接到FTP服务器");
}
if (!ftp_login($this->conn, $username, $password)) {
ftp_close($this->conn);
throw new Exception("FTP登录失败");
}
// 保存初始选项
$this->saveCurrentOptions();
}
/**
* 保存当前选项
*/
private function saveCurrentOptions() {
$this->options['timeout'] = ftp_get_option($this->conn, FTP_TIMEOUT_SEC);
$this->options['autoseek'] = ftp_get_option($this->conn, FTP_AUTOSEEK);
$this->options['use_pasv_address'] = ftp_get_option($this->conn, FTP_USEPASVADDRESS);
}
/**
* 根据操作类型优化设置
*/
public function optimizeForOperation($operation_type) {
$original_options = $this->getCurrentOptions();
switch ($operation_type) {
case 'large_file_transfer':
// 大文件传输:增加超时时间,启用断点续传
ftp_set_option($this->conn, FTP_TIMEOUT_SEC, 300);
ftp_set_option($this->conn, FTP_AUTOSEEK, true);
echo "优化为大型文件传输模式\n";
break;
case 'multiple_small_files':
// 多个小文件:减小超时时间,禁用自动寻找(因为不需要)
ftp_set_option($this->conn, FTP_TIMEOUT_SEC, 30);
ftp_set_option($this->conn, FTP_AUTOSEEK, false);
echo "优化为多个小文件传输模式\n";
break;
case 'unstable_network':
// 不稳定网络:增加超时时间,禁用PASV地址使用
ftp_set_option($this->conn, FTP_TIMEOUT_SEC, 180);
ftp_set_option($this->conn, FTP_USEPASVADDRESS, false);
echo "优化为不稳定网络模式\n";
break;
default:
// 恢复默认设置
$this->restoreDefaultOptions();
echo "使用默认设置\n";
}
return $original_options;
}
/**
* 获取当前所有选项
*/
public function getCurrentOptions() {
return [
'FTP_TIMEOUT_SEC' => ftp_get_option($this->conn, FTP_TIMEOUT_SEC),
'FTP_AUTOSEEK' => ftp_get_option($this->conn, FTP_AUTOSEEK),
'FTP_USEPASVADDRESS' => ftp_get_option($this->conn, FTP_USEPASVADDRESS)
];
}
/**
* 恢复默认选项
*/
public function restoreDefaultOptions() {
if (isset($this->options['timeout'])) {
ftp_set_option($this->conn, FTP_TIMEOUT_SEC, $this->options['timeout']);
}
if (isset($this->options['autoseek'])) {
ftp_set_option($this->conn, FTP_AUTOSEEK, $this->options['autoseek']);
}
if (isset($this->options['use_pasv_address'])) {
ftp_set_option($this->conn, FTP_USEPASVADDRESS, $this->options['use_pasv_address']);
}
}
/**
* 监控操作性能
*/
public function monitorOperation($operation_name, callable $operation) {
$start_time = microtime(true);
try {
$result = $operation();
$success = true;
} catch (Exception $e) {
$result = $e->getMessage();
$success = false;
}
$end_time = microtime(true);
$duration = round(($end_time - $start_time) * 1000, 2);
// 记录性能日志
$log_entry = [
'operation' => $operation_name,
'duration_ms' => $duration,
'success' => $success,
'timestamp' => date('Y-m-d H:i:s'),
'options' => $this->getCurrentOptions()
];
$this->performance_log[] = $log_entry;
// 如果操作时间过长,建议调整设置
if ($duration > 5000) { // 超过5秒
echo "警告: {$operation_name} 操作耗时 {$duration} 毫秒,建议增加超时时间\n";
}
return [
'result' => $result,
'duration' => $duration,
'success' => $success
];
}
/**
* 获取性能报告
*/
public function getPerformanceReport() {
if (empty($this->performance_log)) {
return "没有性能数据";
}
$total_operations = count($this->performance_log);
$successful_operations = 0;
$total_duration = 0;
foreach ($this->performance_log as $log) {
if ($log['success']) {
$successful_operations++;
}
$total_duration += $log['duration_ms'];
}
$success_rate = ($successful_operations / $total_operations) * 100;
$avg_duration = $total_duration / $total_operations;
return [
'total_operations' => $total_operations,
'successful_operations' => $successful_operations,
'success_rate' => round($success_rate, 2) . '%',
'average_duration' => round($avg_duration, 2) . ' 毫秒',
'logs' => $this->performance_log
];
}
public function getConnection() {
return $this->conn;
}
public function close() {
if (is_resource($this->conn)) {
ftp_close($this->conn);
}
}
}
// 使用示例
try {
$manager = new SmartFTPManager("ftp.example.com", "username", "password");
echo "初始连接选项:\n";
$initial_options = $manager->getCurrentOptions();
foreach ($initial_options as $key => $value) {
echo " {$key}: " . (is_bool($value) ? ($value ? 'true' : 'false') : $value) . "\n";
}
echo "\n优化为大文件传输模式:\n";
$manager->optimizeForOperation('large_file_transfer');
// 模拟大文件上传
$result = $manager->monitorOperation('大文件上传', function() use ($manager) {
$conn = $manager->getConnection();
// 这里应该是实际的上传操作
// ftp_fput($conn, "remote_large_file.zip", $local_handle, FTP_BINARY);
sleep(2); // 模拟耗时操作
return "上传成功";
});
echo "操作结果: {$result['result']} (耗时: {$result['duration']} 毫秒)\n";
// 获取性能报告
echo "\n性能报告:\n";
$report = $manager->getPerformanceReport();
if (is_array($report)) {
foreach ($report as $key => $value) {
if ($key !== 'logs') {
echo " {$key}: {$value}\n";
}
}
}
$manager->close();
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
?>
<?php
/**
* FTP选项管理器
*/
class FTPOptionsManager {
const OPTION_TIMEOUT = FTP_TIMEOUT_SEC;
const OPTION_AUTOSEEK = FTP_AUTOSEEK;
const OPTION_USEPASVADDRESS = FTP_USEPASVADDRESS;
private $conn;
private $option_history = [];
public function __construct($host, $username, $password) {
$this->conn = ftp_connect($host);
if (!$this->conn) {
throw new Exception("无法连接到FTP服务器");
}
if (!ftp_login($this->conn, $username, $password)) {
ftp_close($this->conn);
throw new Exception("FTP登录失败");
}
$this->recordOptionState("连接建立");
}
/**
* 安全获取选项值
*/
public function safeGetOption($option) {
$value = ftp_get_option($this->conn, $option);
if ($value === false) {
// 检查是否是无效选项
$last_error = error_get_last();
if ($last_error && strpos($last_error['message'], 'Unrecognized option') !== false) {
throw new Exception("不支持的FTP选项: " . $this->getOptionName($option));
}
}
return $value;
}
/**
* 安全设置选项值
*/
public function safeSetOption($option, $value) {
$old_value = $this->safeGetOption($option);
if (!ftp_set_option($this->conn, $option, $value)) {
throw new Exception("设置选项失败: " . $this->getOptionName($option));
}
$this->recordOptionChange($option, $old_value, $value);
return $old_value;
}
/**
* 记录选项状态
*/
private function recordOptionState($context) {
$state = [
'timestamp' => microtime(true),
'context' => $context,
'options' => []
];
$options = [
self::OPTION_TIMEOUT,
self::OPTION_AUTOSEEK,
self::OPTION_USEPASVADDRESS
];
foreach ($options as $option) {
try {
$value = $this->safeGetOption($option);
$state['options'][$this->getOptionName($option)] = $value;
} catch (Exception $e) {
$state['options'][$this->getOptionName($option)] = '错误: ' . $e->getMessage();
}
}
$this->option_history[] = $state;
}
/**
* 记录选项变化
*/
private function recordOptionChange($option, $old_value, $new_value) {
$change = [
'timestamp' => microtime(true),
'option' => $this->getOptionName($option),
'old_value' => $this->formatValue($old_value),
'new_value' => $this->formatValue($new_value),
'caller' => $this->getCallerInfo()
];
$this->option_history[] = [
'timestamp' => microtime(true),
'context' => '选项变更',
'change' => $change
];
}
/**
* 获取选项名称
*/
private function getOptionName($option) {
$names = [
self::OPTION_TIMEOUT => 'FTP_TIMEOUT_SEC',
self::OPTION_AUTOSEEK => 'FTP_AUTOSEEK',
self::OPTION_USEPASVADDRESS => 'FTP_USEPASVADDRESS'
];
return isset($names[$option]) ? $names[$option] : "未知选项({$option})";
}
/**
* 格式化值
*/
private function formatValue($value) {
if (is_bool($value)) {
return $value ? 'true' : 'false';
} elseif (is_int($value)) {
return (string)$value;
} else {
return var_export($value, true);
}
}
/**
* 获取调用者信息
*/
private function getCallerInfo() {
$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
if (isset($trace[2])) {
return $trace[2]['file'] . ':' . $trace[2]['line'];
}
return '未知';
}
/**
* 获取选项历史
*/
public function getOptionHistory() {
return $this->option_history;
}
/**
* 生成选项报告
*/
public function generateOptionReport() {
$report = "FTP选项监控报告\n";
$report .= str_repeat("=", 50) . "\n";
foreach ($this->option_history as $index => $entry) {
$time = date('Y-m-d H:i:s', (int)$entry['timestamp']);
$report .= "[{$time}] {$entry['context']}\n";
if (isset($entry['options'])) {
foreach ($entry['options'] as $name => $value) {
$report .= " {$name}: " . $this->formatValue($value) . "\n";
}
}
if (isset($entry['change'])) {
$change = $entry['change'];
$report .= " 变更: {$change['option']} = {$change['old_value']} -> {$change['new_value']}\n";
$report .= " 调用: {$change['caller']}\n";
}
$report .= "\n";
}
return $report;
}
/**
* 获取推荐配置
*/
public function getRecommendedConfiguration($use_case) {
$recommendations = [
'web_hosting' => [
'timeout' => 30,
'autoseek' => true,
'use_pasv_address' => true,
'notes' => '适合常规网站托管,中等超时时间'
],
'backup_server' => [
'timeout' => 300,
'autoseek' => true,
'use_pasv_address' => false,
'notes' => '适合备份服务器,长超时时间,禁用PASV地址'
],
'file_sharing' => [
'timeout' => 60,
'autoseek' => false,
'use_pasv_address' => true,
'notes' => '适合文件共享,短超时时间,禁用自动寻找'
],
'cdn_storage' => [
'timeout' => 120,
'autoseek' => true,
'use_pasv_address' => true,
'notes' => '适合CDN存储,中等超时时间'
]
];
return isset($recommendations[$use_case]) ? $recommendations[$use_case] : null;
}
/**
* 应用推荐配置
*/
public function applyRecommendedConfiguration($use_case) {
$config = $this->getRecommendedConfiguration($use_case);
if (!$config) {
throw new Exception("未知的用例: {$use_case}");
}
$this->safeSetOption(self::OPTION_TIMEOUT, $config['timeout']);
$this->safeSetOption(self::OPTION_AUTOSEEK, $config['autoseek']);
$this->safeSetOption(self::OPTION_USEPASVADDRESS, $config['use_pasv_address']);
return $config;
}
public function getConnection() {
return $this->conn;
}
public function close() {
if (is_resource($this->conn)) {
ftp_close($this->conn);
}
}
}
// 使用示例
try {
$manager = new FTPOptionsManager("ftp.example.com", "username", "password");
echo "当前选项状态:\n";
$current_state = $manager->safeGetOption(FTPOptionsManager::OPTION_TIMEOUT);
echo "超时时间: " . ($current_state !== false ? $current_state . ' 秒' : '未知') . "\n";
echo "\n应用Web托管推荐配置:\n";
$config = $manager->applyRecommendedConfiguration('web_hosting');
echo "已应用配置: {$config['notes']}\n";
echo "\n监控报告:\n";
echo $manager->generateOptionReport();
// 进行一些操作
$conn = $manager->getConnection();
$manager->safeSetOption(FTPOptionsManager::OPTION_TIMEOUT, 60);
echo "\n最终选项状态:\n";
echo "超时时间: " . $manager->safeGetOption(FTPOptionsManager::OPTION_TIMEOUT) . " 秒\n";
$manager->close();
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
?>
<?php
/**
* 带有完整错误处理的FTP选项工具
*/
class SafeFTPOptions {
private $conn;
private $last_error = null;
public function __construct($host, $username, $password, $timeout = 90) {
// 设置错误处理器
set_error_handler([$this, 'errorHandler']);
$this->conn = ftp_connect($host, 21, $timeout);
if (!$this->conn) {
$this->throwException("无法连接到FTP服务器");
}
if (!ftp_login($this->conn, $username, $password)) {
ftp_close($this->conn);
$this->throwException("FTP登录失败");
}
// 恢复错误处理器
restore_error_handler();
}
/**
* 自定义错误处理器
*/
public function errorHandler($errno, $errstr, $errfile, $errline) {
$this->last_error = [
'level' => $errno,
'message' => $errstr,
'file' => $errfile,
'line' => $errline
];
return true; // 阻止PHP默认错误处理器
}
/**
* 安全获取选项(带验证)
*/
public function getOption($option, $default = null) {
$this->last_error = null;
set_error_handler([$this, 'errorHandler']);
$value = ftp_get_option($this->conn, $option);
restore_error_handler();
if ($value === false) {
if ($this->last_error) {
// 检查是否是"Unrecognized option"错误
if (strpos($this->last_error['message'], 'Unrecognized option') !== false) {
$this->logWarning("尝试获取不支持的选项: " . $this->optionToString($option));
return $default;
} else {
$this->logError("获取选项失败", $this->last_error);
}
}
return $default;
}
return $value;
}
/**
* 验证选项值是否有效
*/
public function validateOptionValue($option, $value) {
switch ($option) {
case FTP_TIMEOUT_SEC:
return is_int($value) && $value > 0;
case FTP_AUTOSEEK:
case FTP_USEPASVADDRESS:
return is_bool($value);
default:
$this->logWarning("验证未知选项: " . $this->optionToString($option));
return true; // 对于未知选项,不进行验证
}
}
/**
* 设置选项(带验证和回滚)
*/
public function setOption($option, $value, $validate = true) {
if ($validate && !$this->validateOptionValue($option, $value)) {
throw new Exception("无效的选项值: " . var_export($value, true) .
" 对于选项: " . $this->optionToString($option));
}
// 获取旧值以便回滚
$old_value = $this->getOption($option);
set_error_handler([$this, 'errorHandler']);
$result = ftp_set_option($this->conn, $option, $value);
restore_error_handler();
if (!$result) {
if ($this->last_error) {
$this->logError("设置选项失败", $this->last_error);
}
throw new Exception("无法设置选项: " . $this->optionToString($option));
}
// 验证设置是否成功
$actual_value = $this->getOption($option);
if ($actual_value !== $value) {
// 回滚到旧值
if ($old_value !== false) {
ftp_set_option($this->conn, $option, $old_value);
}
throw new Exception("选项设置验证失败: 期望 " . var_export($value, true) .
" 但得到 " . var_export($actual_value, true));
}
$this->logInfo("选项已设置", [
'option' => $this->optionToString($option),
'old_value' => $old_value,
'new_value' => $value
]);
return $old_value;
}
/**
* 获取所有支持的选项
*/
public function getAllSupportedOptions() {
$options = [];
$test_values = [
FTP_TIMEOUT_SEC => 90,
FTP_AUTOSEEK => true,
FTP_USEPASVADDRESS => true
];
foreach ($test_values as $option => $test_value) {
$old_value = $this->getOption($option);
if ($old_value !== false) {
// 尝试设置并恢复来测试是否支持
try {
$this->setOption($option, $test_value, false);
// 恢复原值
if ($old_value !== false) {
$this->setOption($option, $old_value, false);
}
$options[$this->optionToString($option)] = true;
} catch (Exception $e) {
$options[$this->optionToString($option)] = false;
}
} else {
$options[$this->optionToString($option)] = false;
}
}
return $options;
}
/**
* 选项常量转字符串
*/
private function optionToString($option) {
$map = [
FTP_TIMEOUT_SEC => 'FTP_TIMEOUT_SEC',
FTP_AUTOSEEK => 'FTP_AUTOSEEK',
FTP_USEPASVADDRESS => 'FTP_USEPASVADDRESS'
];
return isset($map[$option]) ? $map[$option] : "未知选项({$option})";
}
/**
* 抛出异常
*/
private function throwException($message) {
restore_error_handler();
throw new Exception($message);
}
/**
* 日志方法
*/
private function logError($message, $context = []) {
error_log("[ERROR] " . $message . " " . json_encode($context));
}
private function logWarning($message, $context = []) {
error_log("[WARNING] " . $message . " " . json_encode($context));
}
private function logInfo($message, $context = []) {
error_log("[INFO] " . $message . " " . json_encode($context));
}
public function getLastError() {
return $this->last_error;
}
public function getConnection() {
return $this->conn;
}
public function close() {
if (is_resource($this->conn)) {
ftp_close($this->conn);
}
}
}
// 使用示例
try {
$ftp = new SafeFTPOptions("ftp.example.com", "username", "password");
echo "测试支持的选项:\n";
$supported_options = $ftp->getAllSupportedOptions();
foreach ($supported_options as $name => $supported) {
echo " {$name}: " . ($supported ? "支持" : "不支持") . "\n";
}
echo "\n获取超时设置:\n";
$timeout = $ftp->getOption(FTP_TIMEOUT_SEC, 90);
echo " 当前超时: {$timeout} 秒\n";
echo "\n设置新超时时间:\n";
$old_timeout = $ftp->setOption(FTP_TIMEOUT_SEC, 120);
echo " 旧超时: {$old_timeout} 秒\n";
echo " 新超时: " . $ftp->getOption(FTP_TIMEOUT_SEC) . " 秒\n";
echo "\n尝试获取不支持的选项:\n";
$invalid_option = $ftp->getOption(999, 'default_value');
echo " 结果: {$invalid_option}\n";
$ftp->close();
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
if ($ftp->getLastError()) {
echo "详细错误: " . print_r($ftp->getLastError(), true) . "\n";
}
}
?>
设置FTP操作的超时时间(秒)。这个选项影响所有网络操作,包括连接、登录、数据传输等。
// 获取当前超时设置
$current_timeout = ftp_get_option($conn, FTP_TIMEOUT_SEC);
// 设置新的超时时间
ftp_set_option($conn, FTP_TIMEOUT_SEC, 300); // 5分钟
// 验证设置
$new_timeout = ftp_get_option($conn, FTP_TIMEOUT_SEC);
echo "超时时间已设置为: {$new_timeout} 秒";
控制在恢复上传或下载时是否自动寻找文件中的正确位置。启用此选项后,当指定startpos参数时,会自动寻找文件位置。
在某些FTP服务器上,自动寻找可能导致性能问题。如果遇到问题,可以尝试禁用它。
控制是否使用PASV命令返回的IP地址。有些FTP服务器在被动模式下返回错误的IP地址,禁用此选项可以解决连接问题。
如果遇到被动模式连接问题,可以尝试:
// 禁用PASV地址使用
ftp_set_option($conn, FTP_USEPASVADDRESS, false);
// 然后开启被动模式
ftp_pasv($conn, true);
ftp_get_option()返回false可能有以下原因:
可以使用以下代码进行调试:
$value = ftp_get_option($conn, FTP_TIMEOUT_SEC);
if ($value === false) {
$error = error_get_last();
if ($error) {
echo "错误: " . $error['message'] . "\n";
}
}
<?php
function getSupportedFTPOptions() {
$supported = [];
// 测试标准选项
$test_options = [
'FTP_TIMEOUT_SEC' => FTP_TIMEOUT_SEC,
'FTP_AUTOSEEK' => FTP_AUTOSEEK,
'FTP_USEPASVADDRESS' => FTP_USEPASVADDRESS,
];
// 创建测试连接
$conn = ftp_connect('localhost', 21, 1); // 1秒超时快速失败
if ($conn) {
foreach ($test_options as $name => $constant) {
$value = @ftp_get_option($conn, $constant);
$supported[$name] = ($value !== false);
}
ftp_close($conn);
}
return $supported;
}
// 检查PHP版本
echo "PHP版本: " . PHP_VERSION . "\n";
echo "FTP扩展版本: " . (extension_loaded('ftp') ? phpversion('ftp') : '未加载') . "\n\n";
$options = getSupportedFTPOptions();
echo "支持的选项:\n";
foreach ($options as $name => $supported) {
echo " {$name}: " . ($supported ? "✓" : "✗") . "\n";
}
?>
| 选项 | 对性能的影响 | 优化建议 |
|---|---|---|
FTP_TIMEOUT_SEC |
设置过短会导致频繁超时,设置过长会占用连接资源 | 根据网络状况调整,一般为30-120秒 |
FTP_AUTOSEEK |
启用会增加少量CPU开销,但支持断点续传 | 大文件传输时启用,小文件传输时禁用 |
FTP_USEPASVADDRESS |
禁用可能导致额外的网络延迟 | 仅在遇到PASV模式问题时禁用 |
| 函数 | 描述 |
|---|---|
ftp_set_option() |
设置FTP连接的运行时选项 |
ftp_connect() |
建立FTP连接 |
ftp_pasv() |
开启或关闭被动模式 |
error_get_last() |
获取最后发生的错误 |
phpversion() |
获取PHP扩展版本 |
ftp_get_option()获取当前值