CLI 选项
概述
PHP CLI(命令行界面)提供了丰富的运行选项,用于控制 PHP 解释器的行为。这些选项包括执行脚本、直接运行代码、启动内置开发服务器、查看配置信息等,是 PHP 开发和运维的重要工具。
常用选项速查
php script.php— 执行脚本文件php -r 'code'— 直接执行 PHP 代码php -S localhost:8000— 启动内置 Web 服务器php -i— 显示 PHP 配置信息php -m— 列出已加载模块
基础概念
CLI vs CGI 模式
| 特性 | CLI 模式 | CGI/FPM 模式 |
|---|---|---|
| 无超时限制 | 默认无超时 | max_execution_time |
| 输出目标 | STDOUT | 响应 body |
| 工作目录 | 当前目录 | 脚本目录 |
$_SERVER | 精简 | 完整 HTTP 信息 |
| 内存限制 | 通常更大 | 默认 128MB |
| HTTP 头 | 不发送 | 通过 header() 发送 |
选项分类
| 类别 | 选项 | 说明 |
|---|---|---|
| 执行 | -f, -r, -B, -E | 脚本执行与代码预处理 |
| 服务器 | -S, -t | 内置 Web 服务器 |
| 配置 | -d, -c, -n, -a | ini 设置与加载 |
| 信息 | -i, -m, -v, -l | 查看模块与配置 |
| 语法 | -l, --syntax-check | 语法检查 |
语法与代码
基本执行选项
bash
# -f — 执行文件(默认行为,可省略)
php -f script.php
php script.php # 等同
# -r — 直接执行 PHP 代码(注意: 使用 PHP 标签)
php -r 'echo "Hello, World!\n";'
php -r 'echo date("Y-m-d H:i:s") . "\n";'
# -B — 在执行脚本前执行 PHP 代码
php -B 'define("APP_ENV", "cli");' script.php
# -E — 在执行脚本后执行 PHP 代码
php -E 'echo "Memory: " . memory_get_peak_usage(true) . "\n";' script.php
# 组合使用 — 脚本执行前后进行配置
php -B 'error_reporting(E_ALL);' -E 'echo "Done.\n";' script.php内置开发服务器
bash
# -S — 启动内置 Web 服务器(PHP 5.4+)
php -S localhost:8000
php -S 127.0.0.1:8080
php -S 0.0.0.0:9000 # 监听所有接口
php -S [::]:8000 # 监听 IPv6
# -t — 指定文档根目录
php -S localhost:8000 -t public/
php -S localhost:8000 -t /var/www/html
# router.php — 自定义路由脚本
php -S localhost:8000 router.php
# router.php 示例
if (php_sapi_name() === 'cli-server') {
// 内置服务器路由逻辑
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$file = __DIR__ . '/public' . $uri;
if ($uri !== '/' && file_exists($file) && !is_dir($file)) {
return false; // 交由服务器处理静态文件
}
// 所有其他请求转发到 index.php
require __DIR__ . '/public/index.php';
}配置选项
bash
# -d — 覆盖 php.ini 设置
php -d display_errors=1 -d error_reporting=E_ALL script.php
php -d memory_limit=512M -d max_execution_time=0 script.php
php -d extension=redis script.php # 加载扩展
# -c — 指定 php.ini 文件路径
php -c /etc/php/custom.ini script.php
php -c /etc/php/cli/ script.php # 指定 ini 目录
# -n — 不使用 php.ini(纯净模式,不加载任何 ini 配置)
php -n script.php
# -a — 交互式 shell(REPL)
php -a
# php >
# php > echo "Hello\n";
# php > $array = [1, 2, 3];
# php > print_r($array);
# php > exit
# --ini — 显示已加载的 ini 文件
php --ini
# 输出: Configuration File (php.ini) Path: /usr/local/etc/php
# Loaded Configuration File: /usr/local/etc/php/php.ini信息查看选项
bash
# -i — 显示完整的 PHP 信息(等同 phpinfo())
php -i
php -i | grep "mysql"
php -i | grep "redis"
# -m — 列出已加载的 PHP 模块
php -m
# 输出: [PHP Modules]
# bcmath, calendar, Core, ctype, curl, date, dom, fileinfo, filter, ...
# -v — 显示 PHP 版本
php -v
# 输出: PHP 8.3.0 (cli) (built: Nov 21 2023 10:30:00) (NTS)
# -l — 语法检查(不执行)
php -l script.php
# 输出: No syntax errors detected in script.php
# 或: Parse error: syntax error, unexpected ';' in script.php on line 10
# --ri — 显示扩展信息
php --ri redis
php --ri mysqli
php --ri pdo_mysql
# -h — 显示帮助信息
php -h-l 语法检查的用途
- CI/CD 流水线中的代码质量检查
- 编辑器保存时自动语法检查
- 部署前的快速验证
- 批量检查整个项目:
find . -name "*.php" -exec php -l {} \;
实战示例
开发服务器脚本
bash
#!/bin/bash
# dev-server.sh — 开发服务器启动脚本
HOST="${1:-localhost}"
PORT="${2:-8000}"
DOCROOT="${3:-public}"
echo "启动开发服务器: http://{$HOST}:{$PORT}"
echo "文档根目录: {$DOCROOT}"
echo "按 Ctrl+C 停止"
php -S "${HOST}:${PORT}" -t "${DOCROOT}" -d display_errors=1 -d error_reporting=E_ALLphp
<?php
// server.php — 带路由的开发服务器
if (php_sapi_name() === 'cli-server') {
$uri = urldecode(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
// 静态文件直接返回
$filePath = __DIR__ . '/public' . $uri;
if ($uri !== '/' && file_exists($filePath) && !is_dir($filePath)) {
return false;
}
// API 路由
if (str_starts_with($uri, '/api/')) {
require __DIR__ . '/public/index.php';
return true;
}
// SPA fallback — 所有未匹配的请求返回 index.html
require __DIR__ . '/public/index.html';
return true;
}PHP 代码执行器
bash
#!/bin/bash
# php-exec.sh — 快速执行 PHP 代码片段
# 从 stdin 读取代码
echo '<?php echo strtoupper(readline("Input: "));' | php
# 从文件读取代码
php -r "$(cat code_snippet.php)"
# 多行代码
php -r '
$items = ["apple", "banana", "cherry"];
foreach ($items as $item) {
echo strtoupper($item) . "\n";
}
'批量语法检查
bash
#!/bin/bash
# lint-check.sh — 批量语法检查
PHP_BIN="${PHP_BIN:-php}"
ERRORS=0
TOTAL=0
# 查找所有 PHP 文件并检查语法
while IFS= read -r -d '' file; do
TOTAL=$((TOTAL + 1))
OUTPUT=$($PHP_BIN -l "$file" 2>&1)
if [ $? -ne 0 ]; then
echo "FAIL: $file"
echo "$OUTPUT"
ERRORS=$((ERRORS + 1))
fi
done < <(find . -name "*.php" -not -path "*/vendor/*" -print0)
echo ""
echo "检查完成: {$TOTAL} 个文件, {$ERRORS} 个错误"
if [ $ERRORS -gt 0 ]; then
exit 1
fi环境检测工具
bash
#!/bin/bash
# php-env.sh — PHP 环境信息报告
echo "========== PHP 环境信息 =========="
echo ""
echo "PHP 版本:"
php -v | head -1
echo ""
echo "PHP SAPI:"
php -r 'echo PHP_SAPI . "\n";'
echo ""
echo "已加载模块数:"
php -m | grep -c "^."
echo ""
echo "关键模块检查:"
for ext in curl mbstring openssl pdo pdo_mysql redis json xml zip; do
if php -m | grep -qi "^$ext$"; then
echo " ✓ $ext"
else
echo " ✗ $ext (未安装)"
fi
done
echo ""
echo "重要配置:"
php -r '
$configs = ["memory_limit", "max_execution_time", "upload_max_filesize", "post_max_size", "date.timezone"];
foreach ($configs as $c) {
echo " $c = " . ini_get($c) . "\n";
}
'
echo ""
echo "OpCache 状态:"
php -r 'echo "OpCache: " . (function_exists("opcache_get_status") ? "已启用" : "未启用") . "\n";'
echo ""
echo "======================================"注意事项
-r 选项的语法要求
bash
# -r 选项中的代码不需要 <?php 标签
php -r 'echo "Hello\n";' # 正确
php -r '<?php echo "Hello\n";' # 错误: 不需要 <?php
# 但需要处理 shell 的特殊字符
php -r 'echo "Price: $100\n";' # 错误: $ 被 shell 解释
php -r 'echo "Price: \$100\n";' # 正确: 转义 $
# 推荐使用单引号包裹,避免 shell 变量替换
php -r 'echo getcwd() . "\n";'
# 多行代码
php -r '
$data = json_decode(file_get_contents("config.json"), true);
print_r($data);
'内置服务器限制
bash
# 内置服务器限制:
# 1. 单线程 — 一次只能处理一个请求
# 2. 无 HTTPS — 仅 HTTP(需配合 nginx 反向代理)
# 3. 不适合生产环境 — 仅用于开发/测试
# 生产环境使用 Nginx + PHP-FPM:
# server {
# listen 80;
# root /var/www/public;
# location / {
# try_files $uri /index.php?$query_string;
# }
# location ~ \.php$ {
# fastcgi_pass unix:/run/php/php-fpm.sock;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# include fastcgi_params;
# }
# }内置服务器安全
内置开发服务器默认监听所有接口(0.0.0.0 时)。确保在防火墙内使用,或绑定到 127.0.0.1。不要在生产环境中暴露内置服务器。
最佳实践
1. 项目入口脚本
bash
#!/bin/bash
# bin/run — 项目统一入口脚本
PHP_BIN="${PHP_BIN:-php}"
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
case "$1" in
server)
$PHP_BIN -S "${2:-localhost:8000}" -t "${ROOT_DIR}/public"
;;
test)
$PHP_BIN -d memory_limit=512M vendor/bin/phpunit "${@:2}"
;;
lint)
find "$ROOT_DIR/src" -name "*.php" -exec $PHP_BIN -l {} \;
;;
env)
$PHP_BIN -r "phpinfo();" | less
;;
modules)
$PHP_BIN -m
;;
version)
$PHP_BIN -v
;;
*)
echo "Usage: bin/run {server|test|lint|env|modules|version}"
exit 1
;;
esac2. 常用命令速查
bash
# 语法检查所有文件
find . -name "*.php" ! -path "*/vendor/*" -exec php -l {} \; 2>&1 | grep -v "No syntax errors"
# 查看模块信息
php --ri openssl
php --ri pdo_mysql
# 快速测试代码
php -r 'var_dump(json_decode("{\"a\":1,\"b\":2}", true));'
# 启动 HTTPS 服务器(需配合 stunnel 或 mkcert)
mkcert -install
php -S localhost:8443 -t public/
# 内存分析
php -d memory_limit=1G script.php