从PHP执行R脚本

时间:2017-04-13 03:23:57

标签: php r user-permissions

index.php

<?php
    echo exec("Rscript foo.R");
?>

foo.R

#!/usr/bin/env Rscript
print("Before!")
#library(rJava);
print("After!");

网页上的输出:

[1] "After!"

现在这是预期的输出,因为exec返回命令结果的最后一行。 现在,因为我想访问需要rJavaRMongo库的mongodb数据库,所以我修改了上面的代码。

foo.R

#!/usr/bin/env Rscript
print("Before!")
library(rJava);
print("After!");

网页上的输出:

[1] "Before!"

现在我不明白这个输出。我期望与之前相同的输出,即[1] "After!"。好像从库导入行开始的R代码根本不存在。我已经在kmeans中测试了上面的代码(以及我对从mongodb抓取的数据使用R shell时省略的代码),它按预期工作。

R脚本中导入库时出现了什么问题,该脚本是从PHP执行的?

更新1
有趣的是,如果我从命令行调用foo.R,则会根据我的期望调用并执行修改后的index.php

$ php index.php 
Loading required package: methods
[1] "After!"

所以我的结论是我的普通用户帐户可以执行index.php,而foo.R可以加载www-data中的库,但似乎R用户帐户没有权限加载www-data中的库1}}。

现在问题是如何授予R加载www-data库的权限?

更新2
我通过将apache用户从if更改为我当前的用户来暂时解决了这个问题,但我知道这是一个巨大的安全风险,我正在寻找替代解决方案。

2 个答案:

答案 0 :(得分:3)

首先,当www-user无法加载R库时,您应该确切地检查Apache日志中出现的错误。最可能的两个罪魁祸首是权限错误和库搜索路径不正确。

如果为本地用户而不是系统范围安装库,则www-data将无法找到它们,但Apache日志中的错误应显示此信息。

答案 1 :(得分:0)

另一种选择可能是您不使用PHP直接执行R脚本。

您可以使用像Redis这样的键值数据库或像Rabbitmq这样的排队系统。而不是直接执行脚本,而是向这些系统中的任何一个发送消息。

在命令行中执行php脚本,轮询其中任何一个系统以查找任何新消息,当它收到消息时,它会执行脚本并使用脚本的结果作出响应。

所以它将成为一个双向消息传递系统:

Script A ----> Queue ----> Script B  ----> R Script
R Script --result--> Script B ----> Queue ----> Script A

这是一个初期实施但有点安全和可扩展的系统。

我建议你看一下Celery