48

My system is Ubuntu and I have set my environment variables in /etc/environment.

If I'm running PHP script using CLI - environment variables from /etc/environment are recognized.

But, if I go to execute PHP script thru http://domain/test.php (that is apache2handler) exactly the same script prints out NULL, meaning environment variables from /etc/environment are not loaded.

The fix I did was adding variables in /etc/apache2/envvars and that solved the problem.

But that is two different files, which then have to be kept in sync.

How can I make PHP / Apache load and recognize environment variables from /etc/environment (system)?

EDIT: To clarify things, when I say 'not loaded into PHP' it means variables from /etc/environment are not set in $_SERVER, $_ENV, getenv() and do not exists in $GLOBALS. In other words 'are not loaded into PHP'.

Aaron Miller
  • 3,692
  • 1
  • 19
  • 26
rock3t
  • 2,193
  • 2
  • 19
  • 24

4 Answers4

67

Original reply in 2014

I had exactly the same problem. To solve it, I just sourced /etc/environment inside /etc/apache2/envvars.

The content of /etc/environment:

export MY_PROJECT_PATH=/var/www/my-project
export MY_PROJECT_ENV=production
export MY_PROJECT_MAIL=support@my-project.com

The content of /etc/apache2/envvars:

# Load all the system environment variables.
. /etc/environment

Now, I'm able to use these variables in the Apache Virtual Host config files and in PHP.

Here's an example of an Apache virtual host:

<VirtualHost *:80>
  ServerName my-project.com
  ServerAlias www.my-project.com
  ServerAdmin ${MY_PROJECT_MAIL}
  UseCanonicalName On

  DocumentRoot ${MY_PROJECT_PATH}/www

  # Error log.
  ErrorLog ${APACHE_LOG_DIR}/my-project.com_error.log
  LogLevel warn

  # Access log.
  <IfModule log_config_module>
    LogFormat "%h %l %u %t \"%m %>U%q\" %>s %b %D" clean_url_log_format
    CustomLog ${APACHE_LOG_DIR}/my-project.com_access.log clean_url_log_format
  </IfModule>

  # DocumentRoot directory
  <Directory ${MY_PROJECT_PATH}/www>
    # Disable .htaccess rules completely, for better performance.
    AllowOverride None
    Options FollowSymLinks Includes
    Order deny,allow
    Allow from All

    Include ${MY_PROJECT_PATH}/config/apache/inc.mime-types.conf
    Include ${MY_PROJECT_PATH}/config/apache/inc.cache-control.conf

    # Rewrite rules.
    <IfModule mod_rewrite.c>
      RewriteEngine on
      RewriteBase /

      # Include all the common rewrite rules (for http and https).
      Include ${MY_PROJECT_PATH}/config/apache/inc.rewriterules-shared.conf
    </IfModule>
  </Directory>
</VirtualHost>

And this is an example of how to access them with PHP:

<?php
header('Content-Type: text/plain; charset=utf-8');
print getenv('MY_PROJECT_PATH') . "\n" .
      getenv('MY_PROJECT_ENV') . "\n" .
      getenv('MY_PROJECT_MAIL') . "\n";
?>

Update from 2020

As mentioned by several of you, this method is rather old and not secure as we don't want the web server to know all about the other environment variables and let them be accessible by attackers.

My answer is very old and clearly not valid any more!

The main idea was to have a single place to define some project constants and to have them available at several places (bash scripts, Apache or Nginx conf, PHP scripts). You could have a project file containing these vars and only source this one in /etc/apache2/envvars and /etc/environment.

Since a few years, I use Ansible to deploy my projects. This way, I can define some constants or variables and inject them into multiple configuration files. I also have the flexibility to override them and have variations of them if I deploy to a cluster of servers.

Patrick Janser
  • 3,318
  • 1
  • 16
  • 18
  • 1
    In my case, in /etc/environment I had to separate each variable declaration into two lines: first `export VAR` and then `VAR="myVar"`, otherwise it wouldn't work – cafonso Aug 01 '14 at 09:06
  • This worked for me but I used `/etc/profiles.d/myproject.sh` (on Ubuntu Raring). – willoller Oct 03 '14 at 16:51
  • 1
    On my (Ubuntu 16.04LTS) system I had to COMBINE the export statements in /etc/environment like this: `export MY_VAR='foo'` – sean.boyer Oct 24 '16 at 16:49
  • 1
    Ubuntu 16.04 LAMP stack: Strangely above method did not work. But at last I was able to achieve the goal by using **SetEnv** in _/etc/apache2/sites-available_ as `SetEnv VARNAME myvariable` All thanks to [Set Environment Variables in Apache for Php](https://coderwall.com/p/mvcqcg/set-environment-variables-in-apache-for-php) – Vinay Vissh Mar 28 '17 at 18:01
  • Inserting the variables directly into `/etc/apache2/envvars` suffices tho :-) – kawerewagaba Mar 29 '19 at 05:55
  • 1
    Piggybacking off of this, there is also a PHP.ini setting to allow access to environment variables - it seems disabled by default in 7.2. The setting `variables_order` needs the character `'E'` in it. https://www.php.net/manual/en/ini.core.php#ini.variables-order – zbee Jul 24 '19 at 09:40
  • 1
    FWIW I would strongly discourage against using the `/etc/environment` file to source the environment variables from, especially using a [technically] invalid environment format with those "export" lines. If you do, watch for the Ubuntu snapd service dumping all of your environment variables to the system log every time it restarts! – taiidani Sep 13 '19 at 15:16
  • As of 2020, with current versions of Ubuntu and Apache Httpd 2, none of these methods seem to work any longer. It appears they have been disabled for security reasons. The only way I know to get environment variables into PHP is by hard-setting them with SetEnv inside the directive. Am I wrong? – blitter Jul 25 '20 at 19:09
  • Thanks all of you for your feedback. Yes, effectively, **my answer is very old** and clearly not valid anymore! The main idea was to have a single place to define some project constants and to have them available at several places (bash scripts, Apache or Nginx conf, PHP scripts). **Actually, I use Ansible to deploy my projects**. This way, I can define some constants or variables and inject them into multiple configuration files. – Patrick Janser Aug 03 '20 at 06:03
3

On ubuntu, PHP uses different ini files for regular and CLI processes.

There should be few ini files like /etc/php5/cli/php.ini, /etc/php5/fpm/php.ini or /etc/php5/php.ini. Open related INI file and change the

variables_order = "GPCS"

line to

variables_order = "EGPCS".

After that, you would get the environment variables which you set before using $_ENV['varname'].

From php.ini about variables_order :

Abbreviations for the following respective super globals: GET, POST, COOKIE,
ENV and SERVER. There is a performance penalty paid for the registration of
these arrays and because ENV is not as commonly used as the others, ENV is
is not recommended on productions servers. You can still get access to
the environment variables through getenv() should you need to.

So you can try to use getenv() instead of $_ENV[].

edigu
  • 9,878
  • 5
  • 57
  • 80
  • 2
    I'm aware of two different php.ini files on Ubuntu. And they both have variable order set to 'GPCS'. Adding 'E' wont help me here... as I'm not having problem with system (ubuntu) env vars not being in $_ENV, but not being loaded into PHP at all, meaning non of the superglobals list them, nor $GLOBALS, nor $_SERVER, nor $_ENV. To be 100% sure, I'll add 'E' and check. – rock3t Nov 26 '12 at 17:11
  • As expected: /etc/environment variables are not loaded into PHP globals while using SAPI as apache2handler. – rock3t Nov 26 '12 at 17:26
  • I have used `php -i` to inspect which `php.ini` file it loads. Changing `variables_order` there doesn't work. `php -i` still reports `GPCS`. – mzedeler Feb 19 '13 at 14:03
  • Mike, try to set your env variables in /etc/apache2/envvars instead of /etc/environment – edigu Mar 10 '13 at 12:23
1

Recently i wrote a library to get values from environment variables and parse to the PHP data types. This library can be used to parse environment variables to PHP data types (like the casting to integer, float, null, boolean), parse the complex data structures like a JSON string and more with the contribution of the commnunity.

The library is available here: https://github.com/jpcercal/environment

Put your environment variables into "/etc/environment" and "/etc/apache2/envvars", after restart your Apache Server and load your environment variables to operational system:

# source /etc/environment
# source /etc/apache2/envvars

And to get the values from environment variable (independently of the environment CLI, Apache, Nginx, PHP Built-in Server and more) to do it:

<?php
// ...
require "vendor/autoload.php";
// ...
var_dump(Cekurte\Environment\Environment::get("YOUR_ENV_VARIABLE_NAME"));

Enjoy it.

João Paulo Cercal
  • 733
  • 1
  • 8
  • 12
-6

i think you can only use to set an environment variable from .htaccess:

SetEnv greet hello

PHP:

print $_SERVER["greet"];
slier
  • 6,511
  • 6
  • 36
  • 55
DolDurma
  • 15,753
  • 51
  • 198
  • 377