Fork me on GitHub

ThinkPHP文件上传接口

简易文件上传接口

上传在项目/runtime/storage/下,返回的是相对路径.


    /**
     * 文件上传接口
     * param file: /2024-06-11_09-50-43.png
     * return
     * {
     * "status": 1,
     * "msg": "上传成功",
     *  "data": {
     *     "file_path": "/uploads/20240611/6a2282ada486c614e170dff06063527f.png"
     *  }
     * }
     */
    public function uploadAjax()
    {
        // 获取上传的文件
        $file = Request::file('file');// 使用 Facade
		// 或$file = request()->file('file'); // 使用全局辅助函数

        // 验证规则
        $validate = Validate::rule([
            'file' => 'fileExt:jpg,jpeg,png,gif|fileSize:10485760', // 限制文件扩展名和大小
        ]);
        // 验证文件
        if (!$validate->check(['file' => $file])) {
            return json(['status' => 0, 'msg' => $validate->getError()]);
        }

        // 上传文件
        try {
            // $_SERVER['DOCUMENT_ROOT']为/www/wwwroot/项目/public目录
            // 如果使用服务器其他非项目路径,需要在public/.user.ini文件中添加授权的目录,且将该目录设为www用户,权限为766
            // $file->getOriginalName()为文件名称
            $file->move($_SERVER['DOCUMENT_ROOT']."/uploads/",$file->getOriginalName());
            /**
             * 存储在/www/wwwroot/项目名/runtime/storage/下面指定的uploads文件夹中
             * $savename = Filesystem::putFile('uploads', $file);
             */
            return json(['status' => 1, 'msg' => '上传成功', 'data' => ['file_path' => '/' . $savename]]);
        } catch (\Exception $e) {
            return json(['status' => 0, 'msg' => $e->getMessage()]);
        }
    }

文件上传管理

/**
 * 上传文件模型
 */
class UploadFileModel extends Model{

    protected $table = 'upload_file';
    protected $pk = 'id';
    protected $autoWriteTimestamp = 'timestamp';
    protected $createTime = 'upload_time';
    protected $updateTime = false;

    protected $field = [
        'id',
        'filepath',
        'filename',
        'filesize',
        'fileext',
        'upload_time'
    ];
}

<?php

namespace app\controller\project;

use app\BaseController;
use app\model\project\UploadFileModel;
use DateTime;
use Exception;
use League\Flysystem\FilesystemException;
use think\facade\Request;
use think\response\Json;
use think\facade\Filesystem;

/**
 * 文件上传
 */
class UploadFileController extends BaseController
{

    /**
     * 文件上传接口
     * @return Json 返回文件路径及其他属性
     * "data": {
     * "filepath": "projectfiles/20250220/20250220165335422_geek.zip",
     * "filename": "geek.zip",
     * "filesize": "2.82 MB",
     * "fileext": "zip"
     * }
     */
    public function uploadFileAjax()
    {
        try {
            $file = Request::file('file');

            if ($file && $file->isValid()) {
                //保存文件的路径
                $dir = 'projectfiles';
                $datePath = date('Ymd');
                $dirPath = $dir . '/' . $datePath;
                //原文件名
                $originalName = $file->getOriginalName();
                //后缀
                $extension = $file->getOriginalExtension();
                //保存文件名
                $timestamp = (new DateTime())->format('YmdHisv');
                $saveName = $timestamp . '_' . $originalName;
                //保存文件,并返回保存的文件路径
                $savedPath = Filesystem::disk('public')->putFileAs($dirPath, $file, $saveName);

                if ($savedPath) {
                    $model = new UploadFileModel();
                    //返回文件路径 文件名 文件大小 文件后缀
                    $data = [
                        'filepath' => $savedPath,
                        'filename' => $originalName,
                        'filesize' => round($file->getSize() / (1024 * 1024), 2) . ' MB',
                        'fileext' => $extension
                    ];
                    $newId = $model->insertGetId($data);
                    $savedData = $model->find($newId);
                    return $this->jsonSuccess($savedData);
                } else {
                    return $this->jsonFail('Failed to save file: ' . $originalName);
                }
            } else {
                return $this->jsonFail('No valid file uploaded');
            }
        } catch (Exception $e) {
            return $this->jsonFail('Exception: ' . $e->getTraceAsString());
        }
    }

    /**
     * 文件上传接口,返回文件绝对路径(根据request的protocol host port返回访问路径)
     * @return Json
     *
     */
    public function uploadFileReturnAbsPathAjax()
    {
        $schema = Request::scheme();
        $host = Request::host();
        $baseUrl = $schema . '://' . $host . '/static/upload/';
        try {
            $file = Request::file('file');

            if ($file && $file->isValid()) {
                //保存文件的路径
                $dir = 'projectfiles';
                $datePath = date('Ymd');
                $dirPath = $dir . '/' . $datePath;
                //原文件名
                $originalName = $file->getOriginalName();
                //后缀
                $extension = $file->getOriginalExtension();
                //保存文件名
                $timestamp = (new DateTime())->format('YmdHisv');
                $saveName = $timestamp . '_' . $originalName;
                //保存文件,并返回保存的文件路径
                $savedPath = Filesystem::disk('public')->putFileAs($dirPath, $file, $saveName);
                $savedPath=$baseUrl.$savedPath;
                if ($savedPath) {
                    $model = new UploadFileModel();
                    //返回文件路径 文件名 文件大小 文件后缀
                    $data = [
                        'filepath' => $savedPath,
                        'filename' => $originalName,
                        'filesize' => round($file->getSize() / (1024 * 1024), 2) . ' MB',
                        'fileext' => $extension
                    ];
                    $newId = $model->insertGetId($data);
                    $savedData = $model->find($newId);
                    return $this->jsonSuccess($savedData);
                } else {
                    return $this->jsonFail('Failed to save file: ' . $originalName);
                }
            } else {
                return $this->jsonFail('No valid file uploaded');
            }
        } catch (Exception $e) {
            return $this->jsonFail('Exception: ' . $e->getTraceAsString());
        }
    }

    /**
     * 删除文件及记录接口
     * @return Json
     * @throws FilesystemException
     */
    public function deleteFileAjax()
    {
        $id = Request::post('id');
        if (empty($id)) {
            return $this->jsonFail('参数错误');
        }

        $model = new UploadFileModel();
        $fileRecord = $model->find($id);

        if ($fileRecord) {
            $filePath = $fileRecord['filepath'];
            // 删除数据库记录
            $model->where('id', $id)->delete();
            // 删除文件
            if ($filePath) {
                Filesystem::disk('public')->delete($filePath);
            }

            return $this->jsonSuccess('删除成功');
        } else {
            return $this->jsonFail('记录不存在');
        }
    }

    /**
     * 下载文件请求(通过接口下载)
     * 可以直接通过 http://xxx:xx/static/upload/projectfiles/2021-09-01/xxx.zip请求
     * @return \think\response\File|Json
     */
    public function downloadFileAjax()
    {
        $filePath = Request::get('filePath');
        $file = Filesystem::disk('public')->path('projectfiles' . $filePath);

        if (file_exists($file)) {
            $fileName = basename($file);
            return download($file,$fileName);
        } else {
            return json(['error' => 'File not found']);
        }
    }

}

FTP服务上传

<?php

namespace app\controller;
use app\Request;

class FtpController
{
    protected $ftp_server = '127.0.0.1'; // FTP 服务器地址,如果公网IP,FTP能连接能创建文件但是大小为0切换127发现成功
    protected $ftp_port = 21;                  // FTP 端口号
    protected $ftp_user = 'ftpuser';          // FTP 用户名
    protected $ftp_pass = 'ftppwd';          // FTP 密码

    // FTP 连接
    private function connect()
    {
        $conn_id = ftp_connect($this->ftp_server, $this->ftp_port);
        if (!$conn_id) {
            return ['error' => '无法连接到 FTP 服务器'];
        }

        if (!@ftp_login($conn_id, $this->ftp_user, $this->ftp_pass)) {
            ftp_close($conn_id);
            return ['error' => 'FTP 登录失败'];
        }

        // 启用被动模式
        ftp_pasv($conn_id, true);

        return $conn_id;
    }

    // 上传文件
    public function uploadAjax(Request $request)
    {
        // 连接到 FTP 服务器
        $conn_id = $this->connect();
        if (isset($conn_id['error'])) return json($conn_id);

        // 从文件输入框获取上传的文件
        $file = $request->file('file'); // 'file' 是文件输入框的名称

        // 检查文件是否上传成功
        if (!$file) {
            return json(['error' => '没有接收到文件']);
        }

        // 将文件保存到服务器的临时目录
        $local_file = $file->getPathname();
        $remote_file = '/' . $file->getOriginalName(); // 目标路径,ftp的根目录下面

        // 上传文件到 FTP 服务器
        if (@ftp_put($conn_id, $remote_file, $local_file, FTP_BINARY)) {
            $result = ['message' => '文件上传成功'];
        } else {
            // 获取错误信息
            $error = error_get_last();
            $result = [
                'error' => '文件上传失败',
                'message' => $error['message'] ?? '未知错误'
            ];
//            $result = ['error' => '文件上传失败'];
        }

        // 关闭 FTP 连接
        ftp_close($conn_id);
        return json($result);
    }

    // 删除文件
    public function deleteFileAjax(Request $request)
    {
        $conn_id = $this->connect();
        if (isset($conn_id['error'])) return json($conn_id);

        $remote_file = $request->param('remote_file'); // 服务器上的文件路径

        if (ftp_delete($conn_id, $remote_file)) {
            $result = ['message' => '文件删除成功'];
        } else {
            $result = ['error' => '文件删除失败'];
        }

        ftp_close($conn_id);
        return json($result);
    }

    // 重命名文件
    public function rename(Request $request)
    {
        $conn_id = $this->connect();
        if (isset($conn_id['error'])) return json($conn_id);

        $old_name = $request->param('old_name'); // 原文件名
        $new_name = $request->param('new_name'); // 新文件名

        if (ftp_rename($conn_id, $old_name, $new_name)) {
            $result = ['message' => '文件重命名成功'];
        } else {
            $result = ['error' => '文件重命名失败'];
        }

        ftp_close($conn_id);
        return json($result);
    }

    // 列出文件
    public function listFilesAjax(Request $request)
    {
        $conn_id = $this->connect();
        if (isset($conn_id['error'])) return json($conn_id);

        $directory = $request->param('directory', '.'); // 默认当前目录
        $file_list = ftp_nlist($conn_id, $directory);
        if ($file_list !== false) {
            $result = ['files' => $file_list];
        } else {
            $result = ['error' => '无法获取文件列表'];
        }

        ftp_close($conn_id);
        return json($result);
    }
}
posted @   秋夜雨巷  阅读(61)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
历史上的今天:
2019-06-11 metasploit、msfvenom生成木马入侵电脑及手机
点击右上角即可分享
微信分享提示