Background: I'm building a website with PHP, and I need to have the website call a script that's written in Ruby 1.9. I'm using a CentOS 5.10 server that already had Ruby 1.8 installed on it, and I used RVM to upgrade to Ruby 1.9. When I type
It's important to keep in mind that the user that runs the web server process which executes your PHP script is different from you, the user, when using the command line. To verify this, you can create a php script like the following:
<?php print exec('whoami');
Run that script as yourself from the command line, and you'll see your username. Put that script in a web accessible folder, and run it through your web browser (for example:
http://localhost/whoami.php), and you'll probably see a username like
You can also compare which ruby is running between you at the command line and your web browser. Use the following php script:
<?php print exec('which ruby');
Run that from the command line and then also run that in your web browser. Those should be two different locations - and, of course, that's your core problem.
When you installed rvm, it's likely that a line of code was appended to your
.profile file in your home folder. Look near the end of either of those files to see if there is a line that looks similar to this:
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*
This line initializes your shell environment every time you login or open a terminal so that rvm is accessible. To verify this, you can create a php file with the following:
<?php print exec('env | grep rvm');
Running this as yourself, from the command line, you should see lines related to
rvm_path and others. But, put this script in a web accessible folder and run it from your browser - you'll notice that none of those lines are outputted to your browser. That's because the shell that the PHP process spawns, when running as
www-data user (or whatever user your web server runs as) doesn't have the same rvm initialization lines that your
`.bash_profile script has.
One possible way to solve this problem is to set the correct environment variables in PHP so that, when
exec is called, it is called within an environment that is already properly initialized to run rvm related things (like setting the ruby version). But, most likely, there are certain safe_mode protections on PHP which prevent you from setting those environment variables in your PHP script.
The other solution, which is a bit of a hack, is to have your PHP script in the browser run the same ruby interpreter that you would run in the command line. That is, instead of
exec('ruby some_ruby_file.rb'), you would do
exec('/home/my_username/.rvm/rubies/ruby-1.9/bin/ruby some_ruby_file.rb') - I just made up that path to your ruby interpreter. From the command line, run
which ruby to find out the exact path to your ruby interpreter. BUT you have to make sure that
www-data has permission to run this ruby interpreter in your folder. To avoid this hassle, though this is even more of a hack, is simply to make a copy of that ruby interpreter and place it in a bin folder owned by
www-data, and have your PHP script
exec that ruby interpreter.