PHP ftp_pwd() 函数用于获取FTP服务器上的当前工作目录。
pwd命令。
ftp_pwd(resource $ftp): string|false
| 参数 | 描述 |
|---|---|
ftp |
必需。FTP连接的标识符,由ftp_connect()或ftp_ssl_connect()返回 |
false| 函数 | 功能 | 关系 |
|---|---|---|
ftp_pwd() |
获取当前工作目录 | 基本目录查询 |
ftp_chdir() |
改变当前工作目录 | 与ftp_pwd()配合使用 |
ftp_cdup() |
切换到上级目录 | 目录导航 |
ftp_mkdir() |
创建新目录 | 创建后可能需要ftp_pwd()确认位置 |
ftp_rmdir() |
删除目录 | 删除前可能需要ftp_pwd()确认当前目录 |
ftp_nlist() |
列出目录内容 | 列出ftp_pwd()返回的目录内容 |
<?php
// 连接FTP服务器
$ftp_server = "ftp.example.com";
$ftp_user = "username";
$ftp_pass = "password";
$ftp_conn = ftp_connect($ftp_server);
if (!$ftp_conn) {
die("无法连接到 $ftp_server");
}
// 登录
if (!ftp_login($ftp_conn, $ftp_user, $ftp_pass)) {
die("登录失败");
}
// 启用被动模式
ftp_pasv($ftp_conn, true);
// 获取当前目录
$current_dir = ftp_pwd($ftp_conn);
if ($current_dir !== false) {
echo "当前目录: $current_dir\n";
// 列出当前目录内容
$file_list = ftp_nlist($ftp_conn, $current_dir);
if ($file_list !== false) {
echo "目录内容:\n";
foreach ($file_list as $file) {
echo " - $file\n";
}
}
} else {
echo "无法获取当前目录\n";
}
// 关闭FTP连接
ftp_close($ftp_conn);
?>
<?php
class FTPNavigator {
private $ftp_conn;
private $history = [];
private $max_history = 10;
public function __construct($server, $username, $password) {
$this->ftp_conn = ftp_connect($server);
if (!$this->ftp_conn) {
throw new Exception("无法连接到FTP服务器");
}
if (!ftp_login($this->ftp_conn, $username, $password)) {
throw new Exception("FTP登录失败");
}
ftp_pasv($this->ftp_conn, true);
// 记录初始目录
$this->recordCurrentDir();
}
public function getCurrentDir() {
$dir = ftp_pwd($this->ftp_conn);
if ($dir === false) {
throw new Exception("无法获取当前目录");
}
return $dir;
}
public function changeDir($directory) {
$old_dir = $this->getCurrentDir();
if (ftp_chdir($this->ftp_conn, $directory)) {
$new_dir = $this->getCurrentDir();
echo "目录切换成功: $old_dir -> $new_dir\n";
$this->recordCurrentDir();
return $new_dir;
} else {
echo "目录切换失败: 无法切换到 $directory\n";
return false;
}
}
public function goToParentDir() {
if (ftp_cdup($this->ftp_conn)) {
$new_dir = $this->getCurrentDir();
echo "切换到上级目录: $new_dir\n";
$this->recordCurrentDir();
return $new_dir;
} else {
echo "无法切换到上级目录\n";
return false;
}
}
public function listCurrentDir($detailed = false) {
$current_dir = $this->getCurrentDir();
echo "当前目录: $current_dir\n";
if ($detailed) {
// 使用 rawlist 获取详细信息
$list = ftp_rawlist($this->ftp_conn, $current_dir);
} else {
// 使用 nlist 获取简单列表
$list = ftp_nlist($this->ftp_conn, $current_dir);
}
if ($list === false) {
echo "无法列出目录内容\n";
return [];
}
echo "目录内容 (" . count($list) . " 个项目):\n";
if ($detailed) {
foreach ($list as $item) {
echo " $item\n";
}
} else {
foreach ($list as $item) {
$basename = basename($item);
// 判断是否是目录
if ($this->isDirectory($item)) {
echo " 📁 $basename/\n";
} else {
$size = ftp_size($this->ftp_conn, $item);
$size_str = ($size != -1) ? " (" . $this->formatBytes($size) . ")" : "";
echo " 📄 $basename$size_str\n";
}
}
}
return $list;
}
public function createDir($dir_name) {
$current_dir = $this->getCurrentDir();
$new_dir = rtrim($current_dir, '/') . '/' . $dir_name;
if (ftp_mkdir($this->ftp_conn, $new_dir)) {
echo "目录创建成功: $new_dir\n";
return $new_dir;
} else {
echo "目录创建失败: $new_dir\n";
return false;
}
}
public function getHistory() {
return $this->history;
}
public function goBack($steps = 1) {
if (count($this->history) <= $steps) {
echo "历史记录不足,无法后退 $steps 步\n";
return false;
}
// 移除当前记录
array_pop($this->history);
// 后退指定步数
for ($i = 1; $i < $steps; $i++) {
array_pop($this->history);
}
// 获取目标目录
$target = end($this->history);
if ($target) {
return $this->changeDir($target);
}
return false;
}
public function printPathInfo() {
$current_dir = $this->getCurrentDir();
$parts = explode('/', trim($current_dir, '/'));
echo "路径分析:\n";
echo "完整路径: $current_dir\n";
echo "目录深度: " . count($parts) . "\n";
if (!empty($parts)) {
echo "路径组成:\n";
$path_so_far = '';
foreach ($parts as $index => $part) {
$path_so_far .= '/' . $part;
echo " " . str_repeat(' ', $index) . "├── $part ($path_so_far)\n";
}
}
// 检查权限
echo "目录测试:\n";
echo " 可读取: " . ($this->canReadDir() ? '✓' : '✗') . "\n";
echo " 可写入: " . ($this->canWriteDir() ? '✓' : '✗') . "\n";
}
private function isDirectory($path) {
$current = $this->getCurrentDir();
// 尝试切换目录来判断
if (@ftp_chdir($this->ftp_conn, $path)) {
// 切换回原目录
ftp_chdir($this->ftp_conn, $current);
return true;
}
return false;
}
private function canReadDir() {
$list = @ftp_nlist($this->ftp_conn, '.');
return $list !== false;
}
private function canWriteDir() {
// 尝试创建一个临时文件来测试写入权限
$test_file = '.test_write_' . time();
$result = @ftp_put($this->ftp_conn, $test_file, 'php://memory', FTP_ASCII);
if ($result) {
// 删除测试文件
ftp_delete($this->ftp_conn, $test_file);
return true;
}
return false;
}
private function recordCurrentDir() {
$dir = $this->getCurrentDir();
$this->history[] = $dir;
// 限制历史记录长度
if (count($this->history) > $this->max_history) {
array_shift($this->history);
}
}
private function formatBytes($bytes, $precision = 2) {
if ($bytes <= 0) return '0 Bytes';
$units = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
$base = log($bytes, 1024);
$pow = floor($base);
$pow = min($pow, count($units) - 1);
return round(pow(1024, $base - $pow), $precision) . ' ' . $units[$pow];
}
public function __destruct() {
if ($this->ftp_conn) {
ftp_close($this->ftp_conn);
}
}
}
// 使用示例
try {
$nav = new FTPNavigator('localhost', 'user', 'pass');
echo "=== FTP目录导航演示 ===\n\n";
// 显示当前目录
$current_dir = $nav->getCurrentDir();
echo "初始目录: $current_dir\n\n";
// 列出目录内容
$nav->listCurrentDir();
echo "\n";
// 创建新目录
$nav->createDir('test_folder');
// 切换到新目录
$nav->changeDir('test_folder');
// 再次列出目录内容
$nav->listCurrentDir();
// 返回上级目录
$nav->goToParentDir();
// 显示路径信息
$nav->printPathInfo();
// 显示历史记录
echo "\n目录历史:\n";
$history = $nav->getHistory();
foreach ($history as $index => $dir) {
echo " [$index] $dir\n";
}
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
?>
<?php
class FTPDirectoryManager {
private $ftp_conn;
public function __construct($ftp_conn) {
$this->ftp_conn = $ftp_conn;
}
/**
* 获取当前目录的详细信息
*/
public function getDirectoryInfo($directory = null) {
if ($directory === null) {
$directory = ftp_pwd($this->ftp_conn);
if ($directory === false) {
return false;
}
}
$info = [
'path' => $directory,
'exists' => false,
'is_readable' => false,
'is_writable' => false,
'contents' => [],
'file_count' => 0,
'dir_count' => 0,
'total_size' => 0
];
// 检查目录是否存在
$current_dir = ftp_pwd($this->ftp_conn);
if (@ftp_chdir($this->ftp_conn, $directory)) {
$info['exists'] = true;
// 切换回原目录
ftp_chdir($this->ftp_conn, $current_dir);
} else {
return $info; // 目录不存在,返回基本信息
}
// 获取目录内容
$items = @ftp_nlist($this->ftp_conn, $directory);
if ($items === false) {
$info['is_readable'] = false;
return $info;
}
$info['is_readable'] = true;
foreach ($items as $item) {
if ($item == '.' || $item == '..') {
continue;
}
$item_info = $this->getItemInfo($item, $directory);
if ($item_info['type'] == 'dir') {
$info['dir_count']++;
} else {
$info['file_count']++;
$info['total_size'] += $item_info['size'];
}
$info['contents'][] = $item_info;
}
// 检查写入权限
$info['is_writable'] = $this->testWritePermission($directory);
return $info;
}
/**
* 获取文件/目录的详细信息
*/
private function getItemInfo($item, $base_dir) {
$full_path = rtrim($base_dir, '/') . '/' . basename($item);
$info = [
'name' => basename($item),
'full_path' => $full_path,
'type' => 'unknown',
'size' => 0,
'modified' => 0,
'permissions' => ''
];
// 尝试判断是否是目录
$current_dir = ftp_pwd($this->ftp_conn);
if (@ftp_chdir($this->ftp_conn, $full_path)) {
$info['type'] = 'dir';
// 切换回原目录
ftp_chdir($this->ftp_conn, $current_dir);
} else {
$info['type'] = 'file';
$info['size'] = ftp_size($this->ftp_conn, $full_path);
if ($info['size'] == -1) {
$info['size'] = 0;
}
}
// 获取修改时间
$mtime = ftp_mdtm($this->ftp_conn, $full_path);
if ($mtime > 0) {
$info['modified'] = $mtime;
$info['modified_formatted'] = date('Y-m-d H:i:s', $mtime);
}
return $info;
}
/**
* 测试目录的写入权限
*/
private function testWritePermission($directory) {
$test_file = rtrim($directory, '/') . '/.write_test_' . time();
$test_content = 'test';
// 尝试创建测试文件
$temp_file = tempnam(sys_get_temp_dir(), 'ftp_test');
file_put_contents($temp_file, $test_content);
$result = @ftp_put($this->ftp_conn, $test_file, $temp_file, FTP_ASCII);
unlink($temp_file);
if ($result) {
// 删除测试文件
@ftp_delete($this->ftp_conn, $test_file);
return true;
}
return false;
}
/**
* 获取目录树
*/
public function getDirectoryTree($directory = null, $max_depth = 3, $current_depth = 0) {
if ($directory === null) {
$directory = ftp_pwd($this->ftp_conn);
if ($directory === false) {
return false;
}
}
if ($current_depth >= $max_depth) {
return [
'path' => $directory,
'name' => basename($directory),
'type' => 'dir',
'truncated' => true
];
}
$tree = [
'path' => $directory,
'name' => basename($directory) ?: '/',
'type' => 'dir',
'contents' => []
];
$items = @ftp_nlist($this->ftp_conn, $directory);
if ($items === false) {
$tree['error'] = '无法读取目录';
return $tree;
}
foreach ($items as $item) {
$basename = basename($item);
if ($basename == '.' || $basename == '..') {
continue;
}
$full_path = rtrim($directory, '/') . '/' . $basename;
// 判断是否是目录
$current_dir = ftp_pwd($this->ftp_conn);
if (@ftp_chdir($this->ftp_conn, $full_path)) {
// 是目录,递归处理
ftp_chdir($this->ftp_conn, $current_dir);
$subtree = $this->getDirectoryTree($full_path, $max_depth, $current_depth + 1);
$tree['contents'][] = $subtree;
} else {
// 是文件
$size = ftp_size($this->ftp_conn, $full_path);
$tree['contents'][] = [
'path' => $full_path,
'name' => $basename,
'type' => 'file',
'size' => $size != -1 ? $size : 0
];
}
}
return $tree;
}
/**
* 格式化目录树为文本
*/
public function formatTree($tree, $indent = '', $last = true) {
$output = '';
$prefix = $indent . ($last ? '└── ' : '├── ');
$icon = $tree['type'] == 'dir' ? '📁 ' : '📄 ';
$output .= $prefix . $icon . $tree['name'];
if ($tree['type'] == 'file' && isset($tree['size'])) {
$output .= ' (' . $this->formatBytes($tree['size']) . ')';
}
if (isset($tree['truncated'])) {
$output .= ' [...]';
}
$output .= "\n";
if (isset($tree['contents']) && is_array($tree['contents'])) {
$child_indent = $indent . ($last ? ' ' : '│ ');
$count = count($tree['contents']);
foreach ($tree['contents'] as $i => $child) {
$is_last = ($i == $count - 1);
$output .= $this->formatTree($child, $child_indent, $is_last);
}
}
return $output;
}
/**
* 查找文件或目录
*/
public function find($pattern, $directory = null, $search_type = 'both') {
if ($directory === null) {
$directory = ftp_pwd($this->ftp_conn);
if ($directory === false) {
return [];
}
}
$results = [];
$items = @ftp_nlist($this->ftp_conn, $directory);
if ($items === false) {
return $results;
}
foreach ($items as $item) {
$basename = basename($item);
if ($basename == '.' || $basename == '..') {
continue;
}
$full_path = rtrim($directory, '/') . '/' . $basename;
// 判断类型
$current_dir = ftp_pwd($this->ftp_conn);
$is_dir = @ftp_chdir($this->ftp_conn, $full_path);
if ($is_dir) {
ftp_chdir($this->ftp_conn, $current_dir);
$type = 'dir';
} else {
$type = 'file';
}
// 检查是否匹配搜索条件
$matches = false;
if ($search_type == 'both' || $search_type == $type) {
if (fnmatch($pattern, $basename)) {
$matches = true;
}
}
if ($matches) {
$results[] = [
'path' => $full_path,
'name' => $basename,
'type' => $type,
'size' => $type == 'file' ? ftp_size($this->ftp_conn, $full_path) : 0
];
}
// 如果是目录,递归搜索
if ($is_dir) {
$sub_results = $this->find($pattern, $full_path, $search_type);
$results = array_merge($results, $sub_results);
}
}
return $results;
}
private function formatBytes($bytes, $precision = 2) {
if ($bytes <= 0) return '0 Bytes';
$units = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
$base = log($bytes, 1024);
$pow = floor($base);
$pow = min($pow, count($units) - 1);
return round(pow(1024, $base - $pow), $precision) . ' ' . $units[$pow];
}
}
// 使用示例
$ftp_conn = ftp_connect('localhost');
if ($ftp_conn && ftp_login($ftp_conn, 'user', 'pass')) {
ftp_pasv($ftp_conn, true);
$manager = new FTPDirectoryManager($ftp_conn);
echo "=== FTP目录管理工具 ===\n\n";
// 获取当前目录信息
$current_dir = ftp_pwd($ftp_conn);
echo "当前目录: $current_dir\n\n";
$dir_info = $manager->getDirectoryInfo();
if ($dir_info) {
echo "目录信息:\n";
echo "路径: {$dir_info['path']}\n";
echo "存在: " . ($dir_info['exists'] ? '是' : '否') . "\n";
echo "可读: " . ($dir_info['is_readable'] ? '是' : '否') . "\n";
echo "可写: " . ($dir_info['is_writable'] ? '是' : '否') . "\n";
echo "文件数: {$dir_info['file_count']}\n";
echo "目录数: {$dir_info['dir_count']}\n";
echo "总大小: " . $manager->formatBytes($dir_info['total_size']) . "\n";
if (!empty($dir_info['contents'])) {
echo "\n目录内容:\n";
foreach ($dir_info['contents'] as $item) {
$icon = $item['type'] == 'dir' ? '📁' : '📄';
$size = $item['type'] == 'file' ? ' (' . $manager->formatBytes($item['size']) . ')' : '';
echo " $icon {$item['name']}$size\n";
}
}
}
echo "\n=== 目录树结构 ===\n";
$tree = $manager->getDirectoryTree('/', 2);
echo $manager->formatTree($tree);
echo "\n=== 文件搜索 ===\n";
$results = $manager->find('*.txt', '/', 'file');
echo "找到 " . count($results) . " 个文本文件:\n";
foreach ($results as $result) {
echo " 📄 {$result['path']}\n";
}
ftp_close($ftp_conn);
} else {
echo "无法连接FTP服务器\n";
}
?>
ftp_pwd() 返回的是服务器端的当前目录,可能与客户端本地目录不同PWD命令,导致函数失败/,Windows可能使用\)falseftp_pwd()确认当前目录ftp_pwd()验证目录切换是否成功ftp_pwd()总是成功,应检查返回值ftp_pwd(),可能影响性能ftp_pwd()获取当前目录ftp_pwd()检查可访问性ftp_pwd() 返回 false 的可能原因:
PWD 命令PWD 命令的使用解决方法:检查连接状态、用户权限和服务器日志。
确保目录操作正确的策略:
ftp_chdir()后,使用ftp_pwd()验证是否成功// 示例:安全的目录操作
$start_dir = ftp_pwd($ftp);
// 执行操作...
// 如果失败,返回起始目录
ftp_chdir($ftp, $start_dir);
| 函数 | 作用 | 返回值 | 用途 |
|---|---|---|---|
ftp_pwd() |
获取当前工作目录的路径 | 字符串(路径)或 false | 获取当前位置,用于导航和验证 |
ftp_nlist('.') |
列出当前目录的内容 | 数组(文件名列表)或 false | 查看当前目录包含哪些文件和目录 |
简单来说:
ftp_pwd() 告诉你"你在哪里"ftp_nlist('.') 告诉你"这里有什么"ftp_chdir() - 改变当前工作目录ftp_cdup() - 切换到上级目录ftp_mkdir() - 在FTP服务器上创建目录ftp_rmdir() - 删除FTP服务器上的目录ftp_nlist() - 列出FTP目录中的文件ftp_rawlist() - 返回目录的详细列表ftp_size() - 返回指定文件的大小ftp_mdtm() - 返回指定文件的最后修改时间