webman自定义命令必须通过./webman make:command生成,因裸脚本跳过support/bootstrap.php导致di容器未初始化,故config()、db::table()等调用失败并报“call to a member function on null”;生成的命令类需继承symfony\component\console\command\command,且static $defaultname须为字符串字面量(如'db:backup'),参数统一用$input->getargument()或$input->getoption()获取,框架已注入完整上下文。

Webman 自定义命令必须走 webman/console 插件机制,否则 config()、Db::table() 等调用必然失败——裸跑 PHP 脚本跳过了 support/bootstrap.php 初始化,容器、配置、数据库连接全为空。
为什么直接 php script.php 会报 Call to a member function get() on null
错误本质是 DI 容器未初始化。Webman 启动依赖 support/bootstrap.php 执行完整生命周期:注册服务、加载配置、初始化数据库连接器。裸脚本即使 require autoload 和 bootstrap,也大概率失败——因为 bootstrap.php 内部依赖 start.php 的执行上下文(如 define('WEBMAN_START', true)),而该上下文在 CLI 直接运行时不存在。
常见现象包括:
-
config('database')返回null -
Db::table('user')报Call to a member function table() on null -
Log::info()静默丢弃日志,不写入文件
如何用 ./webman make:command 创建可用命令
这是唯一被框架支持的路径。执行命令生成骨架类后,handle() 或 execute() 方法内可直接使用全部框架能力,无需手动初始化。
- 运行
./webman make:command db:backup→ 生成app/command/DbBackupCommand.php - 类必须继承
Symfony\Component\Console\Command\Command -
static $defaultName必须是字符串字面量,例如'db:backup',不能拼接或从变量读取,否则./webman list不识别 - 参数获取统一用
$input->getArgument('name')或$input->getOption('force'),别碰$argv - 数据库操作、配置读取、日志写入均可直接调用,框架已注入完整上下文
命令中访问数据库或配置时容易踩的坑
看似能跑通,但实际行为可能错位,根源常在环境隔离和连接复用上。
- 开发环境
config/database.php默认用 mysql 连接,但命令行运行时若未显式指定APP_ENV=console,会误读.env中的DB_DATABASE=homestead—— 该库在生产服务器上根本不存在 - 多线程/多进程命令下,数据库连接未显式关闭,可能导致连接池耗尽或事务残留
- 命令执行过程中修改了全局配置(如
config(['app.debug' => true])),会影响后续命令或 Web 请求,建议用临时副本而非直接改原配置 - 长命令(如数据迁移)未设置超时或心跳,可能被系统 kill,需配合
set_time_limit(0)和ignore_user_abort(true)
传参解析别依赖 getopt() 处理子命令
Webman 命令本身基于 Symfony Console,但如果你在自定义脚本里手动解析参数,getopt() 对子命令完全无感。
-
php start.php user create --name=john中,getopt()在遇到user(非选项参数)时就停止,--name=john根本不会被解析到 - 子命令逻辑必须手动切分
$_SERVER['argv'],从索引 1 开始判断第一个非选项参数,再根据它分发后续逻辑 - 带空格的值必须用引号包裹:
php start.php handle --message="hello world"→$_SERVER['argv'][2]是--message=hello world,不是两个独立字符串 - 所有值都是字符串,
"42"不会自动转成整型,需手动(int)或filter_var($val, FILTER_VALIDATE_INT)
真正难的不是写命令,而是让命令在不同环境(dev/console/prod)、不同调用方式(./webman cmd / php webman cmd / crontab)下始终读到正确的配置、连上正确的数据库、不干扰主服务的连接池和日志通道。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











