Laravel different config/database.php for production and development - php

I'm developing Laravel app on my local server where I have database and also I'm putting in online in production environment.
Each environment has different db connection information. So far I dealt with this just commenting information when I'm committing like this:
'mysql' => [
'driver' => 'mysql',
'host' => $host,
'database' => $database,
'username' => $username,
'password' => $password,
// 'host' => env('DB_HOST', 'localhost'),
// 'database' => env('DB_DATABASE', 'forge'),
// 'username' => env('DB_USERNAME', 'forge'),
// 'password' => env('DB_PASSWORD', ''),
// 'unix_socket' => '/Applications/MAMP/tmp/mysql/mysql.sock',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
but this is sure wrong approach. How can I set different database connection information for each environment is some better way?

Use the .env file instead.. Have a .env in your production and one in your development..
Take a look at your .env.example
Laravel Environment Configuration Documentation

Related

Laravel 5.0 Auth uses Homestead instead of .env DB

I've setup Laravel 5.0 (that's a requirement) and set it up to use remote MySQL DB. All migrations and data interactions pass OK, but when trying to use Auth login POST, it fails with PDOException in Connector.php line 47:
SQLSTATE[HY000] [2002] No such file or directory, mentioning " PDO->__construct('mysql:host=localhost;dbname=homestead', 'homestead', 'secret', array('0', '2', '0', false, false))"
WHERE did it take that homestead DSN? Why does it skip the database.php config and .env config? If I try to add to .env some socket info (well it should not count here, right?) the socket path passes to the mentioned PDOException call stack, but hostname, login etc. NOT!
Confused. What am I doing wrong?
UPD
Here's the .env:
APP_ENV=local
APP_DEBUG=true
APP_KEY=SomeRandomString
DB_HOST=mysql.someremteohosting.net
DB_DATABASE=mydb
DB_USERNAME=myuser
DB_PASSWORD=mysuperpassword
CACHE_DRIVER=file
SESSION_DRIVER=file
QUEUE_DRIVER=sync
And here's database.php:
<?php
return [
'fetch' => PDO::FETCH_CLASS,
'default' => 'mysql',
'connections' => [
'sqlite' => [
'driver' => 'sqlite',
'database' => storage_path().'/database.sqlite',
'prefix' => '',
],
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
'pgsql' => [
'driver' => 'pgsql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'prefix' => '',
'schema' => 'public',
],
'sqlsrv' => [
'driver' => 'sqlsrv',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'prefix' => '',
],
],
'migrations' => 'migrations',
],
];
Again, all migrations work. I can create, save and fetch objects in tinker without any problem. The only reference to homestead is in .env.example file.
Not sure what exactly was wrong here. The only place where I found 'homestead' in the app code was in .env.example. I deleted it an ran composer dump-autoload. After that it worked. Still surprised about laravel lurking into .example config without any reason.

Laravel testing with phpunit

How can I make sure that when I'm testing in Laravel with phpunit and for example I want to test my api route /test/1 it uses my test database?
I already made a test connection and changed my phpunit.xml file. I changed DB_CONNECTION to the test connection that I made.
<env name="DB_CONNECTION" value="mysql_testing"/>
But it when I make a post request I receive data from the development database?
In your Config/database.php file, what is the value of database in mysql_testing? It should be like this:
'mysql_testing' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', '3306'),
'database' => env('TEST_DB_DATABASE', 'db_testing'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
'engine' => null,
],
And database db_testing must exists.
Inside one of your test files, add the following to output your current DB_CONNECTION:
dd(env('DB_CONNECTION'));
You should get mysql_testing in your test output if PHPUnit.xml is properly setup.

Change database setup now having error even after reverting to orginal setup (Laravel 5)

I tried to experiment with my Laravel 5 database.php, originally
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', 'forge'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
then I changed to
'mysql' => [
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'mydb',
'username' => 'root',
'password' => 'password',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
now I am having this error even if I revert to the original setup?
#1045 - Access denied for user 'root'#'localhost' (using password: NO)
env file contains
DB_HOST=localhost
DB_DATABASE=homestead
DB_USERNAME=homestead
DB_PASSWORD=secret
In the first part of your config/database.php there's should be something like:
'default' => env('DB_CONNECTION', 'mysql'),
make sure you didn't change that.
Anyway, as explained here you should use a local .env file for your database configuration.

Using multiple databases for different endpoints

I have API written in lumen(laravel). I am using Eloquent for my models.
What I need to do is to use different databases based on url (endpoint).
For example I have http://apiprovider.com/api/v1/ as base API url and it connects to the api_v1 database, but I need to use another database if v2 is used http://apiprovider.com/api/v2 for instance api_v2 database.
All classes and laravel application should be the same, only different database according to version.
Database settings is stored in .env file.
Please suggest the right way to implement this ? Or at least possible ways.
Thanks.
It's just an idea, i haven't tried it but a simple way would be switching between the two databases from a middleware.
For example you could define the two connections available in database.php :
'connections' => [
'mysql1' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
'mysql2' => [
'driver' => 'mysql',
'host' => env('DB_HOST_2', 'localhost'),
'database' => env('DB_DATABASE_2', 'forge'),
'username' => env('DB_USERNAME_2', 'forge'),
'password' => env('DB_PASSWORD_2', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
]
Then create a middleware and switch the DB in the handle method
public function handle($request, Closure $next)
{
//check the request URL and decide what DB to use
//set the DB for this request
Config::set('database.default', $dbname );
}
I think that Config::set('database.default', $dbname); will work only for the current request, but it would do what you need

Best way to connect multiple databases in Laravel [duplicate]

This question already has answers here:
How to use multiple databases in Laravel
(7 answers)
Closed 5 years ago.
I am creating a multi-tenant application in which, based on the sub-domain, I am connecting to a database of that particular tenant.
Here is code to do that:
// To connect with a subdomain - the entry will be in config/database.php.
public static function connectSubdomainDatabase($dbname)
{
$res = DB::select("show databases like '{$dbname}'");
if (count($res) == 0) {
App::abort(404);
}
Config::set('database.connections.subdomain.database', $dbname);
//If you want to use query builder without having to specify the connection
Config::set('database.default', 'subdomain');
DB::reconnect('subdomain');
}
Is it the best way to connect with a database or is there any problem that because I am thinking from the performance point of view because every time I am connecting with the database when there are different subdomains. What is the best possible way to do that?
This is nearly the best way to do this. In the end, it's all opinion anyway. However, I would create a connection in the configuration file for each of the subdomains. Then, in your connectSubdomainDatabase() function, I would get the current subdomain instead of passing a database name. You can already specify a connection in laravel, the only place you should be using database names is in the config file.
So, something like this:
// To connect with a subdomain - the entry will be in config/database.php.
public static function connectSubdomainDatabase()
{
// Break apart host
$urlParts = explode('.', $_SERVER['HTTP_HOST']);
// Change default connection
Config::set('database.default', $urlParts[0]);
}
Where the config/database.php connections is:
'connections' => [
'subdomain1' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
'subdomain2' => [
'driver' => 'mysql',
'host' => env('DB_HOST', 'localhost'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
],

Categories