如何通过PHP的exec()函数向R脚本传递参数并在R中使用
PHP调用R脚本的参数传递解决方案
问题背景
需要从PHP代码中调用执行R脚本,将年份ye、月份mon两个参数从PHP传递到R脚本中使用,无参调用时脚本运行正常,传参时出现异常。
原错误原因分析
PHP的exec()函数语法为:
exec(string $command, array &$output = null, int &$result_code = null): string|false
之前的错误写法将自定义参数直接作为exec()的第二、第三参数传入,而这两个参数的实际作用是接收命令执行的输出结果、返回状态码,并非传递自定义参数,因此参数无法正确传入R脚本。
实现代码
无参时可正常运行的初始代码
PHP端初始代码
<?php exec('C:\"Program Files"\R\R-4.0.3\bin\Rscript.exe C:\xampp\htdocs\chatchops\R_privatChat\R_TodayOnline.R'); ?>
R端初始代码
library(dygraphs) library(DBI) library(RMySQL) library(htmlwidgets) #get db Connection mydb <- dbConnect(MySQL(), user='root', password='', dbname='chatchops', host='localhost', port=3307) ye <- '2021' mon <- '10' #get data from MySQL database query <- paste0("SELECT d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 FROM `analizeonlineeachmonthd` WHERE recYear = ",ye," AND recMonth = ",mon,";") result1 <- dbSendQuery(mydb, query) timeData <- fetch(result1) dbClearResult(result1) dbDisconnect(mydb)
正确传参写法
PHP端代码
将自定义参数用空格分隔,直接拼接在执行命令的R脚本路径之后即可,若参数包含特殊字符建议用escapeshellarg()处理后再拼接,避免命令注入风险:
<?php $ye = "2021"; $mon = "10"; // 可选参数转义处理,避免特殊字符导致解析错误 $ye = escapeshellarg($ye); $mon = escapeshellarg($mon); exec('C:\"Program Files"\R\R-4.0.3\bin\Rscript.exe C:\xampp\htdocs\chatchops\R_privatChat\R_TodayOnline.R ' . $ye . ' ' . $mon); ?>
R端接收代码
用commandArgs(TRUE)获取自定义参数,返回的数组顺序和PHP端拼接参数的顺序一一对应:
library(dygraphs) library(DBI) library(RMySQL) library(htmlwidgets) # 接收PHP传递的参数 args <- commandArgs(TRUE) ye <- args[1] mon <- args[2] #get db Connection mydb <- dbConnect(MySQL(), user='root', password='', dbname='chatchops', host='localhost', port=3307) #get data from MySQL database query <- paste0("SELECT d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 FROM `analizeonlineeachmonthd` WHERE recYear = ",ye," AND recMonth = ",mon,";") result1 <- dbSendQuery(mydb, query) timeData <- fetch(result1) dbClearResult(result1) dbDisconnect(mydb)
调试建议
如果传参后仍然运行异常,可以在PHP端接收exec的输出和状态码排查问题:
exec($command, $output, $return_var); // 打印执行输出和状态码,0代表执行成功,非0代表执行出错 var_dump($output); var_dump($return_var);
内容的提问来源于stack exchange,提问作者Kavishka Madhushan
相关产品推荐
相关产品推荐

