在PHP脚本中通过SSHFS挂载远程文件系统,能够借助SSH协议的安全特性,实现本地对远程文件的无缝访问,避免传统文件共享方式带来的安全风险。这种方式不需要在远程服务器开放额外的文件传输端口,仅依赖SSH默认端口即可完成所有操作,非常适合需要跨服务器读写文件的业务场景。

环境准备与依赖安装
要实现PHP脚本中的SSHFS挂载,首先需要确保服务器环境满足以下要求:
- 本地服务器已安装SSHFS工具,主流Linux发行版可通过包管理器直接安装
- PHP环境已安装ssh2扩展,用于执行SSH相关命令和远程操作
- 本地服务器与远程服务器之间已配置SSH免密登录,避免挂载时输入密码
安装SSHFS工具
以Ubuntu/Debian系统为例,执行以下命令安装SSHFS:
# 更新软件源 sudo apt-get update # 安装SSHFS sudo apt-get install sshfs -y # 验证安装是否成功 sshfs --version
安装PHP ssh2扩展
PHP需要通过ssh2扩展执行远程命令,安装方式如下:
# 安装依赖库 sudo apt-get install libssh2-1-dev -y # 安装PHP ssh2扩展,根据PHP版本调整包名,例如PHP8.1对应php8.1-ssh2 sudo apt-get install php8.1-ssh2 -y # 重启PHP服务使扩展生效 sudo systemctl restart php8.1-fpm
配置SSH免密登录
为了避免挂载时手动输入密码,需要配置本地服务器到远程服务器的SSH免密登录:
生成SSH密钥对
在本地服务器执行以下命令生成密钥对,一路回车使用默认配置即可:
ssh-keygen -t rsa -b 4096
拷贝公钥到远程服务器
将本地生成的公钥复制到远程服务器的~/.ssh/authorized_keys文件中:
# 替换remote_user为远程服务器用户名,remote_ip为远程服务器IP ssh-copy-id remote_user@remote_ip
配置完成后,执行ssh remote_user@remote_ip命令,无需输入密码即可登录远程服务器,说明免密配置成功。
PHP脚本实现SSHFS挂载
接下来编写PHP脚本,实现远程文件系统的挂载、文件操作以及卸载流程。
创建挂载目录
首先在本地服务器创建一个目录作为挂载点:
<?php
// 定义挂载点路径
$mountPoint = '/mnt/remote_files';
// 检查挂载点是否存在,不存在则创建
if (!is_dir($mountPoint)) {
$createRes = mkdir($mountPoint, 0755, true);
if (!$createRes) {
die('创建挂载点失败');
}
}
echo "挂载点创建成功:{$mountPoint}";
?>
执行SSHFS挂载命令
通过PHP的exec函数执行SSHFS挂载命令,注意命令中的特殊字符需要转义:
<?php
// 远程服务器信息
$remoteUser = 'remote_user';
$remoteIp = '192.168.0.100';
$remoteDir = '/home/remote_user/data'; // 远程要挂载的目录
$localMountPoint = '/mnt/remote_files'; // 本地挂载点
// 拼接SSHFS挂载命令,添加-o allow_other参数允许其他用户访问挂载目录
$mountCmd = "sshfs {$remoteUser}@{$remoteIp}:{$remoteDir} {$localMountPoint} -o allow_other -o IdentityFile=/root/.ssh/id_rsa";
// 执行命令并获取输出和返回值
exec($mountCmd, $output, $returnCode);
if ($returnCode === 0) {
echo "远程文件系统挂载成功n";
// 打印挂载信息
exec('df -h | grep ' . $localMountPoint, $mountInfo);
print_r($mountInfo);
} else {
echo "挂载失败,错误码:{$returnCode}n";
print_r($output);
}
?>
挂载后文件操作验证
挂载成功后,可以像操作本地文件一样操作远程文件:
<?php
$localMountPoint = '/mnt/remote_files';
// 在远程目录创建测试文件
$testFile = $localMountPoint . '/php_test.txt';
$writeRes = file_put_contents($testFile, '这是PHP脚本写入的远程文件内容');
if ($writeRes) {
echo "文件写入成功,内容:n";
echo file_get_contents($testFile);
} else {
echo "文件写入失败";
}
// 列出远程目录下的文件
$fileList = scandir($localMountPoint);
echo "n远程目录文件列表:n";
print_r($fileList);
?>
卸载远程文件系统
操作完成后,需要及时卸载远程文件系统,避免资源占用:
<?php
$localMountPoint = '/mnt/remote_files';
// 执行卸载命令
$umountCmd = "fusermount -u {$localMountPoint}";
exec($umountCmd, $output, $returnCode);
if ($returnCode === 0) {
echo "远程文件系统卸载成功";
} else {
echo "卸载失败,错误码:{$returnCode}n";
print_r($output);
}
?>
常见问题排查
| 问题现象 | 可能原因 | 解决方法 |
|---|---|---|
| 挂载时提示权限不足 | 本地挂载点权限不够,或SSHFS命令未加allow_other参数 | 给挂载点设置755权限,挂载命令添加-o allow_other参数 |
| 挂载后无法访问文件 | 远程服务器目录权限不足,或免密登录配置错误 | 检查远程目录权限,重新配置SSH免密登录 |
| 卸载时提示设备忙 | 有进程正在访问挂载目录 | 使用lsof命令查找占用进程,关闭后再执行卸载 |
注意:生产环境中执行挂载命令时,建议添加错误日志记录,方便后续排查问题。同时不要将远程服务器的敏感信息硬编码在PHP脚本中,可通过配置文件或环境变量读取。