由于本人最近在工作中需要用到sftp上传文件,然后各种百度google寻找使用方法。无奈不知道是因为我的环境问题还是网上教程的知识太旧还是说我没有按照正确的方法去使用。导致我花了半天时间没有实现我想要的效果。现在踩完坑之后把代码贴在下面。
ftp版本:
ftp版本的比较简单,首先安装好ftp扩展,调用方式如下
$conn = ftp_connect('远程服务器地址', '端口');
ftp_login($conn, '用户名', '密码');
ftp_pasv($conn,TRUE);
ftp_set_option($conn,FTP_TIMEOUT_SEC,20);//20秒超时
$res = ftp_put($conn, $zip, $file, FTP_BINARY);
sftp版本:
业务代码如下:
//$mchnt_cd为文件名
public function uploadFtp($mchnt_cd)
{
try {
$params = ['host' => '远程服务器地址', 'port' => '端口'];
$sftp = new Sftp($params);
$login_result = $this->sftp->login('username','用户名', '密码');
if ($login_result !== true) throw new Exception('登录失败');
$dir = '/upload/' . date('Ymd', time());//日期文件夹
$is_exist = $this->sftp->dir_exits($dir);//判断文件夹是否存在
if ($is_exist === false) $this->sftp->ssh2_sftp_mchkdir($dir);//不存在则创建
$dstFile = '/upload/' . date('Ymd', time()) . '/' . $mchnt_cd;//要保存到远程服务器的文件路径(包括文件名)
$srcFile = FCPATH . 'upload' . DIRECTORY_SEPARATOR . 'updatefile' . DIRECTORY_SEPARATOR . $mchnt_cd;//本地文件目录
$is_true = $this->sftp->upload_file($srcFile, $dstFile);//文件上传
if ($is_true !== true) throw new Exception('文件上传失败');
return true;
} catch (Exception $e) {
return ['status' => 0, 'msg' => $e->getMessage()];
}
}
sftp版本的封装sftp上传类文件:
/**
* Class Sftp
* Since : 2020/6/19 : 17:13
* Description:sftp上传文档
* anthor ZhangHuang
*/
class Sftp
{
private $connection;
private $sftp;
public function __construct($params)
{
$host = $params['host'];//地址
$port = $params['port'];//端口
$this->connection = ssh2_connect($host,$port);
if (! $this->connection) throw new Exception("$host 连接 $port 端口失败");
}
/**
* @param $login_type 登录类型
* @param $username 用户名
* @param null $password 密码
* @param null $pub_key 公钥
* @param null $pri_key 私钥
* @return bool
* author: ZhangHuang
* Since : 2020/6/19 : 14:05
* Description:
* @throws Exception
*/
public function login($login_type,$username, $password = null,$pub_key = null,$pri_key = null)
{
switch ($login_type) {
case 'username': //通过用户名密码登录
$login_result = ssh2_auth_password($this->connection, $username, $password);
break;
case 'pub_key': //公钥私钥登录
$login_result = ssh2_auth_pubkey_file($this->connection,$username,$pub_key,$pri_key);
break;
}
if (! $login_result) throw new Exception("身份验证失败");
$this->sftp = ssh2_sftp($this->connection);
if (! $this->sftp) throw new Exception("初始化sftp失败");
return true;
}
/**
* @param $local_file 本地文件
* @param $remote_file 远程文件
* @return bool
* author: ZhangHuang
* Since : 2020/6/19 : 14:07
* Description: 上传文件
*/
public function upload_file($local_file, $remote_file)
{
$is_true = copy($local_file, 'ssh2.sftp://'.intval($this->sftp).$remote_file);
return $is_true;
}
/**
* 下载文件
* @param $local_file
* @param $remote_file
*/
public function down_file ($local_file, $remote_file)
{
ssh2_scp_recv($this->connection, $remote_file, $local_file);
}
/**
* 判断文件夹是否存在
* @param string $dir 目录名称
* @return bool
*/
public function dir_exits($dir)
{
$is_dir =is_dir('ssh2.sftp://'.intval($this->sftp).$dir);
return $is_dir;
}
/**
* @param $path 例子 '/home/username/newdir'
* @param int $auth 默认 0777的权限
* author: ZhangHuang
* Since : 2020/6/19 : 14:07
* Description:创建目录
* @throws Exception
*/
public function ssh2_sftp_mchkdir($path,$auth = 0777) //使用创建目录循环
{
$end = ssh2_sftp_mkdir($this->sftp, $path,$auth,false);
if ($end !== true) throw new Exception('文件夹创建失败');
}
/**
* @param $old_dir 例子:'/home/username/newnamedir'
* @param $new_dir /var/file/image
* @return bool
* author: ZhangHuang
* Since : 2020/6/19 : 14:08
* Description:目录重命名
*/
public function rename ($old_dir,$new_dir)
{
$is_true = ssh2_sftp_rename($this->sftp,$old_dir,$new_dir);
return $is_true;
}
/**
* 删除文件
* @param string $dir 例子:'/home/username/dirname/filename'
* $dir 示例:/var/file/image/404NotFound.png
* @return bool
*/
public function del_file ($dir)
{
$is_true = ssh2_sftp_unlink($this->sftp,$dir);
return $is_true;
}
/**
* 获取文件夹下的文件
* @param string $remote_file 文件路径 例:/var/file/image
* @return array
*/
public function scan_file_system($remote_file) {
$sftp = $this->sftp;
$dir = "ssh2.sftp://$sftp$remote_file";
$tempArray = array();
$handle = opendir($dir);
// 所有的文件列表
while (false !== ($file = readdir($handle))) {
if (substr("$file", 0, 1) != "."){
if(is_dir($file)){
// $tempArray[$file] = $this->scanFilesystem("$dir/$file");
} else {
$tempArray[]=$file;
}
}
}
closedir($handle);
return $tempArray;
}
}
总结:
我在网上看了很多的实现方式,但是用起来基本上没有一个通的,这个是我花了2个小时一步步调试通过的,使用的PHP版本是5.6,sftp上传文件的前提是安装好了ssh2的扩展。不知道如何安装ssh扩展的可以翻翻我之前的文章。最后调试通过还是比较高兴的。之所以再此记录一下,给后来的人做个参考吧。哈哈~