Помогите разобраться. На локальном сервере все хорошо работает. При переносе на хостинг и попытке войти на сайте вместо стартовой страницы выдает:
Доступ запрещен для пользователя ‘dbuser’@’ localhost ’ (с использованием пароля: ДА)
Фатальная ошибка: объект mysqli уже закрыт DataBase.php:33
Потом это сообщение может просто исчезнуть и сайт показывает пустую белую страницу (хотя favicon показывает). А в отчете об ошибках на хостинге есть такое сообщение:
Класс ‘DataBase’ не найден в Config.php:38
код Config.php
<?php
class Config
{
public $db_h = '+++';
public $db_u = '+++';
public $db_p = '+++';
public $db_n = '+++';
public $db_charset = 'utf8';
public $pdo = false;
public $db_opt = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT,//PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => true,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false,
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8",
];
/* В данном массиве хранятся пути где автозагрузчик классов autoload() будет искать классы. */
public $includes = [
'/',
'/Helpers/'
];
public function __construct()
{
}
}
class App
{
public $connect; // переменная хранит экземляр соединения с базой данных
public function __construct()
{
spl_autoload_register(array($this,'autoload')); // регистрация автозагрузчика классов
$this->config = new Config();
$this->database = new DataBase();
if($this->config->pdo === false)$this->connect = $this->database->connect_mysqli();
else $this->connect = $this->database->connect_pdo();
$this->init();
}
/* Атозагрузчик классов */
private function autoload($class_name){
$class_name = str_replace('\\','/', strtolower($class_name));
/* Цикл, берётся массив includes и каждое значение подставляется в путь, дальше идёт проверка существует ли он, и если да, то include_once */
foreach ($this->config->includes as &$value) {
$file = $_SERVER['DOCUMENT_ROOT'].$value.$class_name.'.php';
if(file_exists($file)){
include_once $file;
}
}
unset($value);
}
/* Основные динамичные конфиг записи. Выполняются при старте класса: $app = new App(); */
public function init()
{
if(true)ini_set('error_reporting', E_ALL);ini_set('display_errors', 1);ini_set('display_startup_errors', 1);
ini_set('session.gc_maxlifetime', 86400*90);
ini_set('session.cookie_lifetime', 86400*90);
ini_set('session.save_path', $_SERVER['DOCUMENT_ROOT'].'/sessions');
if(session_status() == PHP_SESSION_NONE)session_start();
}
}
$app = new App();
$DataBase = $app->database; //Создаёт экземпляр класс DataBase, где находятся вспомогательные функции работы с базой данных (get_result), а так же реализации соединений с базой и получения соединения
$mysqli = $app->connect; //Получаем экземпляр соединения в базой данных (необходимо для поддержки стандартных способов работы с базой)
//$app = new Config2();
//require_once('DataBase.php');
код DataBase.php
<?php
class DB
{
public $mysqli;
public $pdo;
static private $instance = null;
private function __construct(){
}
private function __clone() {}
static function getInstance() {
if(self::$instance == null)self::$instance = new self();
return self::$instance;
}
}
class Database
{
public $mysqli;
public $pdo;
public function __construct(){
$this->config = new Config();//Погрузка экземпляра класса Config (хранит переменные для соединения)
}
/* Функция соединения с базой данных mysqli */
public function connect_mysqli(){
$database = $this->config; //Использовать переменные из класса Config
$mysqli = @new mysqli($database->db_h, $database->db_u, $database->db_p,$database->db_n);
if ($mysqli->connect_error) {
echo $mysqli->connect_error;
//Errors::ErrorConnectBD();
$mysqli->close();
return false;
}
DB::getInstance()->mysqli = $mysqli;
$this->mysqli = $mysqli;
return $mysqli;
}
/* Функция соединения с базой данных pdo */
public function connect_pdo(){
$database = $this->config;
$dsn = 'mysql:host='.$database->db_h.';dbname='.$database->db_n.';charset='.$database->db_charset;
try {
$pdo = new PDO($dsn, $database->db_u, $database->db_p, $database->db_opt);
} catch (PDOException $e) {
print 'Error!: '.$e->getMessage().'<br/>';
return false;
die();
}
DB::getInstance()->pdo = $pdo;
$this->pdo = $pdo;
return $pdo;
}
static function getInstance() {
return self;
}
public function get_types($sql, $params = null)
{
if($params === null)return ['sql'=>$sql];
$pattern = '|(:[a-zA-Z0-9_\-]+)|';
if (preg_match_all($pattern, $sql, $matches)) {
$arr = $matches[1];
foreach ($arr as $word) {
if (strlen($word) > 2 && $word[2] == '_') {
$bindType[] = $word[1];
} else {
switch (gettype($params[$word])) {
case 'NULL':
case 'string':
$bindType[] = 's';
break;
case 'boolean':
case 'integer':
$bindType[] = 'i';
break;
case 'double':
$bindType[] = 'd';
break;
case 'blob':
$bindType[] = 'b';
break;
default:
$bindType[] = 's';
break;
}
}
$bindValue[] = $params[$word];
}
$sql = preg_replace($pattern, '?', $sql);
}
$return['sql'] = $sql;
$return['types'] = $bindType;
$return['value'] = $bindValue;
return $return;
}
/*
Функция упрощения запросов к базе данных с поддержкой безопасной подстановки параметров.
Пример работы:
$DataBase->get_result('SELECT * FROM table WHERE code = :code AND (type = :type OR color = ":color")', array(':code' => 1, ':type' => 12, ':color' => 'blue'));
Параметры функции делятся запятой (в данном случае их 2 сам запрос $sql и параметры $params (в случае если нет подставляемых параметров его можно не вписывать).
array(':code' => 1, ':type' => 12, ':color' => 'blue')
Находит значение и заменяется их в запросе. Так code = :code станет code = 1 ... color = ":color" станет color = "blue".
*/
public function get_result($sql, $params = null) //, $types = null
{
if(!empty($params)){
$pattern = '|(:[a-zA-Z0-9_\-]+)|';
if (preg_match_all($pattern, $sql, $matches)) {
$arr = $matches[1];
foreach ($arr as $word) {
if (strlen($word) > 2 && $word[2] == '_') {
$bindType[] = $word[1];
} else {
switch (gettype($params[$word])) {
case 'NULL':
case 'string':
$bindType[] = 's';
break;
case 'boolean':
case 'integer':
$bindType[] = 'i';
break;
case 'double':
$bindType[] = 'd';
break;
case 'blob':
$bindType[] = 'b';
break;
default:
$bindType[] = 's';
break;
}
}
$bindValue[] = $params[$word];
}
$sql = preg_replace($pattern, '?', $sql);
}
}
$stmt = $this->mysqli->prepare($sql) or die(mysqli_error($this->mysqli));
if(!empty($params))$stmt->bind_param(...$bindType, ...$bindValue);
$stmt->execute();
if($stmt->error)die('Ошибка: '.$stmt->error);
$result = $stmt->get_result();
return $result;
}
}