Skip to content

Instantly share code, notes, and snippets.

@RavuAlHemio
Last active May 7, 2025 18:44
Show Gist options
  • Save RavuAlHemio/b129a9cccceb974bc7318c8bd32c995c to your computer and use it in GitHub Desktop.
Save RavuAlHemio/b129a9cccceb974bc7318c8bd32c995c to your computer and use it in GitHub Desktop.

Passing variables to PHP

Sometimes, we wish to pass the values of specific variables to PHP, e.g. if we have multiple instances of the same application which should obtain its configuration from different files.

This is an attempt to find a method that is independent of web server and SAPI.

The PHP file in question is:

<?php
echo $_SERVER["TESTAGE"];

The name of the variable used should:

  • not begin with HTTP_ (as it will get overriden by request headers)
  • be uppercase (to ensure lighttpd compatibility)

Apache2 and mod_php

Variables can be fed into $_SERVER using the SetEnv configuration directive, which can be specified per URL:

# PHP enablement
LoadModule php_module modules/libphp.so
<FilesMatch \.php$>
  SetHandler application/x-httpd-php
</FilesMatch>
DirectoryIndex index.html index.php

# pass different variables to the same script
Alias "/one" "/srv/sharedphp"
Alias "/two" "/srv/sharedphp"
<Location /one>
  SetEnv TESTAGE TestageOne
  Require all granted
</Location>
<Location /two>
  SetEnv TESTAGE TestageTwo
  Require all granted
</Location>

Note that names of request HTTP headers are translated according to CGI rules, i.e. uppercased, prefixed with HTTP_ and with hyphens replaced by underscores. It is therefore preferable that your variables do not start with HTTP_.

Apache2 and php-fcgi

Same rules and same caveats apply as for mod_php:

# PHP enablement
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
<FilesMatch \.php$>
  SetHandler "proxy:unix:/run/php-fpm/php-fpm.sock|fcgi://localhost/"
</FilesMatch>
DirectoryIndex index.html index.php

# pass different variables to the same script
Alias "/one" "/srv/sharedphp"
Alias "/two" "/srv/sharedphp"
<Location /one>
  SetEnv TESTAGE TestageOne
  Require all granted
</Location>
<Location /two>
  SetEnv TESTAGE TestageTwo
  Require all granted
</Location>

lighttpd and php-fpm

Again, we can pass environment variables which end up in $_SERVER.

Warning: lighttpd capitalizes variables in setenv.add-environment. This means that PHP sees a variable TESTAGE even if we specify a variable testage.

# PHP enablement
server.modules += ( "mod_fastcgi" )
fastcgi.server = ( ".php" => (( "socket" => "/run/php-fpm/php-fpm.sock")) )

server.modules += ( "mod_alias" )
alias.url = (
  "/one" => "/srv/sharedphp",
  "/two" => "/srv/sharedphp",
)

server.modules += ( "mod_setenv" )
$HTTP["url"] = "^/one/" {
  setenv.add-environment = ( "testage" => "TestageOne" )
}
$HTTP["url"] = "^/two/" {
  setenv.add-environment = ( "testage" => "TestageTwo" )
}

nginx and php-fpm

This time around, it's the FastCGI parameters end up in $_SERVER.

(There might be a more elegant way to do this...)

user http;
events {
}
http {
  server {
    listen 80;
    server_name localhost;
    index index.php index.html;
    location / {
      root /srv/http;
    }
    location /one {
      try_files $uri /one/index.php$is_args$args;
    }
    location /two {
      try_files $uri /two/index.php$is_args$args;
    }
    location ~ ^/one/.+\.php$ {
      fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
      fastcgi_split_path_info ^/one/(.+?\.php)(/.*)?$;
      fastcgi_index index.php;
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME /srv/sharedphp/$fastcgi_script_name;
      fastcgi_param SCRIPT_NAME $fastcgi_script_name;
      fastcgi_param testage TestageOne;
    }
    location ~ ^/two/.+\.php$ {
      fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
      fastcgi_split_path_info ^/two/(.+?\.php)(/.*)?$;
      fastcgi_index index.php;
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME /srv/sharedphp/$fastcgi_script_name;
      fastcgi_param SCRIPT_NAME $fastcgi_script_name;
      fastcgi_param testage TestageTwo;
    }
  }
}

Caddy and php-fpm

The env directive of php_fastcgi passes key-value pairs into PHP's _SERVER superglobal.

http:// {
  root * /srv/http
  
  root /one/* /srv/sharedphp
  root /two/* /srv/sharedphp
  php_fastcgi /one/* unix//run/php-fpm/php-fpm.sock {
    index index.php
    env TESTAGE TestageOne
  }
  php_fastcgi /two/* unix//run/php-fpm/php-fpm.sock {
    index index.php
    env TESTAGE TestageTwo
  }
}

In more advanced configurations, the env directive can be placed under reverse_proxy -> transport fastcgi.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment