Tiny File Manager 2.6 常用操作详解

Tiny File Manager 2.6 日常操作手册:登录会话/搜索/新建/编辑/备份/重命名/复制移动/删除/打包解压/上传下载/chmod 全操作,Web 入口与 curl 接口双形态并附实测回显(2026-11-01)

Tiny File Manager文件管理2026/11/01

Tiny File Manager 2.6 常用操作详解

目标:作为 Tiny File Manager 2.6 的日常操作手册,覆盖登录会话、浏览搜索、新建/编辑/备份/重命名/复制/移动/删除、打包解压、上传下载、权限修改与 Settings 面板全部常用操作——每个操作同时给出 Web 界面入口与 curl 接口形态(含真实请求参数与实测响应回显),读者既可以在浏览器里点,也可以在服务器上用脚本自动化。全部命令与回显于 2026-11-01 在 Ubuntu 22.04 实机实测通过。

一、环境信息

  • 应用版本:Tiny File Manager 2.6(官方镜像 tinyfilemanager/tinyfilemanager:master,2026-07-20 构建,PHP 7.4.33)
  • 运行环境:Ubuntu 22.04(x86_64),Web 端口 8134,文件根目录 /var/www/html/data(挂载宿主 data/ 目录)
  • 部署与配置:见 《Tiny File Manager Docker Compose 部署指南》与《Tiny File Manager 2.6 配置参数详解》
  • 演示账号:admin / q1w2e3r4(可写管理员)、user / 12345(只读账号)
  • 应用无独立 REST API:全部操作复用 Web 页面的 GET/POST 表单与 AJAX 端点,均以 CSRF token 校验(下文统一实测)

二、操作概览

Tiny File Manager 的全部操作围绕一个入口 URL 展开:/index.php?p=<子路径>。p 参数是当前所在目录(相对文件根),写操作全部要求携带与会话绑定的 token。操作清单与调用形态:

操作域Web 界面入口接口形态(实测)只读账号
登录/登出登录页 / Sign OutPOST fm_usr,fm_pwd,token;GET logout=1—
浏览目录目录树点击GET ?p=<dir>✅ 可用
搜索Advanced SearchPOST AJAX type=search✅ 可用
新建目录/文件New ItemPOST newfile,newfilename,token❌ 拒绝
在线编辑文件行 EditGET edit=<f>;POST AJAX type=save❌ 拒绝
备份副本文件行 BackupPOST AJAX type=backup❌ 拒绝
重命名文件行 RenamePOST rename_from,rename_to,token❌ 拒绝
复制/移动文件行 Copy/MoveGET copy=<src>&finish=1[&move=1]❌ 拒绝
删除文件行 Delete / 批量 DeleteGET del=<name> + POST token❌ 拒绝
打包 zip/tar批量选择后 Zip/TarPOST group[],file[],zip/tar,token❌ 拒绝
解压压缩包行 UnzipPOST unzip,token❌ 拒绝
下载文件行 DownloadGET dl=<file> + POST token✅ 可用
上传Uploadmultipart file,fullpath,dzchunkindex,dztotalchunkcount,token;AJAX type=upload+uploadurl❌ 拒绝
权限修改Perms 列链接POST chmod,ur..ox,token❌ 拒绝
SettingsSettings 面板POST AJAX type=settings❌ 拒绝

关键差异解读:只读账号(user)能用的只有浏览、搜索、下载三类;其余操作在界面层不渲染、接口层也被服务端拦截(实测确认)。

三、前置条件:准备一个已登录的 curl 会话

所有接口实测都需要「会话 cookie + CSRF token」两件套。以下三步在服务器上准备(每步均有实测回显):

BASE=http://localhost:8134
# 1) 请求登录页:把会话 cookie 存进 cj.txt,并从页面取出 token
curl -s -c cj.txt $BASE/ -o login.html
TOKEN=$(grep -oE 'name="token" value="[^"]+"' login.html | sed 's/.*value="//;s/"$//')
echo "$TOKEN"

实测回显(token 为 64 位十六进制,每次会话不同):

d10dc2d96d58f302b060ca7cec8053a55795e4a2c86391235fe8321adb40592d
# 2) 表单登录(登录失败时服务端强制延迟 1 秒)
curl -s -b cj.txt -c cj.txt -d "fm_usr=admin&fm_pwd=q1w2e3r4&token=$TOKEN" -L "$BASE/index.php?p=" -o main.html
grep -oE 'You are logged in|Login failed[^<]*' main.html

实测回显:

You are logged in

登录页 token 在登录后仍然有效(token 存于会话,与登录状态无关),下文各操作继续复用 $TOKEN 与 cj.txt。

⚠️ 两个实测踩坑点,直连接口必读:

  1. 写操作的 POST 地址必须带 ?p=。不带时应用会先 302 重定向到 ?p=,POST 表单数据随重定向丢失、操作静默无效(实测确认);
  2. token 必须放在 POST 表单里(部分端点只认 POST body 的 token,放在 URL 查询串无效,下载接口实测确认)。

登出(实测回显:返回登录表单,含 fm_usr 输入框):

curl -s -b cj.txt -L "$BASE/index.php?p=&logout=1" | grep -oE 'name="fm_usr"'
name="fm_usr"

四、各操作详解

4.1 浏览目录与搜索

浏览目录就是打开 ?p=<子目录>;文件列表在页面表格中(Name/Size/Modified/Perms/Owner/Actions 六列)。搜索用 AJAX 端点,递归扫描当前目录及子目录:

# 搜索文件名包含 welcome 的条目(path=. 表示从根开始)
curl -s -b cj.txt -d "ajax=1&type=search&path=.&content=welcome&token=$TOKEN" "$BASE/index.php?p="

实测回显:

[{"name":"welcome.md","type":"file","path":""},{"name":"welcome.md_261101_145928.tar","type":"file","path":""},{"name":"welcome.md-01Nov26-145736.bak","type":"file","path":""}]

返回 JSON 数组:name 文件名、type file/folder、path 相对根的目录。Web 界面右上角 Advanced Search 弹窗即调用此端点。

4.2 新建目录与文件

Web 界面顶部 New Item,选 File 或 Folder 并填名称。接口形态(newfile 取值 folder 或 file):

# 新建目录 projects
curl -s -b cj.txt -d "newfile=folder&newfilename=projects&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE '(Folder|File) <b>[^<]+</b> [A-Za-z ]+'
# 新建文件 notes.md
curl -s -b cj.txt -d "newfile=file&newfilename=notes.md&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE '(Folder|File) <b>[^<]+</b> [A-Za-z ]+'

实测回显:

Folder <b>projects</b> Created
File <b>notes.md</b> Created

创建结果落在 $root_path 指向的文件根(挂载卷),宿主侧 ls ./data/ 立即可见同名目录/文件。重名时提示 already exists,含 ../ 等穿越字符的名称被拒绝。

4.3 在线编辑与保存

Web 界面点击文件的 Edit 进入 ace.js 编辑器,Ctrl+S 保存。接口形态——edit=<文件名> 放 URL,新内容放 POST 的 content,保存成功返回 1:

curl -s -b cj.txt --data-urlencode "ajax=1" --data-urlencode "type=save" \
  --data-urlencode "content=hello tiny file manager
line2 测试中文" \
  --data "token=$TOKEN" "$BASE/index.php?p=&edit=welcome.md" -w ' [%{http_code}]'

实测回显(保存成功,HTTP 200):

1 [200]

落盘验证(文件内容与提交一致,注意末尾无换行):

hello tiny file manager
line2 测试中文

查看(不编辑)用 ?p=&view=<文件名>,页面标题实测变为 Tiny File Manager | welcome.md;只读查看页用 highlight.js 做语法高亮。

4.4 备份副本

编辑器页面的 Backup 按钮触发。接口在当前目录生成 <文件名>-<日Mon年-时分秒>.bak 副本:

curl -s -b cj.txt -d "ajax=1&type=backup&file=welcome.md&p=&token=$TOKEN" "$BASE/index.php?p="

实测回显:

Backup welcome.md-01Nov26-145736.bak created

宿主侧确认:

welcome.md
welcome.md-01Nov26-145736.bak

💡 说明:备份副本是「改配置文件前先留后路」的最快手段——时间戳后缀天然防覆盖,配合 $exclude_items = array('*.bak') 可以让列表不显示这些备份。

4.5 重命名与复制/移动

重命名(POST rename_from/rename_to,同目录内改名):

curl -s -b cj.txt -d "rename_from=welcome.md&rename_to=hello.md&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE 'Renamed from <b>[^<]+</b> to <b>[^<]+</b>'

实测回显:

Renamed from <b>welcome.md</b> to <b>hello.md</b>

复制/移动到当前目录用 copy=<源>&finish=1(源可以是子目录里的路径),加 move=1 即为移动(实测移动成功时页面提示 Moved from <b>projects/welcome.md</b> to <b>welcome.md</b>):

# 复制根目录 welcome.md 到 projects/
curl -s -b cj.txt -L "$BASE/index.php?p=projects&copy=welcome.md&finish=1&token=$TOKEN" | grep -oE 'Copied[^<]*(<b>[^<]+</b>[^<]*)*'
# 移动 projects/welcome.md 回根目录
curl -s -b cj.txt -L "$BASE/index.php?p=&copy=projects/welcome.md&move=1&finish=1&token=$TOKEN" | grep -oE 'Moved from[^<]*(<b>[^<]+</b>[^<]*)*'

实测回显:

Copied from <b>welcome.md</b> to <b>projects/welcome.md</b>
Moved from <b>projects/welcome.md</b> to <b>welcome.md</b>

⚠️ 注意:目标是「当前 p 目录」而不是任意指定目录,跨目录操作先切到目标目录再给源路径。目标已存在同名文件时移动/复制失败,页面提示 File or folder with this path already exists(实测复现:目标同名时不产生第二条副本)。

4.6 删除

单个删除用 del=<名称> + POST token(实测回显 File <b>hello.md</b> Deleted):

curl -s -b cj.txt -L "$BASE/index.php?p=&del=hello.md" --data "token=$TOKEN" | grep -oE '(File|Folder) <b>[^<]+</b> (Deleted|not deleted)'
File <b>hello.md</b> Deleted

批量删除:列表勾选多个条目后点 Delete(表单为 group[]=<名称> 数组 + delete + token)。删除是物理删除,没有回收站——批量操作前建议先用 4.4 的备份或先打包归档。

4.7 打包 zip/tar 与解压

批量打包:POST group[] 触发打包动作,file[] 列出要打包的条目,zip= 或 tar= 二选一:

# 多选打包 zip(自动命名 archive_年月日_时分秒.zip)
curl -s -b cj.txt -d "group[]=1&file[]=welcome.md&file[]=welcome.md-01Nov26-145736.bak&zip=&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE 'Archive <b>[^<]+</b> Created'
# 单选打包 tar(命名 <文件名>_年月日_时分秒.tar)
curl -s -b cj.txt -d "group[]=1&file[]=welcome.md&tar=&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE 'Archive <b>[^<]+</b> Created'

实测回显:

Archive <b>archive_261101_145928.zip</b> Created
Archive <b>welcome.md_261101_145928.tar</b> Created

解压用 POST unzip=<压缩包>,加 tofolder=1 则解压到以包名命名的新目录:

curl -s -b cj.txt -d "unzip=up.zip&tofolder=1&p=&token=$TOKEN" -L "$BASE/index.php?p=" | grep -oE 'Archive unpacked|not unpacked'

实测回显(宿主侧 up/ 目录出现且内容与包内一致):

Archive unpacked

⚠️ 打包/解压依赖 PHP 的 ZipArchive(zip)与 PharData(tar)扩展——官方镜像已内置 zip 扩展,自建 PHP 环境需自行安装,否则提示 Operations with archives are not available。

4.8 下载

单文件下载是「GET dl=<文件名> + POST token」的组合(实测:只把 token 放 URL 会返回页面而非文件):

curl -s -b cj.txt -d "token=$TOKEN" "$BASE/index.php?p=&dl=welcome.md"

实测回显(文件原始内容):

hello tiny file manager
line2 测试中文

浏览器端点文件行的 Download 即等价操作。批量下载可先 4.7 打包再下载压缩包。

4.9 上传:本地 multipart 与远程 URL

本地文件上传(multipart 表单,fullpath 必填为目标文件名,分片字段固定传 0/1):

curl -s -b cj.txt \
  -F "file=@./archive_261101_145928.zip;filename=up.zip" \
  -F "p=" -F "dzchunkindex=0" -F "dztotalchunkcount=1" \
  -F "fullpath=up.zip" -F "token=$TOKEN" "$BASE/index.php?p="

实测回显:

{"status":"success","info":"file upload successful"}

⚠️ 排障实录:fullpath 留空时,落盘文件名会变成 _261101150003.zip 这类「下划线+时间戳」(应用以空文件名拼时间戳命名)——浏览器端由 dropzone 自动带上 fullpath,直连接口必须手工传。实测确认带上 fullpath=up.zip 后文件名正确。

远程 URL 拉取(服务器主动从 URL 下载并落盘,Web 界面 Upload 弹窗的 URL 标签页即此功能):

curl -s -b cj.txt -d "ajax=1&type=upload&uploadurl=https://example.com/file.zip&token=$TOKEN" "$BASE/index.php?p="

实测回显(URL 指向本机/127 地址时的防护拦截):

{"fail":{"message":"URL is not allowed"}}

应用内置 SSRF 防护:拒绝 localhost、127.0.0.0/8 及 22/23/25/3306 等敏感端口(实测 127 回环被拒),公网 URL 正常拉取。

4.10 权限修改(chmod)

Web 界面点击 Perms 列的权限值进入九宫格复选框(owner/group/other × r/w/x)。接口用九个复选框字段表达八进制位(ur/uw/ux=属主读写执行,gr/gw/gx=组,or/ow/ox=其他):

# ur+uw+gr+gw = 0664
curl -s -b cj.txt -d "chmod=welcome.md&ur=1&uw=1&gr=1&gw=1&p=&token=$TOKEN" -L "$BASE/index.php?p=" -o /dev/null
stat -c '%a' ./data/welcome.md

实测回显(宿主侧权限确认生效):

664

4.11 Settings 面板

界面 Settings 可改语言/主题/显示隐藏文件/隐藏列,保存即写回 config.php 的 $CONFIG 行(写回机制与实测回显见《Tiny File Manager 2.6 配置参数详解》3.2)。接口形态(返回 1 即保存成功):

curl -s -b cj.txt -d "ajax=1&type=settings&js-language=zh-CN&js-error-report=false&js-show-hidden=true&js-hide-cols=false&js-theme-3=dark&token=$TOKEN" "$BASE/index.php?p="

实测回显:

1

4.12 只读账号的行为差异

用只读账号 user / 12345 登录(会话准备流程同第三节,替换用户名密码),实测确认:

  • 目录浏览、搜索、下载三类操作正常(列表页正常渲染);
  • 界面上写操作入口(Upload/New Item/批量 Delete/Zip 等)不渲染,条目操作列只剩「查看(view)」与「下载(dl)」两类链接(实测页面统计确认);
  • 即使直连接口发起写操作,服务端也拦截(写端点统一带 !FM_READONLY 前置判断)。

五、注意事项

  1. token 与会话绑定:换 cookie 必须重新取 token;登出后旧会话立即失效(实测:登出后继续用旧 cookie 操作,页面静默无消息);
  2. 删除与覆盖不可逆:删除、移动覆盖均无确认弹窗(界面端有 Are you sure 确认框,接口端没有)——脚本化操作前先备份;
  3. 打包/解压是同步操作:大目录打包会占住 PHP 单进程(内置服务器无并发),期间页面无响应,生产大目录建议在服务器命令行完成打包后刷新;
  4. 上传受三层限制:$upload_chunk_size_bytes(分片)、$max_upload_size_bytes(应用层)、PHP upload_max_filesize/post_max_size(运行时),大文件失败逐层排查(参数见配置详解篇 5.5);
  5. 接口自动化的会话管理:curl 会话 cookie 过期(默认 PHP session 生命周期)后所有操作静默退回登录页,脚本里应对每个响应做「是否含 fm_usr 登录框」的判断并自动重登。

六、常见问题

Q1:curl 操作全部「静默无效」没有报错? 按顺序排查三个高频原因(均为实测踩坑):POST 地址没带 ?p=(被 302 丢数据);token 放在 URL 而不是 POST 表单(部分端点不认);会话已过期或登出(响应其实是登录页)。

Q2:搜索没有结果? type=search 的 path 参数取值 .(根)或子目录相对路径;content 是子串匹配(非正则)。确认目标文件在搜索起点之下,且 $exclude_items 没有把它排除。

Q3:移动/复制提示已存在? 目标目录(p)下已有同名条目。应用不会自动重命名,先删除/改名目标,或把源改名后再移动(实测复现)。

Q4:上传后文件名变成一串时间戳? multipart 请求缺 fullpath 字段(见 4.9 排障实录),补上目标文件名即可。

Q5:界面里改了文件但宿主侧看不到/重启后丢了? $root_path 没有指向挂载卷——文件写进了应用目录的可写层。解决与完整排障过程见部署指南 5.2。

七、参考链接