Laravel Dynamically load different .env file - php

I would like to ask how can I possibly dynamically load different env file setting?
I have read the documentation, I have created two files (.env and .env.uat)
.env for development and .env.uat for client testing environment, and it depends on the url to use different env file, eg: (company-dev) -> .env, (company-uat) -> .env.uat
I have added these two lines of code to bootstrap/app.php, actually it works, but when I want to execute php artisan migrate, then it said that HTTP_HOST couldn't found, so it will load the .env.uat as the fallback file. Can someone tell me where should I modify code please? Thanks!! (Actually I knew I can manually change the .env file in different environment everytime, I am seeking some automatic way to recognise the env file for me.
$envFile = $_SERVER['HTTP_HOST'] == 'xxx-dev-testing.com' ? '.env' : '.env-uat';
$app->loadEnvironmentFrom($envFile);

There's no HTTP_HOST in the command line. You'll need a different approach. Ultimately, though, .env shouldn't be in version control at all. Your UAT environment would just have a .env with different values.

Related

Symfony4: Access DEV environment on production server

In Symfony3, when I want to browse the website in DEV environment on the "live" server, I just enter my ip address in /web/app_dev.php and open http://www.example.com/app_dev.php/ in the browser.
Since in Symfony4, the environment is now set in /.env, how can I see the DEV environment on the production machine?
EDIT: I'm looking for a solution that works in production, so applying any global changes (like e.g. setting APP_ENV=dev in /.env) is not an option.
You can change inside your .env file APP_ENV to dev like this:
APP_ENV=dev
If you set that variable symfony load the system into dev enviroment because inside Kernel.php there is this line that check that variable:
$kernel = new Kernel($_SERVER['APP_ENV'] ?? 'dev', $_SERVER['APP_DEBUG'] ?? false);
If you want to do it without change .env file you can for example set a variable in the Apache vhost or Nginx FastCgi configuration, based on the URL you are visiting from - such as APP_ENV=/home/user/app-name/dev.env or on a live server: APP_ENV=/etc/app-name.prod.env
So in this case you have many .env file but you can use rule based on url
At first this is a bad idea and that's why it wasn't possible by default to access app_dev.php on production server (symfony < 4). You're giving a lot of internal information to public and especially to attackers.
From symfony docs:
After you deploy to production, make sure that you cannot access the app_dev.php or config.php scripts (i.e. http://example.com/app_dev.php and http://example.com/config.php). If you can access these, be sure to remove the DEV section from the above configuration.
You should be able to debug most of the things from logs.
But if you really want to do it, you can just remove public/index.php and create public/app.php and public/app_dev.php like it was in symfony 3 and make it work with env variables. - https://github.com/symfony/symfony-standard/tree/3.4/web
EDIT: To be clear: you can just remove public/index.php, create public/app.php, public/app_dev.php (copies of index.php). And get inspiration from symfony 3 standard edition to adjust it to your needs.
EDIT2: As #Cerad mentioned it's a better idea to have index.php and index_dev.php file names (following Symfony4 decisions).

Laravel: Join two application by one config

My project is two Laravel applications in one folder. Why two separate applications instead of one? I have good reasons. Anyway, for example, every time I want to change the app name in the config (config/app.php) I go and edit the .env file in both directories (of the two applications) and then execute artisan config:cache to update the cached config.
It's not much of a task or anything, but it's a bad design I believe. So, I am looking for a way to take the values shared between these two application out to a separate file. And have these application load this file and override/apply the values inside it to the app configuration.
So, now I have a config.php in the root directory (which holds the other two apps in /app1 and /app2). And inside each app's AppServiceProvider I call the config.php and loop through the values and set each using Config::set(..., ...).
This worked for me well, but of course changing the values loaded in the \Config package doesn't change the values that were fetched from it earlier to this point. For example app()->environment() returns the value set in the config/app.php, not the new value introduced in the global config.php. That's because the App library asked for the env property before I could override it!
So, what I want your help with is: you either tell me about a more smart/standard way to achieve 1 config for 2 apps setup. Or tell me where to put the code that overrides the app config with the new values from my global config.php (currently I put the code in register() in App\Providers\AppServiceProvider)
You can share env settings by removing one of .env files and make a symlink to the other file instead of a common file. In this case if you change a file, both applications get changed values.

How do I use one config key in another?

In Laravel 4's cascading configuration files I was able to reference one configuration key from another. For example, I liked to have app.debug set to true or false, and then I could switch error reporting to Sentry to the opposite of that in a different configuration file, by setting the relevant setting to !Config::get('app.debug').
I knew this was a little hairy because presumably whether the config value can be found depends on the order in which files are loaded. But I managed to get it working each time.
I'm having no such luck in Laravel 5. I get a "class not found" error when I try to do Config::get(...) in a configuration file. Using the config(...) helper instead produces no error but the values aren't retrieved.
The convention, of course, is to use environment variables, the .env file and env(...) to grab the values. That way each configuration key can use the value of the environment variable. That's fine and works, but I have some values which are shared between environments, and I do want some of these values to be committed to version control.
Using the .env.example file isn't a good solution for me since I don't want to have to remember to copy values over to the .env file of each environment if they change.
How can I store some configuration values in a way where they are shared between environments, are present in version control, and can be referenced in multiple configuration files?
This is my solution, which works, but I'm interested in other possibilities.
Add a new shared file, checked in to VCS, called .env.shared. Its structure is just like .env. Edit bootstrap/app.php to load in these variables (in addition to .env):
// Load shared environment variables
$app->afterLoadingEnvironment(function () use ($app) {
Dotenv::load($app->basePath(), '.env.shared');
});
I added this right after $app is instantiated.

Artisan unable to use $_SERVER variables from database config file

I am currently deploying a Laravel project on my shared hosting account. It is an open project and hosted on GitHub as a public repository. As a result I'm using dynamic variables set by an .htaccess file in my database.php configuration file for my production environment. This allows me to also update my deployment using a git pull command on my host which helps speed up work.
The database.php file has something similar to
$database = $_SERVER['DBNAME'];
$database_user = $_SERVER['DBUSER'];
This is much like what is done when deploying to PagodaBox & works perfectly fine for the application with all things functioning as expected in the browser, no complaints.
The problem I have is that artisan is unable to use these variables and will attempt instead to connect to the database using what I believe to empty variables when processing a migrate instruction. I get an error that artisan tried to connect to the databases with no password. I have been calling artisan using --env=production and have tested this but found that it will only work if the database.php file has the variables specified explicitly instead of as environment variables.
Is there a way of causing artisan to "see" these environment variables?
answers that have proved useful to me so far:
http://forums.laravel.io/viewtopic.php?pid=8455
and
Environment driven database settings in Laravel?
Because Artisan is a CLI PHP request - the request never hits the .htaccess file - and therefore your variables are never set.
As a workaround - you could define the variables inside the artisan file itself on line 3 (just after the <?php)
$_SERVER['DBNAME'] = 'test';
$_SERVER['DBUSER'] = 'something';
edit: I just noticed you said this is public hosted on github - so you wont want to include your username/password in the file? Maybe put the artisan file as part of the .gitignore group - so you dont push/pull that single file?
The capability to set up environment variables is built in to Laravel, so there's no reason to do it in .htaccess. Laravel's built-in way works with artisan without any trouble.
See this part of the docs about environment variables you would like to protect.
http://laravel.com/docs/configuration#protecting-sensitive-configuration
Quoting:
... create a .env.local.php file within the root of your project [...] The .env.local.php should return an array of key-value pairs, much like a typical Laravel configuration file:
<?php
return array(
'TEST_STRIPE_KEY' => 'super-secret-sauce',
);
All of the key-value pairs returned by this file will automatically be available via the $_ENV and $_SERVER PHP "superglobals". You may now reference these globals from within your configuration files:
'key' => $_ENV['TEST_STRIPE_KEY']
Be sure to add the .env.local.php file to your .gitignore file. This will allow other developers on your team to create their own local environment configuration, as well as hide your sensitive configuration items from source control.
Add your private environment variables
<?php
return array(
'MY_SECRET_KEY' => 'super-secret-sauce',
);

Loading Config and Setting a Config Value in CodeIgniter

I try to create application with back-end and frond-end. The folder structure as follows(only show config file position to explain problem)
+root
|-admin
|-application
|—backend
|—config
|—config.php
|—frontend
|—config
|—config.php
|-system
Using back-end admin panel I try to change config value in both back-end and frond-end config.php value. But I fail to change it in front-end config.php file. I don’t need database based solution for this.
Reading the documentation I got this:
Note: CodeIgniter always tries to load the configuration files for the current environment first. If the file does not exist, the global config file (i.e., the one in application/config/) is loaded. This means you are not obligated to place all of your configuration files in an environment folder − only the files that change per environment.
So based on that information, I think the problem is when you are calling it, maybe a problem with your path.

Categories