dou760663
dou760663
采纳率100%
2017-04-13 03:23

从PHP执行R脚本

已采纳

index.php:

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

foo.R:

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

Output on webpage:

[1] "After!"

Now this is an expected output as exec returns the last line from the result of the command. Now since I want to access the mongodb database which needs rJava and RMongo libraries I modified the above code a little bit.

foo.R:

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

Output on webpage:

[1] "Before!"

Now I don't understand this output. I expected the same output as before i.e [1] "After!". It's as if the R code starting from the library import line doesn't exist at all. I have tested the above code (and the omitted one where I use kmeans on the data grabbed from mongodb) in R shell and it works as expected.

What's wrong with importing a library in a R script which is meant to be executed from PHP?


Update 1:
Interestingly, the modified foo.R gets invoked and executed as per my expectation if I invoke index.php from command line.

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

So my conclusion is that my normal user account can execute index.php which in turn can load libraries in foo.R but it seems www-data user account has no permissions to load libraries in R.

So now the question is how do I give permissions to www-data to load R libraries?


Update 2:
I solved this issue temporarily by changing apache user from www-data to my current user but I'm aware this is a huge security risk and I'm looking for an alternative solution.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • dongyuchen0214 dongyuchen0214 4年前

    First, you should check exactly what error you are getting in your Apache logs when www-user fails to load R libraries. The two most likely culprits are a permissions error and an incorrect library search path.

    If the libraries are installed for the local user instead of system-wide, then www-data will not be able to find them, but the errors in the Apache logs should reveal this information.

    点赞 评论 复制链接分享
  • douzheng1853 douzheng1853 4年前

    Another alternative could be that you don't use PHP to directly execute the R script.

    You can use a key-value database like Redis or a queuing system like Rabbitmq. Rather then executing the script directly, send a message to either of these systems.

    Execute a php script in command line that polls either of these systems to look for any new messages and when it receives the message it executes the script and responds back with the result from the script.

    So it will become a two-way messaging system:

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

    This is a bit complicated system to initially implement but definitely secure and scalable.

    I would suggest you to look at Celery.

    点赞 评论 复制链接分享

相关推荐