PHP无法识别我的RVM Ruby安装

时间:2014-02-04 01:18:14

标签: php ruby rvm centos5

背景:我正在使用PHP构建一个网站,我需要让网站调用一个用Ruby 1.9编写的脚本。我正在使用已经安装了Ruby 1.8的CentOS 5.10服务器,我使用RVM升级到Ruby 1.9。当我从命令行输入ruby --version时,它说我安装了Ruby 1.9(正如预期的那样)。但是,当我使用PHP调用exec('ruby --version');时,它说我安装了Ruby 1.8。另外,当我使用PHP来调用exec('which rvm');时,即使我知道安装了RVM,它也不会返回任何内容。

问题:如何让PHP使用Ruby 1.9的RVM安装而不是Ruby 1.8的系统安装?

2 个答案:

答案 0 :(得分:2)

重要的是要记住,在使用命令行时,运行执行PHP脚本的Web服务器进程的用户与您(用户)不同。要验证这一点,您可以创建如下所示的PHP脚本:

<?php

print exec('whoami');

从命令行运行该脚本,您将看到您的用户名。将该脚本放在可访问Web的文件夹中,然后通过Web浏览器运行(例如:http://localhost/whoami.php),您可能会看到apachewww-data等用户名。

您还可以在命令行和Web浏览器之间比较您之间运行的ruby。使用以下php脚本:

<?php

print exec('which ruby');

从命令行运行它,然后在Web浏览器中运行它。那些应该是两个不同的位置 - 当然,这是你的核心问题。

安装rvm后,可能会在主文件夹中的.bash_profile.profile文件中附加一行代码。查看其中任何一个文件的末尾,看看是否有与此类似的行:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*

每次登录或打开终端时,此行都会初始化您的shell环境,以便可以访问rvm。要验证这一点,您可以使用以下命令创建一个php文件:

<?php

print exec('env | grep rvm');

从命令行运行此操作,您应该看到与rvm_bin_pathrvm_path及其他相关的行。但是,将此脚本放在可访问Web的文件夹中并从浏览器运行 - 您会注意到这些行都没有输出到您的浏览器。这是因为PHP进程生成的 shell ,当作为www-data用户(或您的Web服务器运行的任何用户)运行时,没有与{{1}相同的rvm初始化行脚本有。

解决此问题的一种可能方法是在PHP中设置正确的环境变量,以便在调用`.bash_profile时,在已经正确初始化以运行rvm相关事物的环境中调用它(如设置红宝石版)。但是,最有可能的是,PHP上存在某些safe_mode保护,这会阻止您在PHP脚本中设置这些环境变量。

另一个解决方案就是让您的PHP脚本在浏览器中运行与您在命令行中运行的相同的 ruby​​解释器。也就是说,代替exec,你会做exec('ruby some_ruby_file.rb') - 我只是编写了你的​​ruby解释器的路径。从命令行运行exec('/home/my_username/.rvm/rubies/ruby-1.9/bin/ruby some_ruby_file.rb')以找出ruby解释器的确切路径。 您必须确保which ruby有权在您的文件夹中运行此ruby解释器。为了避免这种麻烦,虽然这更像是一个黑客攻击,只需复制一个ruby解释器并将其放在www-data拥有的bin文件夹中,并让你的PHP脚本www-data红宝石翻译。

答案 1 :(得分:0)

您必须指定ruby和gem_home的完整路径。

示例,让我工作:

        var_dump(exec("
export GEM_HOME='/home/www/.rvm/gems/ruby-2.3.0';
export GEM_PATH='/home/www/.rvm/gems/ruby-2.3.0:/home/www/.rvm/gems/ruby-2.3.0@global';
export MY_RUBY_HOME='/home/www/.rvm/rubies/ruby-2.3.0';

/home/www/.rvm/rubies/ruby-2.3.0/bin/ruby public/okcredit.ge/scripts/restrictions-and-pledges-bot/crawler.rb"));