ftp_cdup() 函数需要启用FTP扩展。在使用前请确保已安装并启用FTP扩展。
ftp_cdup() 函数用于在FTP服务器上切换到当前目录的父目录。
这个函数是FTP协议中的 CDUP 命令的PHP实现,它相当于执行 ftp_chdir("..") 命令。
ftp_cdup() 等同于 ftp_chdir("..")ftp_cdup(resource $ftp_stream): bool
| 参数 | 描述 |
|---|---|
$ftp_stream |
FTP连接资源。由 ftp_connect() 或 ftp_ssl_connect() 函数返回的连接标识符。 |
truefalse| 方面 | ftp_cdup() | ftp_chdir() |
|---|---|---|
| 功能 | 切换到父目录 | 切换到指定目录 |
| 参数 | 只需要FTP连接资源 | 需要FTP连接资源和目录路径 |
| 等效操作 | ftp_chdir("..") |
无等效操作 |
| 使用场景 | 简单向上导航一层 | 导航到任意目录 |
| 灵活性 | 较低(只能向上) | 较高(可到任意目录) |
<?php
// 连接到FTP服务器
$ftp_server = "ftp.example.com";
$ftp_user = "username";
$ftp_pass = "password";
$conn_id = ftp_connect($ftp_server);
if (!$conn_id) {
die("无法连接到 $ftp_server");
}
// 登录到FTP服务器
if (@ftp_login($conn_id, $ftp_user, $ftp_pass)) {
echo "已连接到 $ftp_server,用户为 $ftp_user<br>";
} else {
echo "无法以 $ftp_user 身份登录<br>";
ftp_close($conn_id);
exit;
}
// 启用被动模式
ftp_pasv($conn_id, true);
// 获取当前目录
$current_dir = ftp_pwd($conn_id);
echo "当前目录: " . htmlspecialchars($current_dir) . "<br>";
// 切换到子目录
if (ftp_chdir($conn_id, "public_html")) {
echo "已切换到 public_html 目录<br>";
$current_dir = ftp_pwd($conn_id);
echo "当前目录: " . htmlspecialchars($current_dir) . "<br>";
// 使用 ftp_cdup() 切换到父目录
if (ftp_cdup($conn_id)) {
echo "已切换到父目录<br>";
$current_dir = ftp_pwd($conn_id);
echo "当前目录: " . htmlspecialchars($current_dir) . "<br>";
} else {
echo "无法切换到父目录<br>";
}
} else {
echo "无法切换到 public_html 目录<br>";
}
// 关闭FTP连接
ftp_close($conn_id);
?>
<?php
/**
* FTP目录导航类
*/
class FTPNavigator {
private $conn_id;
private $history = [];
public function __construct($server, $username, $password) {
$this->conn_id = ftp_connect($server);
if (!$this->conn_id) {
throw new Exception("无法连接到FTP服务器: $server");
}
if (!ftp_login($this->conn_id, $username, $password)) {
throw new Exception("FTP登录失败");
}
ftp_pasv($this->conn_id, true);
$this->recordCurrentDirectory();
}
/**
* 记录当前目录到历史
*/
private function recordCurrentDirectory() {
$current_dir = ftp_pwd($this->conn_id);
$this->history[] = $current_dir;
// 只保留最近20条历史记录
if (count($this->history) > 20) {
array_shift($this->history);
}
}
/**
* 获取当前目录
*/
public function getCurrentDirectory() {
return ftp_pwd($this->conn_id);
}
/**
* 切换到父目录
*/
public function goToParent() {
if (ftp_cdup($this->conn_id)) {
$this->recordCurrentDirectory();
return true;
}
return false;
}
/**
* 切换到指定目录
*/
public function changeDirectory($directory) {
if (ftp_chdir($this->conn_id, $directory)) {
$this->recordCurrentDirectory();
return true;
}
return false;
}
/**
* 返回到上一级目录
* 如果已经是最上级,返回false
*/
public function goUp($levels = 1) {
if ($levels < 1) {
return true;
}
$success = true;
for ($i = 0; $i < $levels; $i++) {
if (!ftp_cdup($this->conn_id)) {
$success = false;
break;
}
}
if ($success) {
$this->recordCurrentDirectory();
}
return $success;
}
/**
* 返回历史目录
*/
public function goBack($steps = 1) {
if ($steps <= 0 || $steps >= count($this->history)) {
return false;
}
$target_index = count($this->history) - $steps - 1;
$target_dir = $this->history[$target_index];
return $this->changeDirectory($target_dir);
}
/**
* 获取目录历史
*/
public function getHistory() {
return $this->history;
}
/**
* 列出当前目录内容
*/
public function listDirectory($directory = null) {
$current_dir = $this->getCurrentDirectory();
if ($directory !== null) {
if (!$this->changeDirectory($directory)) {
return false;
}
}
$files = ftp_nlist($this->conn_id, ".");
// 恢复原始目录
if ($directory !== null) {
$this->changeDirectory($current_dir);
}
return $files;
}
/**
* 关闭连接
*/
public function close() {
if ($this->conn_id) {
ftp_close($this->conn_id);
$this->conn_id = null;
}
}
public function __destruct() {
$this->close();
}
}
// 使用示例
echo "<h4>FTP目录导航示例:</h4>";
try {
// 创建导航器实例
$navigator = new FTPNavigator(
"ftp.example.com",
"username",
"password"
);
echo "当前目录: " . htmlspecialchars($navigator->getCurrentDirectory()) . "<br>";
// 切换到子目录
if ($navigator->changeDirectory("public_html")) {
echo "切换到: public_html<br>";
echo "当前目录: " . htmlspecialchars($navigator->getCurrentDirectory()) . "<br>";
// 使用 goToParent() 切换到父目录
if ($navigator->goToParent()) {
echo "返回到父目录<br>";
echo "当前目录: " . htmlspecialchars($navigator->getCurrentDirectory()) . "<br>";
}
// 切换到更深目录
$navigator->changeDirectory("public_html/images");
echo "切换到: public_html/images<br>";
// 向上移动2级
if ($navigator->goUp(2)) {
echo "向上移动2级<br>";
echo "当前目录: " . htmlspecialchars($navigator->getCurrentDirectory()) . "<br>";
}
// 显示历史记录
echo "<br><strong>目录历史:</strong><br>";
$history = $navigator->getHistory();
foreach ($history as $index => $dir) {
echo ($index + 1) . ". " . htmlspecialchars($dir) . "<br>";
}
// 列出当前目录内容
echo "<br><strong>目录列表:</strong><br>";
$files = $navigator->listDirectory();
if ($files !== false) {
foreach ($files as $file) {
echo htmlspecialchars(basename($file)) . "<br>";
}
}
}
// 自动关闭连接(析构函数会处理)
} catch (Exception $e) {
echo "<div class='alert alert-danger'>错误: " . htmlspecialchars($e->getMessage()) . "</div>";
}
?>
<?php
/**
* FTP递归目录操作类
*/
class FTPRecursiveOperations {
private $conn_id;
public function __construct($conn_id) {
$this->conn_id = $conn_id;
}
/**
* 递归创建目录
*/
public function createDirectoryRecursive($remote_path) {
$remote_path = rtrim($remote_path, '/');
$parts = explode('/', $remote_path);
$current_path = '';
foreach ($parts as $part) {
if (empty($part)) continue;
$current_path .= '/' . $part;
// 尝试切换到目录,如果失败则创建
if (!@ftp_chdir($this->conn_id, $current_path)) {
if (!ftp_mkdir($this->conn_id, $current_path)) {
return false;
}
ftp_chdir($this->conn_id, $current_path);
}
}
return true;
}
/**
* 递归删除目录
*/
public function deleteDirectoryRecursive($directory) {
// 保存当前目录
$original_dir = ftp_pwd($this->conn_id);
// 切换到目标目录
if (!ftp_chdir($this->conn_id, $directory)) {
return false;
}
// 获取目录列表
$files = ftp_nlist($this->conn_id, ".");
foreach ($files as $file) {
// 跳过 . 和 ..
if ($file == '.' || $file == '..') {
continue;
}
// 检查是否是目录
if ($this->isDirectory($file)) {
// 递归删除子目录
if (!$this->deleteDirectoryRecursive($file)) {
ftp_chdir($this->conn_id, $original_dir);
return false;
}
} else {
// 删除文件
if (!ftp_delete($this->conn_id, $file)) {
ftp_chdir($this->conn_id, $original_dir);
return false;
}
}
}
// 回到父目录
ftp_cdup($this->conn_id);
// 删除空目录
if (!ftp_rmdir($this->conn_id, $directory)) {
ftp_chdir($this->conn_id, $original_dir);
return false;
}
// 恢复原始目录
ftp_chdir($this->conn_id, $original_dir);
return true;
}
/**
* 递归上传目录
*/
public function uploadDirectoryRecursive($local_dir, $remote_dir) {
if (!is_dir($local_dir)) {
return false;
}
// 在远程创建目录
if (!$this->createDirectoryRecursive($remote_dir)) {
return false;
}
// 保存当前目录
$original_remote_dir = ftp_pwd($this->conn_id);
// 切换到远程目录
if (!ftp_chdir($this->conn_id, $remote_dir)) {
return false;
}
// 处理本地目录内容
$items = scandir($local_dir);
$success = true;
foreach ($items as $item) {
if ($item == '.' || $item == '..') {
continue;
}
$local_path = $local_dir . '/' . $item;
$remote_path = $item;
if (is_dir($local_path)) {
// 递归上传子目录
if (!$this->uploadDirectoryRecursive($local_path, $remote_path)) {
$success = false;
break;
}
} else {
// 上传文件
if (!ftp_put($this->conn_id, $remote_path, $local_path, FTP_BINARY)) {
$success = false;
break;
}
}
}
// 回到原始目录
ftp_chdir($this->conn_id, $original_remote_dir);
return $success;
}
/**
* 检查是否为目录
*/
private function isDirectory($path) {
$original_dir = ftp_pwd($this->conn_id);
// 尝试切换到路径
if (@ftp_chdir($this->conn_id, $path)) {
// 如果是目录,切换回父目录
ftp_cdup($this->conn_id);
ftp_chdir($this->conn_id, $original_dir);
return true;
}
ftp_chdir($this->conn_id, $original_dir);
return false;
}
/**
* 递归列出目录结构
*/
public function listDirectoryRecursive($directory = ".", $indent = "") {
$files = ftp_nlist($this->conn_id, $directory);
$result = [];
foreach ($files as $file) {
if ($file == '.' || $file == '..') {
continue;
}
$full_path = ($directory == ".") ? $file : $directory . '/' . $file;
$relative_path = basename($full_path);
$result[] = $indent . $relative_path;
if ($this->isDirectory($full_path)) {
// 递归列出子目录
$sub_result = $this->listDirectoryRecursive($full_path, $indent . " ");
$result = array_merge($result, $sub_result);
}
}
return $result;
}
}
// 使用示例
echo "<h4>FTP递归目录操作示例:</h4>";
// 假设已经建立了FTP连接
$ftp_server = "ftp.example.com";
$ftp_user = "username";
$ftp_pass = "password";
$conn_id = ftp_connect($ftp_server);
if (!$conn_id) {
die("无法连接到FTP服务器");
}
if (!ftp_login($conn_id, $ftp_user, $ftp_pass)) {
die("登录失败");
}
ftp_pasv($conn_id, true);
// 创建递归操作实例
$ftp_ops = new FTPRecursiveOperations($conn_id);
echo "当前目录: " . htmlspecialchars(ftp_pwd($conn_id)) . "<br><br>";
// 示例1:递归列出目录
echo "<strong>递归目录列表:</strong><br>";
$dir_list = $ftp_ops->listDirectoryRecursive();
foreach ($dir_list as $item) {
echo htmlspecialchars($item) . "<br>";
}
echo "<br>";
// 示例2:创建嵌套目录
echo "<strong>创建嵌套目录:</strong><br>";
if ($ftp_ops->createDirectoryRecursive("/test/nested/directory")) {
echo "成功创建目录结构: /test/nested/directory<br>";
} else {
echo "创建目录失败<br>";
}
// 示例3:使用 ftp_cdup() 在递归操作中
echo "<br><strong>演示 ftp_cdup() 在递归中的使用:</strong><br>";
// 先进入一个深层次目录
ftp_chdir($conn_id, "/test/nested/directory");
echo "当前目录: " . htmlspecialchars(ftp_pwd($conn_id)) . "<br>";
// 使用 ftp_cdup() 返回上级
ftp_cdup($conn_id);
echo "切换到父目录后: " . htmlspecialchars(ftp_pwd($conn_id)) . "<br>";
// 再次使用 ftp_cdup()
ftp_cdup($conn_id);
echo "再次切换到父目录: " . htmlspecialchars(ftp_pwd($conn_id)) . "<br>";
// 清理:删除测试目录
echo "<br><strong>清理测试目录:</strong><br>";
if ($ftp_ops->deleteDirectoryRecursive("/test")) {
echo "成功删除 /test 目录及其所有内容<br>";
} else {
echo "删除目录失败<br>";
}
// 关闭连接
ftp_close($conn_id);
?>
<?php
/**
* 简单的FTP文件浏览器
*/
class FTPFileBrowser {
private $conn_id;
private $current_path;
public function __construct($server, $username, $password) {
$this->conn_id = ftp_connect($server);
if (!$this->conn_id) {
throw new Exception("无法连接到FTP服务器");
}
if (!ftp_login($this->conn_id, $username, $password)) {
throw new Exception("FTP登录失败");
}
ftp_pasv($this->conn_id, true);
$this->current_path = ftp_pwd($this->conn_id);
}
/**
* 获取当前路径
*/
public function getCurrentPath() {
return $this->current_path;
}
/**
* 导航到父目录
*/
public function goToParent() {
if (ftp_cdup($this->conn_id)) {
$this->current_path = ftp_pwd($this->conn_id);
return true;
}
return false;
}
/**
* 导航到指定目录
*/
public function goToDirectory($directory) {
// 处理相对路径
if ($directory == "..") {
return $this->goToParent();
}
if (ftp_chdir($this->conn_id, $directory)) {
$this->current_path = ftp_pwd($this->conn_id);
return true;
}
return false;
}
/**
* 获取当前目录内容
*/
public function getDirectoryContents() {
$contents = [];
$raw_list = ftp_rawlist($this->conn_id, ".");
if ($raw_list === false) {
return [];
}
foreach ($raw_list as $line) {
$item = $this->parseRawListLine($line);
if ($item !== null) {
$contents[] = $item;
}
}
// 按类型和名称排序
usort($contents, function($a, $b) {
if ($a['type'] !== $b['type']) {
return ($a['type'] === 'dir') ? -1 : 1;
}
return strcasecmp($a['name'], $b['name']);
});
return $contents;
}
/**
* 解析 rawlist 输出行
*/
private function parseRawListLine($line) {
// Unix/Linux 格式解析
if (preg_match('/^([-d])([-rwxs]{9})\s+(\d+)\s+(\S+)\s+(\S+)\s+(\d+)\s+(\w{3}\s+\d+\s+[\d:]+)\s+(.+)$/', $line, $matches)) {
$type = ($matches[1] === 'd') ? 'dir' : 'file';
$permissions = $matches[2];
$size = (int)$matches[6];
$date = $matches[7];
$name = $matches[8];
return [
'type' => $type,
'name' => $name,
'size' => $size,
'permissions' => $permissions,
'date' => $date,
'is_dir' => ($type === 'dir')
];
}
// Windows 格式解析
elseif (preg_match('/^(\d{2}-\d{2}-\d{2}\s+\d{2}:\d{2}[AP]M)\s+(<DIR>|\d+)\s+(.+)$/', $line, $matches)) {
$date = $matches[1];
$size_or_dir = $matches[2];
$name = $matches[3];
if ($size_or_dir === '<DIR>') {
$type = 'dir';
$size = 0;
} else {
$type = 'file';
$size = (int)$size_or_dir;
}
return [
'type' => $type,
'name' => $name,
'size' => $size,
'permissions' => '',
'date' => $date,
'is_dir' => ($type === 'dir')
];
}
return null;
}
/**
* 获取文件大小的人类可读格式
*/
private function formatSize($bytes) {
if ($bytes == 0) return '0 B';
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = floor(log($bytes, 1024));
return round($bytes / pow(1024, $i), 2) . ' ' . $units[$i];
}
/**
* 渲染文件浏览器界面
*/
public function renderBrowser() {
$contents = $this->getDirectoryContents();
echo "<div class='ftp-browser'>";
echo "<div class='ftp-path mb-3'>";
echo "<strong>当前路径:</strong> " . htmlspecialchars($this->current_path);
echo "</div>";
// 父目录链接(如果不是根目录)
if ($this->current_path !== '/') {
echo "<div class='ftp-item mb-2'>";
echo "<a href='?action=parent' class='text-decoration-none'>";
echo "<i class='fas fa-level-up-alt'></i> 返回上级目录";
echo "</a>";
echo "</div>";
}
// 目录内容
if (empty($contents)) {
echo "<div class='alert alert-info'>目录为空</div>";
} else {
echo "<table class='table table-sm table-hover'>";
echo "<thead><tr><th>名称</th><th>类型</th><th>大小</th><th>修改时间</th></tr></thead>";
echo "<tbody>";
foreach ($contents as $item) {
$icon = $item['is_dir'] ? '<i class="fas fa-folder text-warning"></i>' :
'<i class="fas fa-file text-secondary"></i>';
$type = $item['is_dir'] ? '目录' : '文件';
$size = $item['is_dir'] ? '-' : $this->formatSize($item['size']);
echo "<tr>";
echo "<td>$icon ";
if ($item['is_dir']) {
echo "<a href='?action=enter&dir=" . urlencode($item['name']) . "' class='text-decoration-none'>";
echo htmlspecialchars($item['name']);
echo "</a>";
} else {
echo htmlspecialchars($item['name']);
}
echo "</td>";
echo "<td>$type</td>";
echo "<td>$size</td>";
echo "<td>" . htmlspecialchars($item['date']) . "</td>";
echo "</tr>";
}
echo "</tbody></table>";
}
echo "</div>";
}
/**
* 处理用户操作
*/
public function handleRequest() {
if (isset($_GET['action'])) {
switch ($_GET['action']) {
case 'parent':
$this->goToParent();
break;
case 'enter':
if (isset($_GET['dir'])) {
$this->goToDirectory($_GET['dir']);
}
break;
}
}
}
public function close() {
if ($this->conn_id) {
ftp_close($this->conn_id);
}
}
}
// 使用示例
echo "<h4>FTP文件浏览器示例:</h4>";
// 在实际应用中,这里应该从表单或配置获取FTP信息
$ftp_config = [
'server' => 'ftp.example.com',
'username' => 'username',
'password' => 'password'
];
try {
// 创建浏览器实例
$browser = new FTPFileBrowser(
$ftp_config['server'],
$ftp_config['username'],
$ftp_config['password']
);
// 处理用户操作
$browser->handleRequest();
// 渲染浏览器界面
$browser->renderBrowser();
// 显示一些统计信息
echo "<div class='mt-3 alert alert-secondary'>";
echo "<strong>FTP服务器信息:</strong><br>";
echo "服务器: " . htmlspecialchars($ftp_config['server']) . "<br>";
echo "当前路径: " . htmlspecialchars($browser->getCurrentPath());
echo "</div>";
// 关闭连接
$browser->close();
} catch (Exception $e) {
echo "<div class='alert alert-danger'>错误: " . htmlspecialchars($e->getMessage()) . "</div>";
}
?>
<?php
/**
* 安全的FTP目录操作函数
*/
class SafeFTPOperations {
private $conn_id;
public function __construct($conn_id) {
$this->conn_id = $conn_id;
}
/**
* 安全的切换到父目录
*/
public function safeCdup() {
// 获取当前目录
$current_dir = @ftp_pwd($this->conn_id);
if ($current_dir === false) {
return [
'success' => false,
'error' => '无法获取当前目录',
'code' => 'PWD_FAILED'
];
}
// 检查是否已经在根目录
if ($current_dir === '/' || $current_dir === '\\') {
return [
'success' => false,
'error' => '已经在根目录,无法切换到父目录',
'code' => 'ALREADY_AT_ROOT',
'current_dir' => $current_dir
];
}
// 尝试切换到父目录
if (!@ftp_cdup($this->conn_id)) {
return [
'success' => false,
'error' => '切换到父目录失败',
'code' => 'CDUP_FAILED',
'current_dir' => $current_dir
];
}
// 验证切换是否成功
$new_dir = @ftp_pwd($this->conn_id);
if ($new_dir === false) {
return [
'success' => false,
'error' => '切换后无法验证目录',
'code' => 'VERIFICATION_FAILED'
];
}
// 确保确实切换到了父目录
$parent_of_current = dirname($current_dir);
if ($parent_of_current === '.') {
$parent_of_current = '/';
}
if ($new_dir !== $parent_of_current) {
return [
'success' => false,
'error' => '目录切换验证失败',
'code' => 'VERIFICATION_MISMATCH',
'expected' => $parent_of_current,
'actual' => $new_dir
];
}
return [
'success' => true,
'previous_dir' => $current_dir,
'current_dir' => $new_dir,
'message' => '成功切换到父目录'
];
}
/**
* 安全地向上导航多级
*/
public function safeNavigateUp($levels = 1) {
if ($levels < 1) {
return [
'success' => true,
'message' => '无需导航',
'levels' => 0
];
}
$results = [];
$success_count = 0;
for ($i = 1; $i <= $levels; $i++) {
$result = $this->safeCdup();
$results[$i] = $result;
if ($result['success']) {
$success_count++;
} else {
// 如果某个级别失败,停止继续尝试
break;
}
}
return [
'success' => ($success_count == $levels),
'levels_attempted' => $levels,
'levels_succeeded' => $success_count,
'results' => $results,
'final_dir' => ftp_pwd($this->conn_id)
];
}
/**
* 测试FTP连接和功能
*/
public function testConnection() {
$tests = [];
$all_passed = true;
// 测试1:获取当前目录
$current_dir = @ftp_pwd($this->conn_id);
if ($current_dir === false) {
$tests[] = ['test' => 'PWD命令', 'result' => '失败', 'error' => '无法获取当前目录'];
$all_passed = false;
} else {
$tests[] = ['test' => 'PWD命令', 'result' => '通过', 'value' => $current_dir];
}
// 测试2:切换到存在的子目录(如果有)
$test_dir = "test_directory_" . time();
if (@ftp_mkdir($this->conn_id, $test_dir)) {
if (@ftp_chdir($this->conn_id, $test_dir)) {
$tests[] = ['test' => '切换到子目录', 'result' => '通过'];
// 测试3:使用 ftp_cdup() 返回
if (@ftp_cdup($this->conn_id)) {
$tests[] = ['test' => '使用CDUP返回父目录', 'result' => '通过'];
} else {
$tests[] = ['test' => '使用CDUP返回父目录', 'result' => '失败'];
$all_passed = false;
}
// 清理测试目录
@ftp_chdir($this->conn_id, "..");
@ftp_rmdir($this->conn_id, $test_dir);
} else {
$tests[] = ['test' => '切换到子目录', 'result' => '失败'];
$all_passed = false;
}
} else {
$tests[] = ['test' => '创建测试目录', 'result' => '跳过', 'note' => '可能没有创建权限'];
}
// 测试4:在根目录测试 ftp_cdup()
// 先尝试回到根目录
while (true) {
$dir = ftp_pwd($this->conn_id);
if ($dir === '/' || $dir === false) {
break;
}
if (!@ftp_cdup($this->conn_id)) {
break;
}
}
// 现在在根目录测试 ftp_cdup()
$result = @ftp_cdup($this->conn_id);
if ($result === false) {
$tests[] = ['test' => '根目录CDUP', 'result' => '通过', 'note' => '在根目录调用CDUP返回false,符合预期'];
} else {
$tests[] = ['test' => '根目录CDUP', 'result' => '警告', 'note' => '在根目录调用CDUP没有返回false'];
}
return [
'all_passed' => $all_passed,
'tests' => $tests,
'server_type' => @ftp_systype($this->conn_id)
];
}
}
// 使用示例
echo "<h4>FTP错误处理和边界情况测试:</h4>";
// 模拟FTP连接
$ftp_server = "ftp.example.com";
$ftp_user = "username";
$ftp_pass = "password";
$conn_id = @ftp_connect($ftp_server);
if (!$conn_id) {
echo "<div class='alert alert-danger'>无法连接到FTP服务器</div>";
} else {
if (!@ftp_login($conn_id, $ftp_user, $ftp_pass)) {
echo "<div class='alert alert-danger'>FTP登录失败</div>";
ftp_close($conn_id);
} else {
ftp_pasv($conn_id, true);
// 创建安全操作实例
$safe_ops = new SafeFTPOperations($conn_id);
echo "<h5>1. 连接功能测试:</h5>";
$test_results = $safe_ops->testConnection();
echo "<table class='table table-sm'>";
echo "<thead><tr><th>测试项目</th><th>结果</th><th>详细信息</th></tr></thead>";
echo "<tbody>";
foreach ($test_results['tests'] as $test) {
$result_class = '';
switch ($test['result']) {
case '通过': $result_class = 'table-success'; break;
case '失败': $result_class = 'table-danger'; break;
case '警告': $result_class = 'table-warning'; break;
default: $result_class = 'table-info';
}
echo "<tr class='$result_class'>";
echo "<td>" . htmlspecialchars($test['test']) . "</td>";
echo "<td>" . htmlspecialchars($test['result']) . "</td>";
echo "<td>";
if (isset($test['error'])) {
echo htmlspecialchars($test['error']);
} elseif (isset($test['value'])) {
echo htmlspecialchars($test['value']);
} elseif (isset($test['note'])) {
echo htmlspecialchars($test['note']);
}
echo "</td>";
echo "</tr>";
}
echo "</tbody></table>";
echo "<div class='alert " . ($test_results['all_passed'] ? 'alert-success' : 'alert-warning') . "'>";
echo "服务器类型: " . htmlspecialchars($test_results['server_type'] ?? '未知') . "<br>";
echo "所有测试: " . ($test_results['all_passed'] ? '通过' : '部分失败');
echo "</div>";
echo "<h5>2. 安全的父目录切换测试:</h5>";
// 测试安全切换到父目录
$result = $safe_ops->safeCdup();
echo "<div class='alert " . ($result['success'] ? 'alert-success' : 'alert-danger') . "'>";
echo "<strong>" . ($result['success'] ? '成功' : '失败') . "</strong><br>";
echo "信息: " . htmlspecialchars($result['message'] ?? $result['error']) . "<br>";
if (isset($result['previous_dir'])) {
echo "原目录: " . htmlspecialchars($result['previous_dir']) . "<br>";
}
if (isset($result['current_dir'])) {
echo "现目录: " . htmlspecialchars($result['current_dir']) . "<br>";
}
if (isset($result['code'])) {
echo "错误代码: " . htmlspecialchars($result['code']) . "<br>";
}
echo "</div>";
echo "<h5>3. 多级向上导航测试:</h5>";
// 先进入一个深层次目录以便测试
$test_path = "/level1/level2/level3";
@ftp_mkdir($conn_id, "level1");
@ftp_chdir($conn_id, "level1");
@ftp_mkdir($conn_id, "level2");
@ftp_chdir($conn_id, "level2");
@ftp_mkdir($conn_id, "level3");
@ftp_chdir($conn_id, "level3");
echo "当前目录: " . htmlspecialchars(ftp_pwd($conn_id)) . "<br>";
// 向上导航2级
$nav_result = $safe_ops->safeNavigateUp(2);
echo "<div class='alert " . ($nav_result['success'] ? 'alert-success' : 'alert-warning') . "'>";
echo "尝试导航: " . $nav_result['levels_attempted'] . " 级<br>";
echo "成功导航: " . $nav_result['levels_succeeded'] . " 级<br>";
echo "最终目录: " . htmlspecialchars($nav_result['final_dir']) . "<br>";
echo "</div>";
// 清理测试目录
@ftp_chdir($conn_id, "/");
@ftp_rmdir($conn_id, "level1/level2/level3");
@ftp_rmdir($conn_id, "level1/level2");
@ftp_rmdir($conn_id, "level1");
// 关闭连接
ftp_close($conn_id);
}
}
?>
ftp_cdup(),大多数FTP服务器会返回错误ftp_cdup() 等价于 ftp_chdir("..")| 函数 | 描述 |
|---|---|
ftp_chdir() |
改变FTP服务器上的当前目录 |
ftp_pwd() |
返回当前目录名 |
ftp_mkdir() |
在FTP服务器上建立新目录 |
ftp_rmdir() |
删除FTP服务器上的目录 |
ftp_nlist() |
返回指定目录的文件列表 |
ftp_rawlist() |
返回指定目录的详细列表 |
ftp_size() |
返回指定文件的大小 |
ftp_cdup() 的返回值ftp_pwd() 验证当前目录该函数是 PHP 后端函数,与浏览器无关。需要 PHP 4.0 或更高版本,且启用 FTP 扩展。