Setting environment variables with the built-in PHP web server - php

PHP 5.4 supports a built-in web server for development purposes. The app we are developing is configured via environment variables.
With Apache you'd do this:
SetEnv FAVORITE_COLOR white
With the normal CLI you can do this:
$ export FAVORITE_COLOR=black
$ php -a
php > echo $_SERVER['FAVORITE_COLOR'];
Is there a way to set these variables for the built-in web server?

Looks like E is excluded from variable_order setting running the built-in server. If you add the E to the variable_order setting, it works:
test.php
<?php
var_dump($_ENV['FOO']);
shell:
FOO=BAR php -d variables_order=EGPCS -S localhost:9090 /tmp/test.php
output:
string 'BAR' (length=3)
Tested on PHP 5.4.12

I use Window DOS to start the PHP server. I store my server startup commands in a text batch file (.bat) to save me from having to select and copy all of the commands at once and paste it into the DOS terminal (note the last blank line that I copy as well so the PHP server will automatically start when I paste the commands into DOS, otherwise I would need to manually use the Enter key to start the server).
Q:
cd Q:\GitLabRepos\myapps\test1
set APPLICATION_TITLE=My testing application with this first env variable
set SOME_OTHER_ENV_VAR2={"myJsonElement":"some value"}
E:\PHP8\php.exe -d variables_order=E -S localhost:8000 -c php.ini
The commands above explained:
The first line Q: changes to the drive where my code resides. The second line cd Q:\GitLabRepos\myapps\test1 changes directories to my root PHP application code (which is where I want to start the PHP server). Next I set some environment variables on lines 3 and 4. Then finally I start the PHP server with the -d variables_order=E parameter so I can use either $_ENV or getenv() to retrieve the environment variable values in my PHP code (eg. $_ENV['APPLICATION_TITLE'] or getenv('APPLICATION_TITLE')). If you exclude -d variables_order=E from the server startup command then you can only use getenv() to access the environment variables. I use the -c php.ini parameter to load additional PHP settings from a php.ini file but this can be excluded for simple server setup.
Then if I have a Q:\GitLabRepos\myapps\test1\index.php script with the following code:
<?php
echo getenv('APPLICATION_TITLE').'---'.$_ENV['APPLICATION_TITLE'].'...'.getenv('SOME_OTHER_ENV_VAR2');
?>
If I visit localhost:8000 in a web browser I should see
My testing application with this first env variable---My testing application with this first env variable...{"myJsonElement":"some value"}.

On Windows:
SET FOO=BAR
php -s localhost:9090

Related

getenv return null from terminal while running php script

I defined in httpd.conf(Apache) setEnv=prod
and call to ENV in php (using getenv() function)
while running from terminal(mac) php file.php the env is NULL
but when I run it from the web page its working; and print "prod"
There are several ways to set the environment of a program you run in the console (Terminal) in macOS and Linux. (The procedures are similar on Windows but the syntax is different.)
You can put env=prod in front of the command line to set the environment variable env with value prod only for the current execution of that command line:
$ env=prod php -f script.php
You can use export env=prod as a separate command line. It sets the environment value env with value prod for the current execution of the shell you are running in the console. The export keyword in front of it tells the shell to pass the variable to all processes it launches from now on (until you close the shell or unset the variable):
$ export env=prod
$ php -f script.php
If you want to set the variable permanently then you put the line export env=prod in ~/.profile or ~/.bashrc or the initialization script of your preferred shell (if it's not bash). All subsequent instances of the shell you launch execute the initialization script and set the env variable with value prod in their environment and mark it as exportable to the child processes that shell launches.

Environment variables readable by Apache/PHP and Systemd/node

On the same server, I have a apache php application and a nodejs application (started via systemd).
For systemd/node, I put the following config:
[Service]
EnvironmentFile=/etc/environment
For apache, I have put the following line in /etc/apache2/envvars
. /etc/environment
My problem is:
It works in PHP and standalone node if I put export before each variable, but not in node via systemd
It works in node via systemd if I remove the export
Is there a way for me to write these variables in a single place that can be used by Apache/PHP and node started via systemd ?
You can use the export statement version of your environent file if you change your ExecStart= line to something like: ExecStart=/bin/sh -c ". /etc/environment && exec /PATH/TO/NODEJS/APPLICATION". This is kludgy though.

How to add a linux environment variable for different language (PHP or RUBY)

I would like to add a linux environment variable for my differents applications written in PHP and Ruby.
Its goal is to differntiate between 'production' and 'development' linux environment.
How to have an linux environment variable (ex : APPLICATION_ENV='production') that can be accessed with PHP and Ruby?
thanks
Edit 1 :
My first solution was :
for Apache/PHP in vhost :
SetEnv APPLICATION_ENV 'production'
for Ruby :
export APPLICATION_ENV='production'
puts ENV['APPLICATION_ENV']
However, this is two places to the same value... There are no solution to merge it in one place ? par exemple to use /etc/environment
Edit :
The answer of my question is detailed here : Inserting Variable Headers in Apache
A simple solution to have a central location for your variable would be to put it in /etc/environment and include it in /etc/init.d/httpd.
$ vim /etc/environment
APPLICATION_ENV=production
$ vim /etc/init.d/httpd
if [ -f /etc/environment ]; then
. /etc/environment
fi
Then restart apache with /etc/init.d/httpd restart and it should be OK.
If you are using ubuntu 16.04 or similar, replace /etc/init.d/httpd with /etc/init.d/apache2
If you don't want to include environment file to apache, you can directly put your code in /etc/apache2/envvars for example at the end of the file:
export HELLO='dear'
For the commandline, do a
export APPLICATION_ENV='production'
prior to calling your code, like Domon suggested. You can write a short wrapper bash script to do all of that in one line, like this
#!/bin/bash
export APPLICATION_ENV='production'
ruby /path/to/your/script.rb
For apache, make sure mod_env is loaded, and include the line
SetEnv APPLICATION_ENV production
in the site's vhost config or .htaccess.
Finally, you can set the APPLICATION_ENV globally on your system (using whatever your distri supports for that) and then simply pass the value to your web app by using
PassEnv APPLICATION_ENV
The most simple way is specifying environment variables directly in shell commands. Then you can access them through the ENV object in Ruby.
For example, create a file called env.rb:
puts ENV['APPLICATION_ENV']
And run it in the shell like this:
APPLICATION_ENV='production' ruby env.rb
It should print out the word "production".
Or, use the export command:
export APPLICATION_ENV='production'
ruby env.rb
You might want to add the export line to some config file. For example, if you use bash, add it to ~/.bashrc and it will get executed every time when you starts a new shell.

how to test php file from command line using spawn-fcgi

I have a php script. I am using nginx and spawn-fcgi.
spawn-fcgi -n -s /tmp/nginx9010.socket -u www-data -g www-data -f /usr/bin/php5-cgi -C 6
How can I test from the command line that spawn-fcgi is working with the script?
e.g. I have a script in /home/ubuntu/test.php
I am having issues with nginx and executing a php script. It prompts for a download.
I have #!/usr/bin/php in the file and did a chmod a+x as well.
Thanks
For testing a FastCGI backend you could try to create a CGI environment and use cgi-fcgi to connect to the backend
You could attach with strace to see what the backend does (for example whether it even receives a request from the web server); attach with -ff to the master process to see syscalls on all workers
php5-cgi in FastCGI mode doesn't need a shebang line nor +x on the files - it doesn't use the kernel to execute them, it just loads them as simple files
Firefox (and probably other browsers too) often cache the mime type, so you will see a download prompt even after you fixed the problem. Use curl for testing!
nginx won't serve the file it passes it to php, nginx only serves static files, So if it is downloading the php file you might need to check that your are sending php files to the correct place, are you using an IP and PORT in the php location block in the config file ?
Only a guess of the top of my head whilst on the train home.
FWIW, problems like that nginx offers the file to be downloaded are due Nginx serving the files itself without sending them to fastcgi backend, often because of try_files or wrong location {} block matching to the uri.

Windows pgpass.conf file does not work with PHP's shell_exec()

I have a windows/apache/php/postgres installed (php 5.3 and Postgres 9)
I'm trying to execute a "psql" command line from PHP, so for this I need psql doesn't ask for the password.
I already have a pgpass.conf file in the %appdata%/postgresql path
If I execute the line from the windows command line
"C:\Program Files\BitNami WAPPStack\postgresql\bin\psql.exe" -U postgres -w -d [DB] < "[SQL FILE]"
it works fine, but when is done through PHP with shell_exec() it does not work, apache error log says "psql: fe_sendauth: no password supplied"
So, I don't know why it works from command line but not from PHP's shell_exec()
Regards!
%appdata% is probably not the same between apache's execution environment and the windows command line you're testing against. Generally on Windows, apache is expected to run as a service under the LocalSystem account (see Using Apache HTTP Server on Microsoft Windows)
But you could store a pgpass.conf file at a different place pointed to by the PGPASSFILE environment variable in apache (a SetEnv declaration in apache configuration file should do, or in the php code).
Or avoid the password file altogether and set the PGPASSWORD environment variable directly to the value of the password just before executing psql.

Categories