Environment driven database settings in Laravel?
You can definitely set database settings (and any other config setting) by environment.
For Laravel 3 (for Laravel 4 and Laravel 5 see below):
Firstly - you need to define $environments
in your paths.php
and set it to something like this:
$environments = array(
'development' => array('*.dev'),
'production' => array('*.com'),
);
Laravel will automatically look for this variable, and if set, will use the associated configuration.
Normally you have a config
folder, with settings such as database.php
and auth.php
Now just create a new folder for each Laravel_Env
you plan to use (such as Development). You'll end up with a folder structure like this;
/application
/config
/development
database.php
/production
database.php
application.php
config.php
database.php
...
user_agents.php
You'll note I've only included database.php
in each subfolder. Laravel will always load the default config settings first, then override them with any custom configs from the environments setting.
Finally, in your development/database file, you would have something like this;
<?php
return array(
'default' => 'mysql'
);
p.s. I just tested this on the current 3.2.12 build of Laravel - and it definitely works.
Bonus Tip: You can also automatically set an environment for Artisan, so you do not have to include the environment manually on each command line! To do this:
You need to know your 'hostname' that you are running Artisan on. To find out - temporarily edit the
artisan.php
in your root folder, and addvar_dump(gethostname());
to line 2 (i.e. above everything).Run
php artisan
from the command line. You will get a string dump with your hostname. In my case its "TSE-Win7";Remove the changes to the
artisan.php
fileAdd your hostname (i.e. "TSE-Win7") to the environments.
You should end up with something like this:
$environments = array(
'development' => array('*.dev', 'TSE-Win7'),
'production' => array('*.com'),
);
Artisan will now run using your development environment. If you deploy to a live server - re-run these steps to get the hostname() for the server, and you can configure a specific artisan config just for the server!
For Laravel 4:
The default environment is always production
. But in your start.php file you can define additional environments.
$env = $app->detectEnvironment(array(
'local' => array('your-machine-name'),
));
On Linux and Mac, you may determine your hostname
by type hostname
in your terminal - it will output the name of your computer. On Windows put dd(gethostname());
at the beginning of your routes.php
file - and run the website once - it will show you the current hostname of your computer.
To get the current environment as a variable in your application - read this SO answer here. Laravel 4: how can I get the environment value?
For Laravel 5:
There is single configuration file, called .env
in your root directory.
Watch this laracast, config explained fully.
Laravel 4 separate config files for packages
Package-related, environment-specific configuration files have to be placed in the package's directory within a subdirectory named after the environment. So in your case this would be
app
- config
- packages
- greggilbert
- recaptcha
- development
- config.php
- production
- config.php
But it can get really ugly and cumbersome in some cases. This can be solved in a (in my opinion) cleaner and more elegant way through enviroment files in your application root directory:
/.env.development.php
<?php
return [
// any configuration settings for your local environment
'RECAPTCHA_TEMPLATE' => 'customCaptcha',
'RECAPTCHA_LANGUAGE' => 'en',
];
That way, you could leave the package directory as it is:
app
- config
- packages
- greggilbert
- recaptcha
- config.php
Laravel will load the environment file according to the environment and make the environment variables globally available through getenv()
. So now you could just grab the specified template for the current environment with getenv('RECAPTCHA_TEMPLATE')
from the config.php.
Laravel Different Database Credentials for local and production
Do like this
config/database.php (production setting)
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'db'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', '********'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
.env file (local setting)
APP_ENV=local
APP_DEBUG=true
APP_URL=project.dev
DB_HOST=localhost
DB_DATABASE=mydb
DB_USERNAME=root
DB_PASSWORD=
Artisan unable to use $_SERVER variables from database config file
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?
Can't install Laravel to dynamically created database
If you want to change a config during runtime, use:
config(["database.connections.{$connection}.database" => $dbname]);
However, as you are changing a pre-existing connection, the DatabaseManager
may have already created a connection using the old config. Therefore you may need to run the following:
DB::reconnect($connection);
This would not be needed if it is a fresh new connection that was not used. i.e.
config(["database.connections.{$connection}' => $connectionConfig]);
If you want to choose which database connection to use just do:
DB::connection($connectionName)->where('what_ever', 20)->...->get()
Alternatively change your default connection like so:
DB::setDefaultConnection($connectionName);
DB::where('whaterver', 20)->...->get()
The reason the following does not work is:
// You shouldn't be changing env variables during runtime, especially if config is cached
$_ENV['DB_DATABASE'] = $dbname;
// this function checks what environment your in. Correct usage $this->getLaravel()->environment('staging')
$this->getLaravel()->environment(['DB_DATABASE' => $dbname]);
$this->info('env: ' . $this->getLaravel()->environment('DB_DATABASE'));
// This enables the the putenv adapter. You shouldn't be calling it for this.
\Illuminate\Support\Env::enablePutenv();
// putenv shouldn't be used in Laravel project
putenv('DB_DATABASE=' . $dbname);
// This should set the database for the config, but you need to make sure your using it. Note this change is not persistent.
config(['database.connections.' . $connection . '.database' => $dbname]);
Related Topics
Multiple Auto Increment in MySQL
Generating a Waveform Using Ffmpeg
How to Set an Absolute Include Path in PHP
Passing JavaScript Variables to PHP
How to Design a Hierarchical Role Based Access Control System
Laravel: Auth::User()->Id Trying to Get a Property of a Non-Object
Dynamically Load Information to Twitter Bootstrap Modal
Magento Addfieldtofilter: Two Fields, Match as Or, Not And
Natural Sorting Algorithm in PHP with Support for Unicode
How to Make My PHP Ide Understand Dependency Injection Containers
Fatal Error: Call to Undefined Function Mcrypt_Encrypt()
Replace &Nbsp; Characters That Are Hidden in Text
Ajax/PHP - How to Get Posted Data to Load into a Modal on the Same Page
Symfony2 - How to Switch from "Dev" to "Prod"
PHP Exec() Is Not Executing the Command