ThinkPHP 6 注册自定义指令需在 app/command.php 中配置类映射,如 'backup:remote' => app\command\BackupRemote::class;类须继承 think\console\Command,实现 configure() 和 handle(),并调用 $this->setName()。

ThinkPHP 6 的 command 扩展机制怎么注册自定义指令
ThinkPHP 6 不再默认提供数据库备份命令,必须手动写一个 Command 类并注册。不注册就执行不了,哪怕类文件放对位置也没用。
注册方式只有两种有效路径:app/command.php 配置数组,或在 app/provider.php 中绑定服务。推荐前者,轻量且直观。
- 在
app/command.php中追加:return [ 'backup:remote' => app\command\BackupRemote::class, ]; - 类文件路径必须是
app/command/BackupRemote.php,命名空间为app\command - 类需继承
think\console\Command,且必须实现configure()和handle() - 别漏掉
$this->setName('backup:remote'),否则php think backup:remote会报错“Command not found”
备份逻辑里怎么调用 ThinkPHP 原生数据库导出功能
TP6 没有内置的 export 方法,但 think\db\Connection 提供了 getFieldsInfo() 和 getTables(),配合 query() 可以手拼 CREATE TABLE 和 INSERT 语句——但这太重,也容易出编码、字段类型兼容问题。
更稳的做法是复用 TP 社区已验证的 thinkphp-helper 或直接调用系统 mysqldump 命令,由它保证 SQL 正确性。
立即学习“PHP免费学习笔记(深入)”;
- 优先走 shell:检查
mysqldump是否在$PATH,用proc_open()调用,避免 PHP 自己拼 SQL - 连接参数从
config/database.php读取,但注意hostname可能是127.0.0.1,而mysqldump对localhost有 socket 特殊处理,建议统一用127.0.0.1 - 导出时加
--skip-extended-insert方便后续 diff,加--single-transaction减少锁表影响 - 别直接
exec("mysqldump ... > file.sql"),要用proc_open捕获 stderr,否则失败静默,你根本不知道密码错了还是库不存在
上传备份文件到远程服务器有哪些可靠方式
FTP/SFTP 是最常见选择,但 ftp_put() 在 PHP 8.1+ 已被废弃;ssh2_scp_send() 需要开启 ssh2 扩展,很多共享主机不支持;最无依赖的是 curl + 远程接收端(比如一个简单的 PHP 接收脚本)。
不过如果远程是同一家公司内网机器,用 rsync over ssh 更高效、支持断点续传、还能自动压缩。
- 用
rsync -avz --remove-source-files /path/to/backup.sql user@host:/backup/,比 scp 少一次本地读+网络发+远程写三阶段开销 - 如果必须用 PHP 上传,选
curl:设置CURLOPT_UPLOAD、CURLOPT_INFILE、CURLOPT_INFILESIZE,别用file_get_contents全读进内存 - 远程接收脚本必须校验
Content-MD5或签名,否则中间人可能篡改备份文件而不自知 - 上传后立即在远程执行
gzip backup.sql,节省空间;本地备份文件记得unlink(),不然磁盘迟早爆
定时任务里执行失败却没报错,怎么排查
Linux cron 执行 PHP 脚本时,环境变量和当前用户跟终端完全不同:没有 PATH、没加载 ~/.bashrc、mysql 或 rsync 命令可能找不到,且标准错误不会吐到屏幕。
最有效的调试方式,是把所有输出重定向到日志,并显式指定绝对路径。
- cron 行写成:
0 2 * * * cd /var/www/myapp && /usr/bin/php /var/www/myapp/think backup:remote >> /var/log/tp-backup.log 2>&1
- 在
handle()开头加error_log("Start at " . date('Y-m-d H:i:s'), 3, '/tmp/backup-debug.log'); - 所有外部命令(
mysqldump、rsync)都用绝对路径,用which mysqldump查准位置 - 别依赖
$_SERVER['HOME'],cron 下它常为空;临时目录统一用sys_get_temp_dir()
远程备份不是“写完就能跑”,光路径、权限、环境变量这三关,就够卡住八成的人。尤其注意 cron 用户对数据库账号是否有远程访问权限,以及目标服务器的磁盘配额是否真够用。



















