Как избежать двойного подключения базы данных MySQL?
В своем скрипте я вызываю функцию
<?php if (checkPinCode() == 1): ?>
текст
<?php endif ?>
Сама функция подключается к базе данных
<?php
session_start();
/**
* Function
*/
function check() {
include __DIR__ . '/db_config.php';
Все работает корректно до того, как повторно не вызову ее.
Т.е. дважды прописываю в скрипте
<?php if (checkPinCode() == 1): ?>
текст
<?php endif ?>
<?php if (checkPinCode() == 1): ?>
текст два
<?php endif ?>
Обратите внимание: Константа DBSERVER уже определена в ...
require_once __DIR__ . '/db_config.php'; не решило проблему.
Как проверить определены ли уже константы, чтобы не вызывать ошибок?
Посоветовали создать шаблон Singleton, не получается у меня интегрировать его в свой скрипт.
db_config.php
<?php
define('DBSERVER', 'localhost');
define('DBNAME', 'cayddftg_pin_code');
define('DBUSER', 'cayddftg_cayddftg');
define('DBPASS', '2E0m9X0r');
$mysqli = new mysqli(DBSERVER, DBUSER, DBPASS, DBNAME);
if($mysqli->connect_errno > 0){
die('Error: [' . $mysqli->connect_error . ']');
}
/* Charset */
if (!$mysqli->set_charset('utf8mb4'));
/* MYSQLI REPORT ERROR | MYSQLI REPORT STRICT */
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
/* PayPal configuration */
define('PAYPAL_SANDBOX', TRUE); // TRUE or FALSE
/* Change not required */
define('PAYPAL_URL', (PAYPAL_SANDBOX == true)?"https://www.sandbox.paypal.com/cgi-bin/webscr":"https://www.paypal.com/cgi-bin/webscr");
Ответы (3 шт):
Подозреваю, что ваш singletone не является таковым, раз уже можно создать 2 екземпляра класса.
вот для примера типичный singletone БД, пересмотрите, мб у вас что-то не так
class DB
{
private static $_instance = null;
private static $_connection;
private const DB_HOST = 'localhost';
private const DB_NAME = 'itvdn';
private const DB_USER = 'root';
private const DB_PASS = 'password';
private function __construct()
{
static::$_connection = new PDO(
'mysql:host=' . self::DB_HOST . ';dbname=' . self::DB_NAME,
self::DB_USER,
self::DB_PASS,
[PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"]
);
}
private function __clone()
{
}
private function __wakeup()
{
}
public static function getInstance(): self
{
if (!static::$_instance) {
static::$_instance = new static();
}
return static::$_instance;
}
public function getConnection(): PDO
{
return static::$_connection;
}
}
Следуя написанному в документации:
Как и superglobals, константы доступны из любой области видимости. Константы можно использовать из любого места скрипта независимо от области видимости.
или
Like superglobals, the scope of a constant is global. Constants can be accessed from anywhere in a script without regard to scope. For more information on scope, read the manual section on variable scope.
Поэтому даже если константа объявлена в функции, то она, если можно так сказать, "всплывает" и получается, что она уже существует.
Так что эти переменные надо подключать единожды в каком-либо файле, который будет подключаться к проекту единожды.
Так же стоит рассмотреть подход, когда работа происходит через единую точку входа в приложении. Это самый распространённый подход. Тогда скрипт с глобальными переменными можно будет подключить где-то в самом начале единожды и всё.
Для того чтобы решить эту ппоблему, надо запомнить несколько важных, но очень простых правил
- Подключение к БД должно быть одно. Для этого файл с подключением надо инклюдить не в каждой функции, а в самом начале кода, один раз.
- Подключение к БД при этом хранится в переменной, в данном случае $mysqli.
- Для того чтобы получить доступ к переменной внутри функции, ее надо передат ьв качестве параметра
То есть при создании функции надо писать так
function checkPinCode($mysqli) {
а при вызове - так:
checkPinCode($mysqli)
и все будет прекрасно работать, с единстенным подключением.