命令行接口

oxphp 二进制文件有三种角色:serve(启动 HTTP 服务器)、run(将单个 PHP 脚本运行至结束),以及 config(配置工具)。不带任何参数的裸 oxphp 是一次隐式的 serve,因此发布镜像里的 CMD ["oxphp"] 会照常启动服务器,无需改动。

text
USAGE: oxphp [OPTIONS] oxphp <COMMAND> [OPTIONS] oxphp serve [--user=<name|uid[:gid]>] oxphp run [-d key=value]... [--user=<spec>] <script.php> [args]... oxphp [-d key=value]... [--user=<spec>] <script.php> [args]... OPTIONS: -h, --help Print this help and exit -v, --version Print version information and exit COMMANDS: serve Start the HTTP server (default; same as bare 'oxphp') run Execute a single PHP script under CLI semantics and exit config Configuration utilities (see 'oxphp config --help')

角色由关键字来选择。serverunconfig 这几个确切的词元用于选取子命令;其他任何作为第一个位置参数出现的内容都会被当作脚本路径,因此 oxphp ./bin/migrate.php 就是 oxphp run ./bin/migrate.php 的简写形式。这里没有基于扩展名的推断:PHP 是按文件内容来执行的,所以没有扩展名的脚本同样能运行。文件不存在的情况由文件系统报告,与 php 完全一致。

oxphp serve

启动 HTTP 应用服务器,即默认角色。oxphpoxphp serve 是等价的。配置通过环境变量完成;serve 本身只接受 --user

bash
oxphp # implicit serve — best-effort drop to www-data oxphp serve # explicit — same default oxphp serve --user=appuser # drop to a specific user (fail-fast) oxphp serve --user=root # opt out: keep running as root

默认情况下,在不带 --user 时,serve 会尽力(best-effort)降权到 www-data。以 root 身份启动、且系统中存在 www-data 账户时(正如官方镜像那样),它会以 root 绑定监听端口,然后在提供任何流量之前永久降权到 www-data。以非 root 身份启动时,它会保持当前用户;以 root 身份在没有 www-data 账户的主机上启动时,它会记录一条警告并继续以 root 运行。这一默认行为绝不会中止启动。

--user=<spec> 会覆盖目标用户,并采用快速失败(fail-fast)策略:它以 root 绑定端口,然后永久降权到该用户,如果并非以 root 身份启动则以错误退出。传入 --user=root 可有意保持 root。完整的用法、<spec> 语法以及文件权限检查清单,参见在 80 端口以非 root 运行

oxphp run

oxphp run <script.php> [args…] 将单个 PHP 文件运行至结束,并以脚本自身的退出码退出。它在主线程上运行:没有监听器,没有工作进程池,也没有请求队列。PHP_SAPI === 'cli',并且 phpinfo() 打印的是文本而非 HTML,与原生 php CLI 行为一致。

bash
oxphp run migrate.php oxphp run bin/console.php cache:clear oxphp run -d memory_limit=512M import.php data.csv

对于数据库迁移、定时任务、队列消费者,以及 artisan/console 风格的命令,都该用这个角色,而且就在为你的应用提供服务的同一镜像里运行,无需第二套 PHP 安装。

完整的 OxPHP 引擎就在脚本底层可用:纤程oxphp_sleep())和共享状态OxPHP\Shared\*)开箱即用。异步 promiseoxphp_async())在 ASYNC_WORKERS 大于 0 时生效;默认调用不会启动异步工作进程池,因此也不会启动后台运行时。

$argv$argc 会被填充($argv[0] 是脚本路径),并且 STDIN / STDOUT / STDERR 均已定义,因此 Composer 和 Symfony Console 风格的入口点无需修改即可运行。

脚本路径就是分隔符

脚本路径之后的每个词元都会原样交给 PHP,包括以 -- 为前缀的那些,因此对于普通参数你无需显式的 --。要传给 oxphp 自身的标志(-d--user)必须放在脚本路径之前;脚本路径之后的一切都属于脚本。

bash
oxphp run console.php migrate --force --pretend # ▲ script └──────────────┬──────────┘ # $argv[1..], passed to PHP verbatim (oxphp parses nothing here)

因此 oxphp run console.php --force 会在 $argv 中把 --force 交给脚本,而 oxphp run --force console.php 则是一个错误:--force 位于脚本路径之前,在那个位置 oxphp 只接受 -d / --user / --help

-- 选项结束标记

oxphp 遵循标准的 -- 选项结束标记,而它恰好只在一处有意义:在脚本路径之前,当脚本路径本身以短横线开头时。-- 会停止选项解析,使下一个词元被当作脚本路径,并由 oxphp 消费;它不会被转发给 PHP。

bash
oxphp run -- -odd-name.php # runs the script "-odd-name.php" oxphp -- -odd-name.php # same, implicit form oxphp run -odd-name.php # error: parsed as options → "unexpected argument to 'run': -o"

脚本路径之后已没有任何选项需要终止,所以那里的 -- 只是普通数据,会原样传给 PHP,与 php 完全一致:

bash
oxphp run app.php -- --raw # $argv = ["app.php", "--", "--raw"]

Shebang 脚本

开头的 #! 行会在编译前被跳过,因此一个可执行、无扩展名、带有 oxphp shebang 的脚本可以直接运行:

greet
#!/usr/bin/env oxphp <?php echo "hello from a shebang script\n";
bash
chmod +x ./greet ./greet

-d ini 覆盖

-d key[=value] 为本次运行设置一条 php.ini 指令。它可重复使用,且裸写 -d key 会把值设为 "1"。这些覆盖在模块启动之前应用,因此对每一种指令类型都会压过 php.ini,包括运行时 ini_set() 无法更改的 PHP_INI_SYSTEM / PHP_INI_PERDIR 指令(opcache.*register_argc_argv……)。

bash
oxphp run -d memory_limit=1G -d display_errors=1 report.php

run 的默认 ini

run 角色会在你的 -d 覆盖和 php.ini 之前应用一批面向 CLI 的默认值:

Directive Default Why
max_execution_time 0 一次性作业(迁移、导入器、守护进程)不能被 SIGALRM 杀掉。
max_input_time -1 CLI 没有输入解析的截止期限。
display_errors stderr 错误输出到标准错误,而非标准输出。
html_errors 0 面向终端的纯文本错误。
output_buffering 0 输出一经产生即写出。
implicit_flush 1 每次写入都立即刷新。
register_argc_argv 1 $argv / $argc 可用。
Note

超全局变量run 始终启用:一次性脚本需要 $argv$_SERVER$_ENV。无论适用于 HTTP 服务器的 SUPERGLOBALS_ENABLED 开关如何设置,这一点都成立。

退出码

Code Meaning
脚本自身的退出码 exit($code) / die($code),或干净结束时为 0
255 致命错误、未捕获的异常,或解析错误。
1 无法打开脚本路径(oxphp: Could not open input file: <path>)。
2 一个无效的 -d 参数。

无法打开文件的情况会在引擎启动之前检查,因此一个缺失或不可读的脚本会以 php 风格的消息快速失败,而不是先启动引擎再因编译错误而崩溃。

run 路径上的 --user

run 遵循与 serve 相同的默认行为:在不带 --user 时,它会在脚本执行前尽力降权到 www-data(当已是非 root 时静默跳过)。oxphp run --user=<spec> <script.php> 会覆盖目标用户,从而让一个以 root 启动的一次性作业能以某个特定的非特权用户运行;--user=root 则保持 root。<spec> 语法和降权机制与 serve --user 完全相同;以非 root 身份启动却显式指定 --user 是一个硬性错误。

oxphp config

配置工具。--check 会校验环境变量配置并报告问题,而不启动服务器。

bash
oxphp config --check
text
config: OK

该检查仅涵盖文件系统层面的合理性:路径是否存在,以及文件/目录的类型(DOCUMENT_ROOTENTRY_FILETLS_CERTTLS_KEYERROR_PAGES_DIR……)。PHP 运行时、TLS 握手和网络绑定都不在检查范围内。校验失败时它以非零退出并打印 config: INVALID,每个问题占一行。

Tip

由于 oxphp config --check 在配置无效时以非零退出,它可以作为入口脚本或 CI 作业中的启动前门禁。

--help--version

bash
oxphp --help # full usage oxphp config --help # config subcommand usage oxphp --version # version and the feature flags compiled into this binary

oxphp --version 会报告该构建启用的特性(例如 php, plugin-apm, plugin-async),这是确认某个镜像是否构建了 APM、async 或其他可选插件的最快方式。

后续步骤