使用Procmail管道调用PHP脚本时,如何传递参数供脚本校验?
解决Procmail向PHP脚本传递触发标识的问题
你之前的写法无效是因为对PHP CLI的参数规则不熟悉,以下是几种可行的解决方案:
方案1:直接传递命令行参数
PHP CLI模式下通过$argv数组接收命令行参数,Procmail里直接在脚本路径后追加参数即可:
Procmail配置:
:0 * ^To.info@domain.com|^Subject.*(REMOVE|Undelivered Mail) | /usr/bin/php -f /var/www/somefolder/script.php iscron=1
PHP脚本处理:
// script.php // 直接获取第一个参数($argv[0]是脚本文件名) if (isset($argv[1]) && $argv[1] === 'iscron=1') { // 执行对应触发逻辑 } // 或者更灵活的键值对解析 $triggerParams = []; foreach ($argv as $arg) { if (strpos($arg, '=') !== false) { list($key, $value) = explode('=', $arg, 2); $triggerParams[$key] = $value; } } if (!empty($triggerParams['iscron']) && $triggerParams['iscron'] === '1') { // 处理触发逻辑 }
方案2:通过环境变量传递
Procmail可以先设置环境变量,PHP脚本通过getenv()读取:
Procmail配置:
:0 * ^To.info@domain.com|^Subject.*(REMOVE|Undelivered Mail) TRIGGER_SOURCE=procmail_remove_or_info | /usr/bin/php -f /var/www/somefolder/script.php
PHP脚本处理:
// script.php $triggerSource = getenv('TRIGGER_SOURCE'); if ($triggerSource === 'procmail_remove_or_info') { // 执行对应逻辑 }
方案3:按触发条件拆分规则(更清晰)
如果需要区分是收件人匹配还是主题匹配触发的,可以拆分Procmail规则,传递不同标识:
Procmail配置:
# 匹配收件人为info@domain.com的情况 :0 * ^To.info@domain.com | /usr/bin/php -f /var/www/somefolder/script.php trigger=to_info # 匹配主题包含REMOVE/Undelivered Mail的情况 :0 * ^Subject.*(REMOVE|Undelivered Mail) | /usr/bin/php -f /var/www/somefolder/script.php trigger=subject_match
PHP脚本处理:
// script.php if (isset($argv[1])) { switch ($argv[1]) { case 'trigger=to_info': // 处理收件人匹配的逻辑 break; case 'trigger=subject_match': // 处理主题匹配的逻辑 break; } }
为什么之前的写法无效?
script.php?iscron=1:这是HTTP请求的查询字符串格式,PHP CLI会把整个字符串当作脚本文件名,自然找不到对应的文件。--iscron=1:双横线是GNU风格的长选项,但PHP CLI的-f参数后只需要指定脚本文件名,后续参数直接写即可,不需要加双横线;加了之后PHP会把--iscron=1当作脚本的参数,但这种写法没必要,直接写参数更简洁。
内容的提问来源于stack exchange,提问作者jamminjames
相关产品推荐
相关产品推荐

