I'm a long time Zend Framework user (now renamed Laminas). But I decided to give a try to last Symfony version. So I just installed it in 5.1.2.
I'm facing a question regarding the multiple environments deployments. In my compay, we have :
Local environment which is developer pc.
Development.
Staging.
Production.
In ZF-Laminas, we have a global.php file which is located in config directory.
For those of you who are not familiar with this framework, you can override key set in global.php file by creating local.php file.
In this global file, I use to put standard configuration for my application.
For example (prod) :
'open_id' => [
'client_id' => 1234
]
Then, I have development and staging files which car override those values for every environmenet. During the deployment, the file corresponding to the environment is copied to local.php.
Let's say staging.local.php.dist becomes local.php with :
'open_id' => [
'client_id' => 5678
]
Which is fine because value is overriding the one from global file.
I would like the same behavior in Symfony but I don't see something similar in Symfony 5.
So far, I only found two possibilities
Create a bundle which will allow me to have a <bundle_name>.yaml file in config/packages directory. According to the documentation (https://symfony.com/doc/current/configuration.html#configuration-files), I will be able to have dev, prod and staging overrides. But it forces me to create a bundle to handle just some standard configurations, which is huge.
Use .env files. But .env files only allow string data, not complex data like arrays.
What do I miss ? Or is it my "zend" way of doing things that is wrong ?
Thanks.
You can also create services_%env%.yaml (services_dev.yaml, services_test.yaml) files for each environment. It will allow you to define different parameters and override/define services for each environment.
Example:
config/services_dev.yaml
parameters:
hello: 'world'
From what I understand from your post, your goal is to have different config values based on the server you are on. If this is the case, you can use environment variables (in the .env file or .env.local for server specific config). You can then use these values in your applications by binding the env var to a parameter. This parameter will then be available within the configuration by using %parameter_name% as value or within the container. You can also pas parameters to services (service definitions are handled the same way as any other config). For more information you can checkout these sources:
https://symfony.com/doc/current/configuration/env_var_processors.html
https://symfony.com/doc/current/configuration.html
Related
I have several instances of the same platform for different people.
Some of them have different translation files than others according to their specific requests.
For the moment, the files have different names and we distinguish them by the pattern in the module.config.php.
The problem is that we have to update and replace the module.config.php every time we update the code (with GIT) to change the pattern according to the client.
Is there a way to define a constant in a *.local.php file and to be able to access it in module.config.php with ZF2 ?
Thank you in advance for your help!
Update : Thanks to #delboy1978uk.
You can use environment variables either in (for Apache at least) the system-wide apache.conf or httpd.conf, in the virtual host or in the .htaccess file. It will then be accessible by getenv()
In Laravel 4, you could set an environment based config folder structure:
/config/app.php
/config/dev/app.php
/config/staging/app.php
/config/testing/app.php
Can you do this with Laravel 5? I understand the .env concept and I'm using that to define which environment I'm in. But I need to define a config value that is an array of arbitrary length, and you can't do that with .env files.
An example of what I'm trying to achieve:
if (in_array($request->input('value'), config('app.valid_values')) {
// do something
}
This valid_values is simply an array of values. It's of arbitrary length, so you can't just set them in your .env file like:
VALID_VALUE1=...
VALID_VALUE2=...
etc.
AND the array needs to be different for each environment.
This was easy to do in Laravel 4 with environment configuration folders. But how do you do this with Laravel 5?
If you need to create an array on values, you can create on string format and when you need you can parse them
MY_ARRAY_VALUE=1,2,house,cat,34234
When you need them
$myArrayValue = explode(',', env('MY_ARRAY_VALUE'));
Or save your values in JSON and get them with json_decode()
$myArrayValue = json_decode(env('MY_ARRAY_VALUE'), true);
Extra info:
On Laravel 5, you need to translate all your configs files in one .env file.
On each environment your .env file will be diferent with values for this environment.
To set your environment, you need to change the value of APP_ENV in your .env file
APP_ENV=local
And you can create your own variables in that file
https://laravel.com/docs/5.2/configuration#environment-configuration
This is an extract of the upgrade guide to Laravel 5.0
https://laravel.com/docs/5.2/releases#laravel-5.0
Instead of a variety of confusing, nested environment configuration directories, Laravel 5 now utilizes DotEnv by Vance Lucas. This library provides a super simple way to manage your environment configuration, and makes environment detection in Laravel 5 a breeze. For more details, check out the full configuration documentation.
You can find a default .env file here: https://github.com/laravel/laravel/blob/master/.env.example
It is often helpful to have different configuration values based on the environment the application is running in. For example, you may wish to use a different cache driver locally than you do on your production server. It's easy using environment based configuration.
To make this a cinch, Laravel utilizes the DotEnv PHP library by Vance Lucas. In a fresh Laravel installation, the root directory of your application will contain a .env.example file. If you install Laravel via Composer, this file will automatically be renamed to .env. Otherwise, you should rename the file manually.
Generally for Phpdotenv
Phpdotenv is about storing values in environment, not general purpose config library. Environment is UNIX concept and the values are always interpreted as character strings. Converting to different datatypes such as arrays or booleans even though convenient would be outside the scope of this class.
Laravel config system
Laravel's config system is already separated. phpdotenv does environment, laravel does config. Then once config is done, environment is ignored. The concern of parsing environment variables from strings into whatever is passed on to laravel (weather that be their env function, or exploding inside your config files).
Good practice
In other words, use Config::get() to get a specific conf file with your desired structure and you have what you need.
You should never use env() in the code directly when it is outside of the config folder according to the Laravel guidelines. It's a good practice to use config(). In config files use env() to get the data from .env file.
I have a Laravel project right now and I'm using Github for my project.
I have two branches, master and develop.
The problem right now is,...
I have all the files in one folder /dev I'm using Sublime Text 2 and the official Github Client. When I switch branches, I see that in ST2 in the status bar, that's fine.
I put sftp-config.json in my gitignore BUT I have different FTP data for master and develop. I always have to edit the data in ST2 tu upload correctly onto my FTP to test my changes. Sometimes I even forget that, and accidentally upload develop to my master/live page.
Same problem for the routes.php, I need to disable SSL in my routes.php for the DEV because I do not have a wildcard certificate and my dev branches/ftp runs on dev.domain.tld and my main site at www.domain.tld .
I created a environment for my Laravel configs, one main config and "development" config.
Is it possible to use Config::get('app.ssl') in my routes.php in my filter? Like that:
Route::group(['before' => ['csrf',Config::get('app.ssl')]], function () {
Route::get('page', array('as' => 'page','uses' => 'PageController#getIndex'));
});
?
My workflow right now is very annoying and confusing sometimes. I always have to check that I do not upload stuff on my live server or changes the master files.
Any suggestions are highly appreciated!
Of course! Laravel supports environmental configuration out of the box. You can find pretty much everything you need in the official docs. However here's an example:
app/config/app.php - "main config"
array(
// other config entries
'ssl' => true
)
app/config/local/app.php - config for the environment local (you can call it whatever you want)
array(
'ssl' => false // here we override the value from our main config
)
Now the last thing we have to do is make sure our environments get detected correctly.
Laravel uses the host name to detect an environment. So you need to figure out how your machine(s) is called.
An easy way to do that is with the PHP function gethostname()
In bootstrap/start.php you can define your environments:
$env = $app->detectEnvironment(array(
'local' => array('your-machine-name'),
'other-environment' => array('other-machine-name')
));
I'm trying to get a config value from another (not current) environment. I would like to get it calling something like:
$value = Config::get('app.locale', 'default', 'my_environment');
Obviuosly Config::get() takes only 2 params by default, but are there any other functions to get config in neat way, to get what I want? I can't find anything in the API.
An answer to this question How to get config data in laravel in a subfolder happens to be a solution for me as well.
Rather than passing some other parameters to Config::get(), you can pass a path to file in the first parameter. So calls like:
Config::get('local/app.locale');
Config::get('dev/app.locale');
will get config from local, dev, etc. environments, no matter what's your current working environment.
Laravel environments, are for seperating configurations from develop machine and production machine.
If you want on all env. the same config you can use the global config files in app/config/* for individual configuration per env. you use the app/config/<YOUR ENVIRONMENT>.
so to get your app.locale in all environment the same use the app/config/app.php file
I sometimes work with Codeigniter, and after I'm done developing on the local site, I need to migrate the files to the server. All the files in the /config/ folder need to be changed to match the Server settings. It's not right to make an entire commit for these changes, do I simply make Git ignore these files altogether, or is there a way to track these changes and apply them with Git at the right moment?
You could keep versioned:
two "value config files", with the right values for each environment
a template config file, with value placeholder in it (for instance, ##PORT_NUMBER##)
a script able to generate the actual config file depending on the current environment
a content filter driver which, on checkout, will trigger the script in order to generate the right config file.
Note: that supposes your template config file has a recognizable content (the filter doesn't have a name or path of the file). See "Git equivalent of subversion's $URL$ keyword expansion" for more on the limitation of git content filter driver).
It depends on Your needs. In my company we use other approach.
We've created several environments (where the asterix is internal project name):
devel - site runs on domain **.local.com*
test - site run on domain test.*.company.com
beta - beta.*.company.com
production - every other domain.
Based on the domain name we switch automatically configurations.
Basicly config file looks like:
<?php
return array(
'_env' => array(
'devel' => array(
// config for devel
),
'production' => array(
// config for production
)
)
);
?>
Some frameworks (AFAIR Zend) set the environment name in Virtual Host config (or .htaccess). You should look at: zend framework auto switch production staging test .. etc
Have You looked at CI documentation? There's a section about it.
Create two folders in the config folder. One is called development and the other is production. Now copy config.php, database.php etc to each of these folders. Now when you are on production server, CodeIgniter will first check the production folder for the files. If it is not there, then it uses the default file in the config folder. And if you are on development environment, CodeIgniter will first check the development folder.
If you want to keep any config file identical to the production and development environment, keep it in config folder.
If you want to set the environment then add the following code in .htaccess file:
#This code for Development Environment
SetEnv CI_ENV development
and
#This code for Production Environment
SetEnv CI_ENV production