【PHP库】phpseclib - sftp远程文件操作
需求场景说明
对接的三方商家需要进行文件传输,并且对方提供的方式是 sftp 的服务器账号,我们需根据他们提供的目录进行下载和上传指定文件。
安装
composer require phpseclib/phpseclib:~3.0
使用sftp功能
1.新建并设置config/sftp.php文件
return [
'sftp' => [
'host' => env('SFTP_HOST', '127.0.0.1'),
'port' => env('SFTP_PORT', 22),
'user' => env('SFTP_USE', null),
'password' => env('SFTP_PASSWORD', null),
],
];
2.配置.env文件
SFTP_HOST=127.0.0.1
SFTP_PORT=22
SFTP_USE=user
SFTP_PASSWORD=password
3.封装 app/Utils/SftpHelper.php调用库文件,通过单例可设置不同的 sftp 服务器
namespace App\Utils;
use phpseclib3\Net\SFTP;
class SftpHelper
{
private static $instance = [];
public static function getInstance($key='sftp')
{
if (!isset(self::$instance[$key])) {
$config = ConfigHelper::getInstance()->read('sftp.'.$key);
self::$instance[$key] = new SFTP($config['host'], $config['port']);
self::$instance[$key]->login($config['user'], $config['password']);
}
return self::$instance[$key];
}
}
4.使用方法说明
nlist:获取指定目录下的文件列表,包括子目录,(默认不会递归子目录下的文件)is_readable: 判断文件是否有读权限chmod:修改文件/目录权限,默认不递归get:获取文件,默认获取文件内容。is_dir:是否存在该目录mkdir:创建目录rename: 将文件重命名put:上传文件
5.访问 sftp 服务器并下载文件到本地
5.1 读取指定服务器下的文件,并循环处理每个文件
5.2 下载远程文件到当前服务器的指定位置,并创建待处理文件记录表
说明:创建文件处理表可使文件读取逻辑失败时,可重复处理,并且不需要多次访问 sftp 服务器,进行逻辑解耦
5.3 创建文件记录数据后将服务器上的文件移到归档目录,避免重复读取
// 连接sftp服务器并登录
$sftp = SftpHelper::getInstance('sftp');
// 获取目录下的文件列表(不递归)
$file_list = $sftp->nlist($remote_dir);
// 循环文件列表,获取处理数据
foreach ($file_list as $file_name) {
// 跳过不处理的目录
if (in_array($file_name, ['.', '..', 'Archive'])) {
continue;
}
// 拼接完整的服务器文件路径
$remote_file = $remote_dir.$file_name;
// 设置本地存储的目录
$save_path = env('FILE_PATH', '/data/storage/sftp/')."{$file_type}/";
File::exists($save_path) or (File::makeDirectory($save_path, 0777, true) && @chmod($save_path, 0777));
// 完整的本地路径
$local_file = $save_path. $file_name;
// 拉取sftp文件到本地目录
if (!file_exists($local_file)) {
if (!$sftp->is_readable($remote_file)) {
$sftp->chmod('0777', $remote_file);
}
$sftp->get($remote_file, $local_file);
}
// 添加文件日志(同一个远程文件不重复拉取)
// 后续可单独增加文件读取逻辑,使文件内容处理失败时可重复处理,并且不需要重复访问 sftp 服务器去读取远程文件
SftpFile::updateOrCreate([
'remote_dir' => $remote_file,
], [
'action' => $file_type, // 文件类型
'filename' => $file_name, // 文件名
'filepath' => $local_file, // 本地服务器路径
]);
// 日志创建成功之后再将文件移到Archive目录下,避免重复读取
if (!$sftp->is_dir($remote_dir.'Archive/')) {
// 没有则创建Archive目录
$sftp->mkdir($remote_dir.'Archive/');
}
// 已读取的文件移到子目录Archive
$sftp->rename($remote_file, "Archive/{$remote_file}");
}
6.上传文件到 sftp 服务器的指定位置
// 读取待处理的文件列表
$file_list = SftpFile::where([
'action' => $file_type,
'state' => 1
])->get();
if (count($file_list) <= 0) {
return;
}
// 连接sftp服务器并登录
$mk_sftp = SftpHelper::getInstance('sftp');
foreach ($file_list as $file) {
// 校验推送的文件是否存在
if (!file_exists($file->filepath)) {
throw new ParamsException('推送的文件不存在');
}
$file_path = $file->filepath;
$remote_file = $file->remote_dir;
// 推送文件到sftp服务器
// SFTP::SOURCE_LOCAL_FILE 表示以文件的形式,不设置时表示是按字符串形式上传
$put_res = $mk_sftp->put($remote_file, $file_path, SFTP::SOURCE_LOCAL_FILE);
if ($put_res) {
$file->state = 1;
$file->save();
}
}
7.读取文件内容
// 当前php.ini配置的是128M
ini_set('memory_limit', '300M');
$local_file = $file_info['filepath'];
$remote_file = $file_info['remote_dir'];
// 读取文件数据
$fp = fopen($local_file, 'r');
$file_data = [];
while (!feof($fp)) {
$row_str = fgets($fp); // 逐行读取。如果fgets不写length参数,默认是读取1k。
$item = explode(',', trim($row_str));
// 跳过表头
// 将行数据转成指定的键值对
}
return $file_data;
参考教程
【PHP库】phpseclib - sftp远程文件操作的更多相关文章
- SFTP远程文件上传
远程服务器remote_host=192.168.29.142用户为remote_www,用户当前目录为/home/remote_www 本地服务器local_host=192.168.29.135用 ...
- 配置openssh实现sftp远程文件上传
客服端:winscp等ftp/sftp客户端 服务器:阿里云默认使用的openssh 需求:可以sftp远程传输文件到服务器固定文件夹下,不可远程ssh登录 步骤: 1. 建立系统用户ftpuser及 ...
- scp & cat远程文件操作
对拷文件夹 (包括文件夹本身) scp -r /home/wwwroot/www/charts/util root@192.168.1.65:/home/wwwroot/limesurvey_back ...
- java远程文件操作
有时在项目中,会有专门的文件服务器(windows),这个时候我们需要对文件进行操作时,就不能像操作本地文件那样操作文件服务器的文件.这时候就可以用SmbFile来操作了. 首先添加jar包,mave ...
- delphi使用Chilkat 组件和库从SFTP下载文件
官网地址:https://www.example-code.com/delphiDll/default.asp 实例代码:(不包括全局解锁) 密码生成器:https://www.cnblogs.co ...
- Python Requests库 form-data 上传文件操作
请求数据示例: ------WebKitFormBoundaryKLoWgrA4O40MayHM Content-Disposition: form-data; name="id" ...
- 《Java核心技术卷二》笔记(二)文件操作和内存映射文件
文件操作 上一篇已经总结了流操作,其中也包括文件的读写.文件系统除了读写以为还有很多其他的操作,如复制.移动.删除.目录浏览.属性读写等.在Java7之前,一直使用File类用于文件的操作.Java7 ...
- Python的高级文件操作(shutil模块)
Python的高级文件操作(shutil模块) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 如果让我们用python的文件处理来进行文件拷贝,想必很多小伙伴的思路是:使用打开2个 ...
- 文件系统之-JAVA Sftp远程操作:
转载:http://blog.csdn.net/lee272616/article/details/52789018 java远程操作文件服务器(linux),使用sftp协议版本会持续更新,当前版本 ...
随机推荐
- Fail2ban 配置详解 基础配置(fail2ban.conf)
[Definition] loglevel = INFO # 设置日志级别:级别越低显示日志的信息更详细. # CRITICAL - 关键级别 # ERROR - 错误级别 # WARNING - 警 ...
- JavaScript正则中//g, g 的作用
//正则表达式的标准写法regexp = new RegExp(pattern[, flag]); pattern: 模板的用法是关键,也是本章的主要内容. flag: "i ...
- 云开发中的战斗机 Laf,让你像写博客一样写代码
各位云原生搬砖师 and PPT 架构师,你们有没有想过像写文章一样方便地写代码呢? 怎样才能像写文章一样写代码? 理想的需求应该是可以在线编写.调试函数,不用重启服务,随时随地在 Web 上查看函数 ...
- isprime
C++实现求素数个数 问题描述 求1~n的素数个数(例:n=10) 1 2 3 4 5 6 7 8 9 10 prime 2 3 5 7 not prime 1 4 6 8 9 10 素数又称质数.所 ...
- C语言- 基础数据结构和算法 - 动态数组
听黑马程序员教程<基础数据结构和算法 (C版本)>,照着老师所讲抄的, 视频地址https://www.bilibili.com/video/BV1vE411f7Jh?p=1 喜欢的朋友可 ...
- 『忘了再学』Shell基础 — 30、sed命令的使用
目录 1.sed命令说明 2.行数据操作 (1)查看文件中的数据 (2)删除文件中的数据 (3)向文件中追加数据 (4)向文件中插入数据 (5)修改文件中的多行数据(删除,追加,插入) (6)替换文件 ...
- 推荐一款M1芯片电脑快速搭建集群的虚拟机软件
虚拟机软件太多了,出名的莫过于VMware,VirutlaBox以及Parallels Desktop. 我们使用虚拟机软件一般有两种用途: 安装不同于宿主机系统的拥有用户界面的操作系统,比如Wind ...
- UML图记忆技巧
什么是UML类图 Class Diagram:用于表示类.接口.实例等之间相互的静态关系 虽然名字叫类图,但类图中并不只有类 记忆技巧 UML箭头方向: 从子类指向父类 我相信 很多同学都会有和我一样 ...
- 使用Runnable和Callable接口实现多线程的区别
使用Runnable和Callable接口实现多线程的区别 先看两种实现方式的步骤: 1.实现Runnable接口 public class ThreadDemo{ public static voi ...
- 静态代码块和数组工具类Arrays
静态代码块 静态代码块:定义在成员位置,使用static修饰的代码块{ }. ~位置:类中方法外. ~执行:随着类的加载而执行且执行一次,优先于main方法和构造方法的执行 格式: public cl ...