【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协议版本会持续更新,当前版本 ...
随机推荐
- 好客租房21-react组件的两种创建方式(函数组件)
1使用函数创建组件 函数组件:使用js的函数或者箭头函数创建的组件 约定1:函数组件名称必须以 开头 约定2:函数组件必须有返回值 表示该组件的结构 如果返回值为null 表示不渲染任何内容 2.1使 ...
- Git 不识别文件名字母大小写变化
问题 今天为一个项目撰写持续构建计划,撰写 Jenkinsfile 之后进行构建时报错: [2022-05-23 16:54:21] unable to prepare context: unable ...
- python将test01文件夹中的文件剪切到test02文件夹中
将test01文件夹中的文件剪切到test02文件夹中 import shutil import os def remove_file(old_path, new_path): print(old_p ...
- 第06组 Alpha冲刺 (2/6)
目录 1.1 基本情况 1.2 冲刺概况汇报 1.郝雷明 2. 方梓涵 3. 黄少丹 4. 董翔云 5.曾丽莉 6. 詹鑫冰 7.鲍凌函 8.杜筱 9.曹兰英 10. 吴沅静 1.3 冲刺成果展示 1 ...
- 数据库常用DDL语句
一.创建表 CREATE TABLE TABLE_NAME( #create table 表名 ID INT(4) PRIMARY KEY, #字段名 数据类型 完整性约束条件 NAME VARCHA ...
- .NET C#基础(6):命名空间 - 组织代码的利器
0. 文章目的 面向C#新学者,介绍命名空间(namespace)的概念以及C#中的命名空间的相关内容 1. 阅读基础 理解C与C#语言的基础语法 2. 名称冲突与命名空间 2.1 一个生活例 ...
- 关闭StackExchange等平台的privacy收集窗口
技术背景 当我们打开一个StackExchange页面的时候,经常会出现一个很大的privacy收集窗口,而且不管怎么点都关闭不了,比如像下图这样: 如果屏幕足够大,影响可能也不是很大,但是关键是对于 ...
- JZOJ 5409 Fantasy & NOI 2010 超级钢琴 题解
其实早在 2020-12-26 的比赛我们就做过 5409. Fantasy 这可是紫题啊 题目大意 给你一个序列,求长度在 \([L,R]\) 区间内的 \(k\) 个连续子序列的最大和 题解 如此 ...
- 一张图进阶 RocketMQ - NameServer
前言 「三此君看了好几本书,看了很多遍源码整理的 一张图进阶 RocketMQ 图片链接,关于 RocketMQ 你只需要记住这张图!觉得不错的话,记得点赞关注哦.」 一张图进阶 RocketMQ 图 ...
- 基于web3D展示技术的煤矿巷道3D可视化系统
地下开采离不开巷道工程.煤矿的生产.运输.排水.通风等各个环节都少不了巷道的支持.在煤矿智能化建设被提上日程的今天,巷道工程的智能化.可视化建设也成了行业趋势.尤其是复杂的井下作业环境,人员信息安全问 ...