Configure Database Connections Automatically base on Environment - php

I know this is so wrong, but I've tried google for this kind of task, and I found nothing.
Goal
I'm trying to make an if check, base on my Laravel environment, I will set the database connection appropriately between my local environment and my Heroku production environment.
connections' => [
'mysql' => [
'driver' => 'mysql',
if(env('APP_ENV') == 'local'){
'host' => env('DB_HOST'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'unix_socket' => env('UNIX_SOCKET'),
}else{
'host' => parse_url(getenv("DATABASE_URL"))["host"],
'database' => substr(parse_url(getenv("DATABASE_URL"))["path"], 1),
'username' => parse_url(getenv("DATABASE_URL"))["user"],
'password' => parse_url(getenv("DATABASE_URL"))["pass"],
}
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
]
],

you can define another connection, named for exmaple mysql-heroku, and then in your models you can do protected $connection = (env('APP_ENV') == 'local') ? 'mysql' : 'mysql-heroku';.

Sounds like the Cascading config package would work great for you. Laravel 4 had something very similar to that package.
You can have a config.local folder and config.production folder for your Heroku environment.
Example folder configuration
config/ (production)
├── database.php
config.local/ (local)
├── database.php
config/database.php (production)
...
connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => 'Heroku Host',
'database' => 'Heroku Database',
'username' => 'Heroku Username',
'password' => 'Heroku Password',
'unix_socket' => 'Heroku Socket',
],
],
...
config.local/database.php (local)
...
connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
],
],
...

Related

Error while creating record in laravel - mongo Application

I am using a package for mongodb in laravel : "jenssegers/mongodb": "^3.8",
migrations are working fine, but when I try to create a record using controller, its throwing error
InvalidArgumentException
Database connection [mongoproject] not configured.
my database.php
'mongodb' => [
'driver' => 'mongodb',
'host' => env('MONGO_DB_HOST', 'localhost'),
'port' => env('MONGO_DB_PORT', 27017),
'database' => env('MONGO_DB_DATABASE'),
'username' => env('MONGO_DB_USERNAME'),
'password' => env('MONGO_DB_PASSWORD'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
my .env
DB_CONNECTION=mongodb
MONGO_DB_HOST=127.0.0.1
MONGO_DB_PORT=27017
MONGO_DB_DATABASE=mongoproject
MONGO_DB_USERNAME=
MONGO_DB_PASSWORD=

Laravel: User notification fails to run when executed by the queue due to a InvalidArgumentException : Database [mysql] not configured error

I'm trying to queue notifications in my laravel project. Whenever a notifications is queued it successfully makes a record in the jobs table with the specified delay. However, when the job is executed, it fails due to this error InvalidArgumentException : Database [mysql] not configured. I can schedule regular jobs in the queue which run properly but any notifications I attempt to queue fail. They do work when queueing in sync mode if that matters.
I've also cleared my cache and config php artisan config:clear && php artisan cache:clear
I have database defined in config/queue.php:
'default' => env('QUEUE_CONNECTION', 'database'),
'connections' => [
'sync' => [
'driver' => 'sync',
],
'database' => [
'driver' => 'database',
'table' => 'jobs',
'queue' => 'default',
'retry_after' => 90,
],
...
'failed' => [
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
'database' => env('DB_CONNECTION', 'mysql'),
'table' => 'failed_jobs',
],
and I have mysql defined in config/database.php
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
'mysql' => [
'driver' => 'mysql',
'url' => '',
'host' => env('DB_HOST', DB_HOST),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', DB_NAME),
'username' => env('DB_USERNAME', DB_USER),
'password' => env('DB_PASSWORD', DB_PASS),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => false,
'engine' => 'InnoDB',
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
...
I have dd(config('database.connections')); in my AppServiceProdivder.php which out puts the correct result:
array:4 [
"mysql" => array:15 [
"driver" => "mysql"
"url" => null
"host" => "127.0.0.1"
"port" => "3306"
"database" => "****"
"username" => "****"
"password" => "****"
"unix_socket" => ""
"charset" => "utf8mb4"
"collation" => "utf8mb4_unicode_ci"
"prefix" => ""
"prefix_indexes" => true
"strict" => false
"engine" => "InnoDB"
"options" => []
],
...
]
I have found that when the notification job is executed the database connections are removed and replaced with a default connection which matches my defined mysql connection. However, laravel is looking for a mysql config not default which causes the job to fail.
.env file:
DB_CONNECTION=mysql
DB_PORT=3306
DB_HOST=127.0.0.1
DB_DATABASE=****
DB_USERNAME=****
DB_PASSWORD=****
CACHE_DRIVER=file
#SESSION_DRIVER=database
SESSION_LIFETIME=120
QUEUE_CONNECTION=database
QUEUE_FAILED_DRIVER=database
Here is the stacktrace for the job error:
[2020-12-15 10:09:02] local.ERROR: Database connection [mysql] not configured. {"exception":"[object] (InvalidArgumentException(code: 0): Database connection [mysql] not configured. at /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php:152)
[stacktrace]
#0 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(115): Illuminate\\Database\\DatabaseManager->configuration()
#1 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php(86): Illuminate\\Database\\DatabaseManager->makeConnection()
#2 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1257): Illuminate\\Database\\DatabaseManager->connection()
#3 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1223): Illuminate\\Database\\Eloquent\\Model::resolveConnection()
#4 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1052): Illuminate\\Database\\Eloquent\\Model->getConnection()
#5 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(969): Illuminate\\Database\\Eloquent\\Model->newBaseQueryBuilder()
#6 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1005): Illuminate\\Database\\Eloquent\\Model->newModelQuery()
#7 /var/www/vhost1/master/laravel/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(1031): Illuminate\\Database\\Eloquent\\Model->newQueryWithoutScopes()
#8 /var/www/vhost1/master/vendor/illuminate/queue/SerializesAndRestoresModelIdentifiers.php(114): Illuminate\\Database\\Eloquent\\Model->newQueryForRestoration()
EDIT:
Output from \Log::info($this->app['config']['database.connections']); inside DatabaseManager.php line 149
[2020-12-16 09:19:26] local.INFO: array (
'default' =>
array (
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => '****',
'username' => '****',
'password' => '****',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
)
[2020-12-16 09:19:26] local.INFO: array (
'default' =>
array (
'driver' => 'mysql',
'host' => '127.0.0.1',
'database' => '****',
'username' => '****',
'password' => '****',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
)
I finally figured it out. Another developer was resetting the database connections in a legacy section of our code base outside of the original laravel project. I'm not sure how its effecting the notification queue from where it's located but regardless it was the root of the issue. I doubt anyone else will run into this same scenario but if you do, I fixed it by re-adding my mysql connection with the config name specified.
$this->capsule->addConnection([
'driver' => 'mysql',
'url' => '',
'host' => DB_HOST,
'port' => '3306',
'database' => DB_NAME,
'username' => DB_USER,
'password' => DB_PASS,
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => false,
'engine' => 'InnoDB',
'options' => [],
], 'mysql');```

Using two databases in Laravel

I wish to hide critical server access information as Laravel recommended, so I have setup config/database.php and .env as below, but these couldn't connect each one. which line was wrong?
Laravel version: 5.4
config/database.php
'connections' => [
'master_db' => [
'driver' => 'mysql',
'host' => env('DB_HOST_MASTER', '127.0.0.1'),
'port' => env('DB_PORT_MASTER', '3306'),
'database' => env('DB_DATABASE_MASTER'),
'username' => env('DB_USERNAME_MASTER'),
'password' => env('DB_PASSWORD_MASTER'),
'unix_socket' => env('DB_SOCKET_MASTER'),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
'slave_db' => [
'driver' => 'mysql',
'host' => env('DB_HOST_SLAVE', '192.1.0.2'),
'port' => env('DB_PORT_SLAVE', '3306'),
'database' => env('DB_DATABASE_SLAVE'),
'username' => env('DB_USERNAME_SLAVE'),
'password' => env('DB_PASSWORD_SLAVE'),
'unix_socket' => env('DB_SOCKET_SLAVE'),
'charset' => 'latin1',
'collation' => 'latin1_general_ci',
'prefix' => '',
'strict' => true,
'engine' => null,
],
]
.env
DB_CONNECTION=master_db
DB_HOST_MASTER=127.0.0.1
DB_PORT_MASTER=3306
DB_DATABASE_MASTER=db_master
DB_USERNAME_MASTER=user_master
DB_PASSWORD_MASTER=passwordmaster
DB_CONNECTION=slave_db
DB_HOST_SLAVE=192.1.0.2
DB_PORT_SLAVE=3307
DB_DATABASE_SLAVE=db_slave
DB_USERNAME_SLAVE=user_slave
DB_PASSWORD_SLAVE=passwordslave
If you want use like upper config/database.php file style, then .env file recommend as below as simple. :)
DB_CONNECTION=master_db
DB_HOST_MASTER=127.0.0.1
DB_PORT_MASTER=3306
DB_DATABASE_MASTER=db_master
DB_USERNAME_MASTER=user_master
DB_PASSWORD_MASTER=passwordmaster
// DB_CONNECTION=slave_db <------ no needed this line
DB_HOST_SLAVE=192.1.0.2
DB_PORT_SLAVE=3307
DB_DATABASE_SLAVE=db_slave
DB_USERNAME_SLAVE=user_slave
DB_PASSWORD_SLAVE=passwordslave

Configuration error with MongoDB laravel

I am planning to use MongoDb along with my Laravel project. I am using the jensseger/mongodb extension for it.
I have configured everything. I am getting an error saying mongodb not configured.
This is how my database.php file looks like:
'connections' => [
# Our primary database connection
'mongodb' => [
'driver' => 'mongodb',
'host' => env('DB_HOST'),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
'strict' => false,
],
Double check your configuration in config/database.php
Also make sure that you fire php artisan config:cache after doing the changes.
Be sure to have DB_CONNECTION=mongodb set in your .env file or just replace 'default' => env('DB_CONNECTION', 'mysql') with 'default' => 'mongodb'. I would go with the former, as it's safer to rely only on the .env, rather than hardcoding your default database connection.
'mongodb' => [
'driver' => 'mongodb',
'host' => env('MONGO_DB_HOST', 'localhost'),
'port' => env('MONGO_DB_PORT', 27017),
'database' => env('MONGO_DB_DATABASE'),
'username' => env('MONGO_DB_USERNAME'),
'password' => env('MONGO_DB_PASSWORD'),
'options' => ['database' => 'Database_Name']
],
After clear cache "php artisan config:cache"
go to .env
Add these lines:
MONGO_DB_HOST=127.0.0.1
MONGO_DB_PORT=27017
MONGO_DB_DATABASE=your database name
MONGO_DB_USERNAME=your database username if you have
MONGO_DB_PASSWORD=your database password if you have

How to make read from slave and write at master in mongodb with replicaset using laravel

I am working with laravel 5.1 with mongodb. For mongodb I am using jenssegers mongo configuration.
Now I have to make mongodb replica set and I want to make read operation only from slave & write operation at master.
In laravel's documentation I read that we can make separation in read & write like below:
'mysql' => [
'read' => [
'host' => '192.168.1.1',
],
'write' => [
'host' => '196.168.1.2'
],
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
Here is link for how to set configuration in laravel.
In jenssegers documentation here is configuration for replication:
'mongodb' => [
'driver' => 'mongodb',
'host' => ['server1', 'server2'],
'port' => env('DB_PORT', 27017),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'options' => ['replicaSet' => 'replicaSetName']
],
So if I change this to:
'mongodb' => [
'driver' => 'mongodb',
'read' => ['host' => '192.168.1.1'],
'write' => ['host' => '192.168.1.2'],
'port' => env('DB_PORT', 27017),
'database' => env('DB_DATABASE'),
'username' => env('DB_USERNAME'),
'password' => env('DB_PASSWORD'),
'options' => ['replicaSet' => 'replicaSetName']
],
So can I use the above configuration in jenssegers mongo db configuration?

Categories