【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协议版本会持续更新,当前版本 ...
随机推荐
- 如何实现将拖动物体限制在某个圆形内--实现方式vue3.0
如何实现蓝色小圆可拖动,并且边界限制在灰色大圆内?如下所示 需求源自 业务上遇到一个组件需求,设计师设计了一个"脸型整合器"根据可拖动小圆的位置与其它脸型的位置关系计算融合比例 如 ...
- 翻页组件page-flip调用问题
翻页组件重新调用解决方案 翻页组件:page-flip import { PageFlip } from 'page-flip' pagefile() { //绘制翻页 this.pageFlip = ...
- git指令使用
仓库为空,本地创建git项目之后提交到仓库中1.创建项目文件夹(本地git仓库)2.在项目文件夹中右键:选择Git Bash3.初始化项目:git init -- 会出现一个.git的隐藏文件夹4.将 ...
- 基于云服务MRS构建DolphinScheduler2调度系统
摘要:本文介绍如何搭建DolphinScheduler并运行MRS作业. 本文分享自华为云社区<基于云服务MRS构建DolphinScheduler2调度系统>,作者: 啊喔YeYe . ...
- 简历应该怎么写,HR看一篇简历仅需要5秒吗,简历模板大全
哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 最近有很多小伙伴问奇哥,说奇哥 ...
- dubbo是如何实现可扩展的?(二)
牛逼的框架,看似复杂难懂,思路其实很清晰.---me 上篇文章,在整体扩展思路上进行了源码分析,比较粗糙,现在就某些点再详细梳理下. dubbo SPi的扩展,基于一类.三注解. 一类是Extensi ...
- kubernetes之常用核心资源对象
部门产品线本身是做DEVOPS平台,最近部署架构也在往K8S上靠了,不得不学一下K8S.自己搭建了K8S集群与harbor仓库来学习. 1.kubernetes之常用核心资源对象 1.1.K8s服务部 ...
- ABAP CDS - DEFINE VIEW, name_list
Syntax ... ( name1, name2, ... ) ... Effect Defines the element names of a CDS view in ABAP CDS in a ...
- 国外价值10K+美金的Python面试题,珍藏已久,含泪放了出来
兄弟们,没吹牛皮,一哥们在国外面试的时候,就是要他做的这个,直接给他说,做出来了给你15K(单位是刀),做不出来就拜拜~ 大兄弟当时就不服了,这不是看不起我么,分分钟就给整完了~ 我上我也行系列: 唠 ...
- dotnet 控制台 使用 Microsoft.Maui.Graphics 配合 Skia 进行绘图入门
本文将告诉大家如何在 dotnet 的控制台模式下,采用 MAUI 自绘库 Microsoft.Maui.Graphics 进行绘图,设置 Microsoft.Maui.Graphics 底层调用 M ...