Different $_SERVER output when running from command line or system() - php

If have these very simple scripts:
foo.php:
<?php
system("php -c /etc/php7/cli/php.ini /some-path/exec.php");
?>
exec.php:
<?php
print_r($_SERVER);
?>
Running exec.php from command line I get the expected output for $_SERVER:
...
[LESSKEY] => /etc/lesskey.bin
[NNTPSERVER] => news
[MANPATH] => /usr/share/man:/usr/local/man:/usr/local/share/man
[XDG_SESSION_ID] => 2
[HOSTNAME] => AAEB-DEV203LD
[XKEYSYMDB] => /usr/X11R6/lib/X11/XKeysymDB
[HOST] => AAEB-DEV203LD
[TERM] => linux
[SHELL] => /bin/bash
...
When exec.php is executed by the system function in the foo.php script called in a browser tab then the output for $_SERVER is totally different and it looks more or less exactly like the Environment section from phpinfo():
...
[APACHE_CONF_INCLUDE_FILES] =>
[mpm_found] => true
[APACHE_CONF_INCLUDE_DIRS] =>
[SYSCONFIG_FILE] => /etc/sysconfig/apache2
[APACHE_START_TIMEOUT] => 2
[HTTPD_MODULE_IDS] => actions_module alias_module ...
[APACHE_SERVERNAME] =>
...
What is the problem:
In the $_SERVER output - running via system() function - there is missing lot of information which we need.
I didn't find anything in the Internet which can give me a hint why the output differs so much.
OS: SLES 12.3
PHP: 7.2.10
Apache: 2.4 MPM
My question:
Why does the output differ so much when running under command line and system() within the Apache session and can I get the same output for the system() function when calling exec.php from the command line with php -c /etc/php7/cli/php.ini /some-path/exec.php?

Good. I could sort it out how it works, it wasn't clear to me.
Running php from command line PHP sets into $_SERVER all exported environment variables. Therefore $_SERVER has the entry HOSTNAME.
Running exec() from a script which is executed in a browser tab PHP sets $_SERVER with the content of Environment section as displayed by phpinfo().
When I want to have set the entry HOSTNAME in $_SERVER I have to call putenv("HOSTNAME=value"); before exec().

Related

Why I cannot run a shell command using PHP 7?

I'm having trouble running a python script using shell_exec or exec using PHP 7 (PHP Version 7.0.33-0+deb9u3).
If I run: var_dump(shell_exec("/usr/bin/python3 /home/pi/Documents/GTranslate/translator.py")); or var_dump(shell_exec("/home/pi/Documents/GTranslate/translator.py"));,
I obtain back NULL.
No problems with user permissions
I've checked the permission running:
$scriptPath = "/home/pi/Documents/GTranslate/translator.py";
var_dump(array(
'file' => is_file($scriptPath),
'readable' => is_readable($scriptPath),
'executable' => is_executable($scriptPath)
));
I've obtained everything true.
Missing safe_mode from php.ini
In my php.ini (the one shown by phpinfo();) there is no fields like safe_mode. Reading the PHP Wiki since PHP 5.4.0 the function has been removed.
shell_exec() is working
The funcion shell_exec() is not disabled because if I run the command:
echo shell_exec("ls -halt /home/pi/Documents/GTranslate/translator.py");
I obtain back:
-r-xr-x--x 1 pi pi 1.7K Aug 11 12:13 /home/pi/Documents/GTranslate/translator.py
Where is the problem?

How to get php readline() to default to Vim mode?

This is on CentOS 7.2, PHP version 5.6.20. According to readline_info():
<?php
print_r(readline_info());
gives
Array
(
[line_buffer] =>
[point] => 0
[end] => 0
[library_version] => EditLine wrapper
[readline_name] =>
[attempted_completion_over] => 0
)
OK, so readline() is using EditLine. I created a ~/.editrc file with:
bind -v
The permission is 664. I then tried:
<?php
$line = readline('Enter: ');
But it doesn't seem to read the file, and it's not in Vim mode. Doing an Alt-X followed by a manual command of "bind -v" puts it in Vim mode, so I know it has Vim mode.
I read somewhere else that I might need to manually set the path in an environment variable. So tried setting the full path:
$ export EDITRC=/home/work/.editrc
Still nothing. I've also seen that "export EL_EDITOR=vi" is supposed to work, but still doesn't work.
Does anyone have any way to make this work? I really need Vim mode to work.

Cant access environment variables in php

Im having issues accessing OS environment variables in php
I have apache/php installed on a centos 6.3 image
in httpd.conf mod mod_env.so is loaded
in php.ini I have set variables_order = "EGPCS"
restarted httpd (many times)
in shell if I type "env" I get
DB_PORT_28017_TCP_PROTO=tcp
HOSTNAME=c6188a8bd77f
DB_NAME=/rockmongo/db
DB_PORT_27017_TCP=tcp://172.17.0.36:27017
TERM=xterm
DB_PORT_28017_TCP_PORT=28017
DB_PORT=tcp://172.17.0.36:27017
DB_PORT_27017_TCP_PORT=27017
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/etc/php.d
DB_PORT_27017_TCP_PROTO=tcp
DB_PORT_28017_TCP_ADDR=172.17.0.36
DB_PORT_28017_TCP=tcp://172.17.0.36:28017
SHLVL=1
HOME=/
DB_PORT_27017_TCP_ADDR=172.17.0.36
container=lxc
_=/usr/bin/env
OLDPWD=/etc
which has the variables im after, however if I execute print_r($_ENV); in php I get
Array ( [TERM] => xterm [PATH] => /sbin:/usr/sbin:/bin:/usr/bin [PWD] => / [LANG] => C [SHLVL] => 2 [_] => /usr/sbin/httpd )
have also looked in $_SERVER & $GLOBALS.
Interestingly if I execute php -i in shell I see the env variables set correctly in _ENV
I should note im running this in a docker container, however I dont believe it is a issue as variables display correctly in #env & #php -i. I think I have a issue with my httpd/php config
Anyone have advice for this?
thanks
I ended up having a few options
if docker container needs to run multiple services, setting env vars to /etc/environment will make them available for all users. I added the following line to my Dockerfile CMD
CMD ["env | grep _ >> /etc/environment"]
if docker container runs a single service, its best to set the entry point to the desired application, env vars will automatically be passed to application user. this is my Dockerfile CDM & ENTRYPOINT to run apache
ENTRYPOINT ["/usr/sbin/httpd"]
CMD ["-D", "FOREGROUND"]
Dagon is correct.
Unless you logged in as your web server User (apache?) you may not see the same environment variables. You can see them easily with a phpinfo test file though:
<?php
phpinfo();
?>
Or you can set your own with a .htaccess file:
SetEnv HTTP_MY_VARIABLE "my value";
From dwitz: You can also make the environment variables available system wide with this:
env | grep _ >> /etc/environment
Sorry can't comment yet... So had to create an answer.
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
As you say, the environment are already loaded. Then, 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.

How to populate SCRIPT_FILENAME and SCRIPT_PATH server vairables to php-cgi from the command line

I'm trying to run cron php script from command line. The server does not have PHP CLI but php-cgi exists. I tried to pass PHP directly to php-cgi but this does not work because two server environment variables are missed ($_SERVER['SCRIPT_FILENAME'] and $_SERVER['SCRIPT_PATH']). I tried to fill variables using following recommendation but these variables are not populated. What is missed in this answer? How to make php-cgi populate these server values? The question is not platform specific, but execution script looks like this currently
#!/bin/bash
export REDIRECT_STATUS=200
export GATEWAY_INTERFACE="CGI/1.1"
export SCRIPT_FILENAME=/usr/local/www/owncloud/cron.php
export REQUEST_METHOD="GET"
/usr/local/bin/php-cgi
Please note that I'm not asking for workaround, I already added helper php file which fill necessary values. But this is temporary solution because next software update could show another issue with php-cgi call
UPDATE
It seems the issue is not with php-cgi execution but with the SCRIPT_FILENAME and SCRIPT_PATH server variables only. So solution works in common cases when you do not need them. Also the issue might be version specific (it works with PHP version prior to 5.5) or platform specific
I searched SO with question to these specific server variables and found following statement here:
You are just juggling variables now. SCRIPT_FILENAME is a part of the
CGI spec. It will not be available if PATH_INFO is unavailable. As for
REQUEST_URI, it's apache's mod_rewrite specific. – LiraNuna
So exporting PATH_INFO variable also populates values from SCRIPT_FILENAME and SCRIPT_PATH environment variables. Please note that SCRIPT_FILENAME is needed still to point php-cgi to php input file. Below is the final script
#!/bin/bash
export REDIRECT_STATUS=200
export GATEWAY_INTERFACE="CGI/1.1"
export REQUEST_METHOD="GET"
export SCRIPT_FILENAME=/usr/local/www/owncloud/cron.php
export SCRIPT_PATH=cron.php
export PATH_INFO=$SCRIPT_FILENAME
/usr/local/bin/php-cgi
Here is what i tested. i used root account on my home PC. My IP is masked from the output. cannot post this much as comment so posting as answer.
The script
#!/bin/bash
export REDIRECT_STATUS=200
export GATEWAY_INTERFACE="CGI/1.1"
export SCRIPT_FILENAME=/root/t.php
export REQUEST_METHOD="GET"
/usr/bin/php-cgi
PHP file
<?php
print_r($_SERVER);
?>
Output I get
X-Powered-By: PHP/5.3.8
Content-type: text/html
Array
(
[HOSTNAME] => HomePC
[SELINUX_ROLE_REQUESTED] =>
[SHELL] => /bin/bash
[TERM] => xterm
[HISTSIZE] => 1000
[SSH_CLIENT] => xx.xx.xx.xx 58196 22
[SELINUX_USE_CURRENT_RANGE] =>
[SSH_TTY] => /dev/pts/3
[USER] => root
[LS_COLORS] => rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.tbz=01;31:*.tbz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
[SCRIPT_FILENAME] => /root/t.php
[PATH] => /usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
[MAIL] => /var/spool/mail/root
[PWD] => /root
[LANG] => en_US.UTF-8
[REDIRECT_STATUS] => 200
[SELINUX_LEVEL_REQUESTED] =>
[HISTCONTROL] => ignoredups
[HOME] => /root
[SHLVL] => 2
[LOGNAME] => root
[SSH_CONNECTION] => xxx.xxx.xx.xxx 58196 192.168.1.2 22
[GATEWAY_INTERFACE] => CGI/1.1
[LESSOPEN] => ||/usr/bin/lesspipe.sh %s
[REQUEST_METHOD] => GET
[G_BROKEN_FILENAMES] => 1
[_] => /usr/bin/php-cgi
[PHP_SELF] =>
[REQUEST_TIME] => 1379952948
)

php custom C++ module works from command line, not on webserver

I made a custom PHP module with C++ and Swig. It works from the command line, but not with my webserver:
php index.php
php-cgi index.php
Both of those work fine.
I'm using lighttpd and php. I didn't configure these in any special way. I just installed them using sudo apt-get install.
Unfortunately if I make a webpage I get this:
Fatal error: Call to undefined function minikey_to_wif() in /var/www/index.php on line 6
Calling function_exists("minikey_to_wif") returns False too.
The phpinfo() does not show my module called minikey, and shows the same configuration path as the file I edited (/etc/php5/cgi/php.ini):
extension=/path/to/php-ext/minikey/minikey.so
I also tried copying it to where the other PHP extensions seem to be installed (/usr/lib/php5/20090626+lfs/) but that didn't work either.
I've been stopping, and starting lighttpd countless times. Each time, when I run ps aux | grep php, there are no results. I've also rebooted a few times to no effect. I have no idea what's up.
OK found the answer.
The extension relied on a library which was installed in a non-standard location. Normally I set LD_LIBRARY_PATH in ~/.bashrc. But when the web server ran the extension, it didn't have that environment variable.
Fix was to create a file in /etc/ld.so.conf.d/genjix.conf with /home/genjix/usr/lib and run ldconfig as root.
Try running phpinfo() using lighty. Make sure that its pointing to the correct php.ini.
If you think this is the problem you can launch php using the -c switch from inside lighttpd.conf with "bin-path" => "/path/to/php-cgi -c /path/to/php.ini":
e.g.
fastcgi.server = (
".php" => (
(
"bin-path" => "/path/to/php-cgi -c /path/to/php.ini",
"socket" => "/tmp/php.socket",
"max-procs" => 4,
"idle-timeout" => 30,
"bin-environment" => (
"PHP_FCGI_CHILDREN" => "4",
"PHP_FCGI_MAX_REQUESTS" => "1000"
)
)
)
)

Categories