#database #laravel #config
#База данных #laravel #конфигурация
Вопрос:
Как вы все знаете, в Laravel config/database.php
есть куча arrays
и values
. Но для определенного условия мне нужно выполнить некоторую логику, и мне удается выполнить простую логику, config/database.php
и она работает так, как я хочу (могу сослаться на приведенный ниже код), но мне интересно, хорошо ли это / практично делать так?
Если это непрактично, можете ли вы предложить другой способ получить тот же результат, что и ниже?
'connections' => [
'mysql' => (function(){
$config = [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'live_db'),
'username' => env('DB_USERNAME', 'myuser'),
'password' => env('DB_PASSWORD', '2309423234'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => 'gn_',
//'prefix_indexes' => true,
'strict' => false,
'engine' => env('DB_ENGINE', null),
];
// do some logic here (and it's working!!)
// but........
// is it okay to do like this?
if(env('DB_WITH_SSLMODE', false)){
$config = [
'sslmode' => env('DB_SSLMODE', 'prefer'),
'options' => [
PDO::MYSQL_ATTR_SSL_CA => env('DB_OPT_MYSQL_ATTR_SSL_CA', 'C:wamp64bincloudsqlcertificatesserver-ca.pem'),
PDO::MYSQL_ATTR_SSL_CERT => env('DB_OPT_MYSQL_ATTR_SSL_CERT', 'C:wamp64bincloudsqlcertificatesclient-cert.pem'),
PDO::MYSQL_ATTR_SSL_KEY => env('DB_OPT_MYSQL_ATTR_SSL_KEY', 'C:wamp64bincloudsqlcertificatesclient-key.pem'),
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => env('DB_OPT_MYSQL_ATTR_SSL_VERIFY_SERVER_CERT', false)
],
];
}
return $config;
})(),
],
Ответ №1:
Как насчет использования троичного оператора? (почти так же, как это делается по умолчанию в laravel 5.8).
Примечание: Первое решение не удаляет sslmode из массива конфигурации. Если вам нужно это сделать, просто выберите второй вариант!
1) Это должно работать следующим образом:
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
'sslmode' => env('DB_WITH_SSLMODE') ? env('DB_SSLMODE','prefer') : null,
'options' => (extension_loaded('pdo_mysql') amp;amp; env('DB_WITH_SSLMODE')) ? [
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
PDO::MYSQL_ATTR_SSL_CERT => env('MYSQL_ATTR_SSL_CERT'),
PDO::MYSQL_ATTR_SSL_KEY => env('MYSQL_ATTR_SSL_KEY'),
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => env('MYSQL_ATTR_SSL_VERIFY_SERVER_CERT')
] : [],
],
],
или
2) грязное решение, но с одним условным:
'connections' => [
'mysql' => array_merge([
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null
], (extension_loaded('pdo_mysql') amp;amp; env('DB_WITH_SSLMODE')) ? [
'sslmode' => env('DB_SSLMODE', 'prefer'),
'options' => [
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
PDO::MYSQL_ATTR_SSL_CERT => env('MYSQL_ATTR_SSL_CERT'),
PDO::MYSQL_ATTR_SSL_KEY => env('MYSQL_ATTR_SSL_KEY'),
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => env('MYSQL_ATTR_SSL_VERIFY_SERVER_CERT')
]
] : [ 'options' => [] ]),
],
Затем переместите значения по умолчанию, которые у вас были в env(), в ваш файл .env (обратите внимание, что я удалил префикс DB_OPT_):
DB_WITH_SSLMODE=true
MYSQL_ATTR_SSL_CA=C:wamp64bincloudsqlcertificatesserver-ca.pem
MYSQL_ATTR_SSL_CERT=C:wamp64bincloudsqlcertificatesclient-cert.pem
MYSQL_ATTR_SSL_KEY=C:wamp64bincloudsqlcertificatesclient-key.pem
MYSQL_ATTR_SSL_VERIFY_SERVER_CERT=false
Поэтому, если вы установите DB_WITH_SSLMODE в значение false, будет возвращен пустой массив, и ssl не будет включен.
Примечание: я думаю, что указанный вами sslmode необходим только для соединений PostgreSQL, что не в вашем случае.
Комментарии:
1. о чем
'sslmode' => env('DB_SSLMODE', 'prefer'),
это?? куда его поместить?2. Прочитайте примечание внизу ответа: оно должно быть необходимо только для соединений PostgreSQL. Если вы попробуете эту конфигурацию, она должна работать в любом случае
3. на самом деле мне это нужно … на моем живом сервере, если я удалю
sslmode
, появится сообщение об ошибке …. поэтому мне нужноsslmode
..4. в моем
live server
мне нужно включить SSL … но на моем локальном хостинге мне нужно отключить SSL … поверьте мне, первое решение не работает… я уже пытался… если я хочу отключить SSL, я должен удалитьsslmode
свойство … если я не удалю его, и если я просто сделаю его пустым значением (например'sslmode'=>''
), это вызовет ошибку .. но, тем не менее, грязное (2-е) решение работает… спасибо, что поделились …. я поддержал ваш ответ..5. Хорошо, позже я подумал, что вам нужно полностью удалить решение. если это так, то второе решение — это правильный путь.
Ответ №2:
Для этого вы можете создать поставщика услуг:
class SSLServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot(Kernel $kernel)
{
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
$config = Config::get('database.connections.mysql');
if (env('DB_WITH_SSLMODE', false)) {
$config = [
'sslmode' => env('DB_SSLMODE', 'prefer'),
'options' => [
PDO::MYSQL_ATTR_SSL_CA => env('DB_OPT_MYSQL_ATTR_SSL_CA',
'C:wamp64bincloudsqlcertificatesserver-ca.pem'),
PDO::MYSQL_ATTR_SSL_CERT => env('DB_OPT_MYSQL_ATTR_SSL_CERT',
'C:wamp64bincloudsqlcertificatesclient-cert.pem'),
PDO::MYSQL_ATTR_SSL_KEY => env('DB_OPT_MYSQL_ATTR_SSL_KEY',
'C:wamp64bincloudsqlcertificatesclient-key.pem'),
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => env('DB_OPT_MYSQL_ATTR_SSL_VERIFY_SERVER_CERT', false)
],
];
}
Config::set('database.connections.mysql', $config);
}
}
и не забудьте зарегистрировать своего поставщика услуг в config/app.php
AppProvidersSSLServiceProvider::class,
Комментарии:
1. новые знания для меня… спасибо … я уверен, что это работает, но я все еще чувствую, что этот ответ не practical….so я не могу отметить ваш ответ… но я поддерживаю этот ответ …. спасибо, что поделились этим…
2. Не используйте никаких вызовов env(), кроме как в файлах конфигурации, потому что, если вы включите кеширование конфигурации (
php artisan optimize/php artisan config:cache
), любой вызов env за пределами папки конфигурации вернет пустое значение.3. @mdexp ,,, да, это делает sense…it означает , что этот ответ не подходит, если мы используем
config:cache
… верно?4. Верно, это также указано в документации
Ответ №3:
На самом деле вы также можете сделать что-то столь же простое, как:
$database = [
'connections' => [
'mysql' => [
'driver' => 'mysql',
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'live_db'),
'username' => env('DB_USERNAME', 'myuser'),
'password' => env('DB_PASSWORD', '2309423234'),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => 'gn_',
//'prefix_indexes' => true,
'strict' => false,
'engine' => env('DB_ENGINE', null),
]
]
];
if(env('DB_WITH_SSLMODE', false)){
$database['connections']['mysql'] = [
'sslmode' => env('DB_SSLMODE', 'prefer'),
'options' => [
PDO::MYSQL_ATTR_SSL_CA => env('DB_OPT_MYSQL_ATTR_SSL_CA', 'C:wamp64bincloudsqlcertificatesserver-ca.pem'),
PDO::MYSQL_ATTR_SSL_CERT => env('DB_OPT_MYSQL_ATTR_SSL_CERT', 'C:wamp64bincloudsqlcertificatesclient-cert.pem'),
PDO::MYSQL_ATTR_SSL_KEY => env('DB_OPT_MYSQL_ATTR_SSL_KEY', 'C:wamp64bincloudsqlcertificatesclient-key.pem'),
PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => env('DB_OPT_MYSQL_ATTR_SSL_VERIFY_SERVER_CERT', false)
]
];
}
return $database;