PHP CLI environment detection - php

I have a Linux server with a bunch of different websites on it. When I program websites, I will develop them locally and set APPLICATION_ENV to development. On my server, I have a staging subdomain setup which I set APPLICATION_ENV to staging. Lastly, if I end up hosting the production website, I can set APPLICATION_ENV to production. All of this works fine, but lately I have been running CLI tasks after every deployment. My command line scripts obviously can't do anything with the APPLICATION_ENV variable I have set up through Apache. I know that you can export a variable like so:
export APPLICATION_ENV="staging"
However, this would be setting it on my whole server, when I really only want to set it on the staging subdomain. Is there a way to contain these variables to a subdomain on my server?

For title of your question:
if (PHP_SAPI == 'cli') {
echo 'This is CLI mode!' . PHP_EOL;
var_dump($argv);
}
For description:
I think you can set APPLICATION_ENV value with args or set it (in source code) as internal CLI APP ENV mode.

There is nothing wrong to have environmental variables server wide, since you can set them for a specific user (or even session) only.
Anyway, probably the easiest way would be to pass the "env" as a parameter, e.g.: cli.php --env=staging
Look how they solved it in Laravel: https://laravel.com/docs/4.2/artisan
Specifying The Configuration Environment
You may specify the configuration environment that should be used
while running a command using the --env switch:
php artisan migrate --env=local
Symfony: http://symfony.com/doc/current/cookbook/console/usage.html
$ php bin/console cache:clear --env=prod

Related

Symfony command php bin/console can't read Apache SetEnv?

With Symfony 5.2, when I execute this command
APP_ENV=prod php bin/console d:m:m
I have this message :
WARNING! You are about to execute a migration in database "db_name" that could ...
However, in my Apache environment variables, I customized the database name :
SetEnv DATABASE_URL "mysql://website:password#localhost:3306/website_prod"
I am sure that this configuration works (when I access the site, I am in the prod environment while I left dev in the .env generated by Symfony).
Why is the wrong database displayed on the APP_ENV=prod php bin/console d:m:m command line? I think Apache variables are not taken into account in php bin / console ... command line and I need to create a specific .env.prod.local.
Can you confirme ? If yes, I don't see why Symfony mentions this in their documentation (https://symfony.com/doc/current/setup/web_server_configuration.html#apache-with-mod-php-php-cgi)
Console commands do not run under the web-server, hence they do not have access to whatever configuration you have for the Apache vhost or anything like that.
The best way to deal with this kind of configuration is storing this values in environment variable, .env files, or use Symfony's secret management features.
This way this configuration will be available both to the application when accessed via the webserver or through a command line script.

Laravel Artisan - Cli doesnt reads environment variables

I had made a custom artisan command. In homestead everything goes right, but when I execute the command on server it cant read environment variables. When I ssh the server and try php artisan external:import the connection timeouts cause of null env vars.
On artisan tinker env() function returns null.
How can I read env vars on server?
IMPORTANT: This server is part of AWS, so it does not have .env file.
did you clear config cache already?
php artisan config:clear
i think env function did not work after you cached the config
I know it's a bit late to answer this question, however, I'll share my experience in case it can help someone.
The environment variables will be available depending on how they have been configured. The different ways to configure these variables are:
Setting them for the current user ~/.bash_profile, ~/.bash_login or ~/.profile
Setting them globally with the /etc/profile file or with a file in the /etc/profile.d/ directory
Establishing them at the web server software level. For example, in the httpd.conf file with SetEnv, in apache.
If you have set environment variables through server software, they will be available only to scripts that handle http requests. This leaves out the artisan commands.
My recommendation is that you add a step to your deployment process to set environment variables globally by creating a new file in /etc/profile.d/. For example, /etc/profile.d/webapp.sh. So webapp.sh would have lines like
MY_VAR=my-value
I hope this helps you.

REDIRECT_ prefix in environment variables (not mod_rewrite related)

We are trying to set up multiple PHP versions running in parallel in our staging environment. To achieve this, I built all relevant PHP binaries (w/ --enable-fastcgi where applicable) and am using mod_fastcgi to invoke the former via wrapper scripts.
If at all relevant, here's /php-fcgi/php-5.5:
#!/bin/sh
PHPRC=/usr/local/php55/etc/php.ini
export PHPRC
PHP_FCGI_MAX_REQUESTS=5000
export PHP_FCGI_MAX_REQUESTS
PHP_FCGI_CHILDREN=3
export PHP_FCGI_CHILDREN
exec /usr/local/php55/bin/php-cgi
This is all working fine so far (i.e. all virtual hosts configured to run w/ PHP 5.5 are running on 5.5, etc.); there is however a problem with environment variables set with "SetEnv" in the <Directory> block. All of those are prefixed with REDIRECT_.
Example for this:
SetEnv APPLICATION_ENV "production"
Will result in this output:
'REDIRECT_APPLICATION_ENV' => string 'production'
Can anyone advice on what I have done wrong?
Clarification on why this is not mod_rewrite related: This behaviour also occurs even when entirely disabling mod_rewrite.

How could I simulate an offline directory with Heroku?

I used to have an offline directory on my server with Perl scripts to dynamically create files.
Say this directory was in an offline directory for security reasons (/server/back/scripts) I used to access it with exec(/server/back/scripts/auto.pl $arguments)
Contents of auto.pl:
system('cp /server/back/includes/default /server/front/ann/'.$enc.'.php');
system('chmod 555 /server/front/ann/'.$enc.'.php');
system("perl -pi -e 's/string/".$key."/g' /server/front/ann/".$enc.".php");
This script copy-paste a default file with garbage values to a public directory, and replace garbage values with something else while setting up the rights we want.
how can I reproduce this on Heroku? - if not possible is there any way to at least reproduce the behavior of this script?
It looks like the goal of this script was to inject keys/credentials into your PHP application by searching/replacing.
Heroku encourages configuration via environment variables, especially keys/credentials.
You should add your keys via the Heroku command line tool:
heroku config:set MY_API_KEY=super-secret-hex-goes-here
... and then pull in the values from the environment on your dyno in your PHP code:
$api_key = getenv('MY_API_KEY');
This will allow you to provision keys/secrets for each running application on Heroku without having to store anything in source code.
Heroku does not expose the File system of the current web dyno. So you can't make any changes to the files to have an impact on the running server.
Files can be changed if you have the file in the code base itself. So, you could commit the change and deploy on Heroku.
If these variables, that you are talking about have to be used system wide then the best way is to use Environment variables as mentioned in Winfield's answer.
You can set and unset Environment variables using command :
heroku config:set VAR_NAME=value [VAR_NAME_2=value.........]
heroku config:unset VAR_NAME [VAR_NAME2.......]
If you need to maintain a file with current values of Environment variables , then you can use this command :
heroku config:pull --overwrite
This will get all the Environment variables currently set on server and store them in .env file.
Then you can update the values in .env file locally itself and update the same on server by command:
heroku config:push
This will replace all current values on server with the values in the .env file
Read more about environmet variables here : https://devcenter.heroku.com/articles/config-vars

How to set global environment variables for PHP

I have read the question/answers here but I don't understand how to set variables in /etc/environment. If I edit the file, do I need to restart my machine or simply log out my current user (or log in a new one?).
I want to set a global variable to denote that websites on my machine are in 'development' or 'testing' mode. I don't want to have to set this for every project (whether it uses PHP, Java/Tomcat, NodeJS, etc). I'm aware that (for Apache) I can set the environment variable in the following ways:
directly from php with putenv() (this seems useless since I want to avoid logic that tries to figure out what server the files are on)
using .htaccess SetEnv ENVIRONMENT 'local' (this would require me to duplicate this file/code for every server, not ideal)
using a Virtual Host directive SetEnv ENVIRONMENT 'local' (if I'm using a virtual host, which in nearly all cases I am, but again requires me to copy/paste code over and over again)
in httpd-conf SetEnv ENVIRONMENT 'local' (this will only apply to apache, and I would like it to apply to NodeJS servers as well)
I'm not saying I can't do #4 (and apply #3 selectively to NodeJS servers). But I'm thinking that this is a good reason to use /etc/environment. As I said above, I have edited the file (after first creating it) and tried the following combinations, none of which seemed to work:
ENVIRONMENT='local'
ENVIRONMENT=local
export ENVIRONMENT='local'
export ENVIRONMENT=local
I say that none of them worked because I did not find the variable in output from:
print_r($_SERVER);
print_r($_ENV);
echo(getenv('ENVIRONMENT'));
What you want to do is use an Apache configuration file. You will need access to a configuration folder and the httpd.conf file (or modified version). You can then configure the httpd.conf to dynamically load configuration files using this approach
Include conf.d/*.conf
Inside the conf.d folder you place your specific environment configuration files.
server-environment-dev.conf example:
SetEnv ENVIRONMENT "local"
server-environment-prod.conf example:
SetEnv ENVIRONMENT "production"
These settings will show up in your php code as available environment variables. This approach allows you to keep your vhost files, .htaccess, and your other configuration files agnostic of the environment.
etc/environment, etc/profile.d, .bash_profile, .profile, etc files are not readable by PHP in Apache due to some process/user limitations. You can bash, smash, crash the variables all you want and see them set in your terminal but they will not show up in phpinfo() unless you set it via one of the Apache configuration files.
For NodeJS you can start the app passing in your environment variable or you can set the NODE_ENV in multiple ways include your .bash_profile and possibly etc/environment file if you want to be user agnostic.
A good read for Node:
http://www.hacksparrow.com/running-express-js-in-production-mode.html
So I would assume you have a global config file somewhere. Why not put a constant in that file that you can change? Would be far easier that trying to set something on the server level.
define('ENVIRONMENT', 'testing');
if(ENVIRONMENT == 'testing') {
echo 'We\'re just testing';
}
If you still can't get your environment variables:
you may need to edit your real httpd.conf in
~/Library/Application Support/appsolute/MAMP PRO/
instead of
/Applications/MAMP/conf/apache/
Also you may need to use getenv() instead of $_ENV

Categories