本文大部分是借鉴:https://www.cnblogs.com/hesitation/p/4653850.html#commentform
1、新建一个ftp的工具类,工具类封装方法。
<?php
namespace app\common\lib;
use think\Exception;
class FtpUntil
{
public $off; // 返回操作状态(成功/失败)
public $conn_id; // FTP连接
/**
* 方法:FTP连接
* @FTP_HOST -- FTP主机
* @FTP_PORT -- 端口
* @FTP_USER -- 用户名
* @FTP_PASS -- 密码
*/
function __construct()
{
$this->conn_id = @ftp_connect('此处写ftp的地址', 21) or die("FTP服务器连接失败");
@ftp_login($this->conn_id, '此处写ftp的用户名', '此处写ftp的用户密码') or die("FTP服务器登陆失败");
@ftp_pasv($this->conn_id, 1); // 打开被动模拟
}
/**
* 方法:上传文件
* @param $path string 本地路径
* @param $newpath string 上传路径
* @param $file_name string 文件路径
* @param bool $type 若目标目录不存在则新建
* @return bool
* @throws Exception
* @author xh
* @date 2020/12/11 15:00
*/
function up_file($path, $newpath, $file_name, $type = true)
{
if ($type)
$this->dir_mkdirs($newpath);
$far_path = $newpath . '/' . $file_name;
$this->off = @ftp_put($this->conn_id, $far_path, $path, FTP_BINARY);
if (!$this->off) return false; //echo "文件上传失败,请检查权限及路径是否正确!"
return true;
}
/**
* 方法:移动文件
* @path -- 原路径
* @newpath -- 新路径
* @type -- 若目标目录不存在则新建
*/
function move_file($path, $newpath, $type = true)
{
if ($type) $this->dir_mkdirs($newpath);
$this->off = @ftp_rename($this->conn_id, $path, $newpath);
if (!$this->off) echo "文件移动失败,请检查权限及原路径是否正确!";
}
/**
* 方法:复制文件
* 说明:由于FTP无复制命令,本方法变通操作为:下载后再上传到新的路径
* @path -- 原路径
* @newpath -- 新路径
* @type -- 若目标目录不存在则新建
*/
function copy_file($path, $newpath, $type = true)
{
$downpath = "c:/tmp.dat";
$this->off = @ftp_get($this->conn_id, $downpath, $path, FTP_BINARY);// 下载
if (!$this->off) echo "文件复制失败,请检查权限及原路径是否正确!";
$this->up_file($downpath, $newpath, $type);
}
/**
* 方法:删除文件
* @path -- 路径
*/
function del_file($path)
{
$this->off = @ftp_delete($this->conn_id, $path);
if (!$this->off) echo "文件删除失败,请检查权限及路径是否正确!";
}
/**
* 方法:生成目录 支持1级或者多级目录
* @path -- 路径
*/
function dir_mkdirs($path)
{
$path_arr = explode('/', $path); // 取目录数组
//定义一个空的字符串,为的是实现生成多级目录
$aa = '';
foreach ($path_arr as $key => $val) // 创建目录
{
//判断截断后的目录,如果文件不是空,并且在ftp远程不存在
if (!empty($val) && (@ftp_chdir($this->conn_id, $val) == FALSE)) {
//拼接路径
$aa .= $val . '/';
//创建目录
$tmp = @ftp_mkdir($this->conn_id, $aa);
//如果目录未创建成功,则跑出异常
if ($tmp == FALSE) {
throw new Exception("目录创建失败,请检查权限及路径是否正确!", 10500);
}
}
}
return true;
}
/**
* 方法:关闭FTP连接
*/
function close()
{
@ftp_close($this->conn_id);
}
}
2、写一个控制器,调用ftp的工具,上传文件
<?php
namespace app\index\controller;
use app\common\lib\FtpUntil;
use think\Exception;
use think\facade\Request;
/**
* 上传zip文件
* Class UploadZip
* @package app\index\controller
*/
class Upload
{
public function upload()
{
$ftp = new FtpUntil();
//文件名称、文件
$file_name = Request::param('file_name');
$file = Request::file('file');
if (empty($file_name)) {
return json(['code' => 9, 'msg' => '请输入证书文件名称']);
}
if (empty($file)) {
return json(['code' => 9, 'msg' => '请选择文件']);
}
$info = $file->move('E:/phpEnv/www/tp5/public/uploads/zip');
if ($info) {
try {
//本地路径
$local_path = 'E:\phpEnv\www\tp5\public\uploads\zip\\' . $info->getSaveName();
$path1 = explode('\\',$info->getSaveName());
//远程路径 支持1级或者多级目录
$far_path = $file_name;
//上传文件
$nn = $ftp->up_file($local_path, $far_path,$path1[1]);
$ftp->close();
if ($nn == false) {
return json(['code' => 1, 'msg' => '上传失败']);
}
//刪除本地图片
unlink('E:/phpEnv/www/tp5/public/uploads/zip/' . $info->getSaveName());
return json(['code' => 0, 'msg' => '上传成功']);
} catch (Exception $e) {
dump($e);
}
} else {
// 上传失败获取错误信息
echo $file->getError();
}
}
}
3、访问结果
踩坑处:使用ftp_connect()函数链接ftp时,出现未定义的情况,需要在php.ini中打开ftp的扩展,并查看在ext文件夹中,是否有php_ftp.dll文件,也可以通过phpinfo() 查看ftp扩展是否打开
此处主要是验证和测试了工具类中上传文件的函数,其他的没有验证,如果有不足的地方,还请指出