Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get PHP to be able to read system environment variables

I am using PHP as PHP-FPM on Centos. I am trying to follow the http://12factor.net/ guidelines of having the settings be stored in environment variables.

I have created a file in /etc/profile.d that sets the environment variables I want, and the environment variables appear when tested in the CLI via Bash i.e. running the bash script:

echo $SOME_SERVER_SETTING

shows the correct output.

I have set the clear_env setting to false and variables_order to EGPCS, however, the variable I have set does not show up in PHP either getenv('SOME_SERVER_SETTING') or doing var_dump($_ENV)

What other setting needs to be set to allow PHP-FPM to receive all of the server environment variables, and in particular those set through a shell script in /etc/profiles.d on Centos?

like image 246
Danack Avatar asked Jun 13 '15 19:06

Danack


People also ask

Can PHP read environment variable?

There are two ways to read environment variables in PHP. One is getenv() function and another is $_ENV array. The uses of the getenv() function are shown in this tutorial.

What is .ENV file in PHP?

An . env file is a plain text file which contains environment variables definitions which are designed so your PHP application will parse them, bypassing the Apache, NGINX and PHP-FPM. The usage of . env files is popular in many PHP frameworks such as Laravel which has built-in support for parsing .


4 Answers

Security reasons :-)

See /etc/php5/fpm/pool.d/www.conf (debian location, may be different on CentOs)

; Clear environment in FPM workers
; Prevents arbitrary environment variables from reaching FPM worker processes
; by clearing the environment in workers before env vars specified in this
; pool configuration are added.
; Setting to "no" will make all environment variables available to PHP code
; via getenv(), $_ENV and $_SERVER.
; Default Value: yes
;clear_env = no 

; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
; the current environment.
; Default Value: clean env
;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp
like image 78
Noch_ein_Kamel Avatar answered Oct 05 '22 23:10

Noch_ein_Kamel


Tested on Centos 7 with Systemd service and PHP 5.6.4

OPEN

/etc/php.ini

FIND

variables_order = "GPCS"

REPLACE TO

variables_order = "EGPCS"
# http://php.net/manual/en/ini.core.php#ini.variables-order

OPEN

/etc/php-fpm.d/www.conf (maybe /etc/php5/fpm/pool.d/www.conf)
(do not confuse with /etc/php-fpm.conf)

FIND IF EXIST

clear_env = yes

REPLACE TO OR ADD

clear_env = no
# http://php.net/manual/en/install.fpm.configuration.php

OPEN

/etc/environment

ADD

#any variables you need, for example:
MY_VAR=1234

RUN IN SHELL FOR CHECK

source /etc/environment
echo $MY_VAR # 1234

RUN IN SHELL

ln -fs /etc/environment /etc/sysconfig/php-fpm
systemctl daemon-reload && service php-fpm restart

...TESTING

OPEN

index.php # in your project folder, running with php-fpm

ADD

var_dump(getenv('MY_VAR'), $_ENV['MY_VAR']);exit;

RUN IN BROWSER

http://mylink.to.project/index.php   
string(4) "1234"
string(4) "1234"

ENJOY!

like image 32
kivagant Avatar answered Oct 06 '22 00:10

kivagant


Environment variables in a FastCGI setup are set as input by the client of the FPM process, for instance NginX. They are sent as headers to the FastCGI server, which interprets them and sets them accordingly for you to read out with getenv.

If you are in fact using NginX, look for the fastcgi_param directives. You can also set environment variables in your pool config of php5-fpm, depending on your use case.

like image 24
Gerard van Helden Avatar answered Oct 05 '22 22:10

Gerard van Helden


You need to read the environment variables from the correct location. PHP creates a super global variable for this: $_ENV So you can access a single variable by accessing a certain element from that variable, which holds an array: echo $_ENV['SOME_SERVER_SETTING'];

I have no idea why your example above should work on CLI. The super global variable is the documented location and works.

What might be your issue here is that the variables are not set for the http server process. Typically scripts like those in /etc/profile.d are executed at login time. So when a user creates a session inside the system. But that will never happen for an http server started as a system server. No login is performed, no profile script is executed, no environment variables are set.

To solve this you can

  • set the environment variables inside the startup script of the service
  • set the variables inside the host configuration or .htaccess style files
  • auto-prepend a script setting the variables
like image 36
arkascha Avatar answered Oct 05 '22 22:10

arkascha