PHP. Как грамотно создать дополнительный класс (ООП) для «конкретных» select'ов для работы с БД? Есть в модели класс работы с бд с синглтоном (назовём его M_MSQLI). Синтаксис используется "классический" с обёртыванием данных $this->mysqli->real_escape_string() перед вставкой в запрос.
Кроме общих стандартных функций в нём есть пачка "одноразовых" функций Select'ов, которые используются только в одном разделе сайта. Чтобы каждый раз не прогружать весь зоопарк функций, хочется выделить функции со "специальными" запросам в отдельный класс, который будет прокладкой между моделью и бд (назовём его M_MSQLI_SELECT). Вот тут и возникает вопрос как грамотно это сделать.
Итак, внимание, вопрос:
Каким образом оптимально и правильно вызвать соединение с БД в классе M_MSQLI_SELECT, чтобы использовать real_escape_string() в функциях этого класса, если учесть, что он использует некоторые функции класса M_MSQLI?
Варианты, которые посещали мои пэхэпэхнутые извилины:Вариант[0]. Наследование: Полистав гугл и тостер, стало понятно, что наследовать новый класс от M_MSQLI моветон и не есть гуд.
Огорчает еще то, что при этом придётся изменить область видимости свойства $mysqli (с private на protected), знаний оценить насколько это чревато не хватает, но ощущение, что не стоит этого делать есть.Вариант[1]. Новое подключение к БД в доп.классе: Заново вызвать в конструкторе класса M_MSQLI_SELECT подключение к БД и в функциях обращаться к нему.
Тут возникает вопрос: проблема ли, что при обращении M_MSQLI_SELECT к M_MSQLI подключение будет создаваться повторно? Или это нормально?Вариант[2]. Использование класса M_MSQLI как объект: В этом случае вообще придётся забыть об инкапсуляции и все требуемые свойства и функции делать публичными. Тут уже никаких "ощущений" нет - это явно лишнее.Вариант[3]. Копипаст: Можно просто скопировать класс M_MSQLI в M_MSQLI_SELECT, добавить в последний специальные запросы и обращаться к нему только по необходимости. Но - дублирование кода и прочие неприятности. Поэтому не хотелось бы.
Не судите строго, это мой первый вопрос поcле освоения php. Буду признателен, если укажите на ошибки в соображениях, поделитесь подходящей ссылкой или подскажите в каком направлении копать. Что смог найти по теме - прочитал, кстати, спасибо FanatPHP за развёрнутые комментарии на тостере и терпение, были очень кстати!
Как выглядит класс M_MSQLI (кусок, далее аналогично стандартные функции для работы):mysqli = new mysqli(M_dbconfig::DB_HOST,
M_dbconfig::DB_USER,
M_dbconfig::DB_PASS,
M_dbconfig::DB_NAME);
// Назначение кодировки
$this->mysqli->query('SET NAMES utf8');
// Установка внутренней кодировки в UTF-8
mb_internal_encoding("UTF-8");
}
// Далее идут общие функции.

// Выборка строк (внутренняя функция)
// $query - полный текст SQL запроса
// результат - массив выбранных объектов $arr
private function Select($query)
{
// Запрос к БД
$result = $this->mysqli->query($query);

// Проверка на успешный результат
if ($this->mysqli->error) {...}
// Создаём массив для конечного результата
$arr = array();
// Извлекаем ряд таблицы в виде ассоциативного массива. Цикл повторяется пока строки есть
while ($row = $result->fetch_assoc())
$arr[] = $row; // Помещаем извлеченные ряды в общий массив
// Возвращаем полученный общий массив
return $arr;
}

// Вставка строки
// $table - имя таблицы
// $object - ассоциативный массив с парами вида "имя столбца - значение"
// результат - идентификатор новой строки ($this->mysqli->insert_id)
public function Insert($table, $object)
{
// Создаём массив для столбцов куда будем вставлять новое значение
$columns = array();
// Создаём массив для значений которые будем вставлять
$values = array();

// Разбираем массив с данными по столбцам. array('title' => '1223', 'content' => 'dadsd')
foreach ($object as $column => $value)
{
// Экранируем специальные символы в названии столбца
$column = $this->mysqli->real_escape_string($column);

// Добавляем каждый столбец в массив столбцов
$columns[] = "`$column`";

// Записываем нулы пустых значений, чтобы длины значений и столбцов были равны
if ($value === NULL)
{
// Добавляем значение в массив значений
$values[] = "''";
}
else
{
// Экранируем специальные символы в значении
$value = $this->mysqli->real_escape_string($value);

// Добавляем каждое значение в массив значений
$values[] = "'$value'";
}
}
// Собираем столбцы в строку
$columns_s = implode(', ', $columns);
// Собираем значения в строку
$values_s = implode(', ', $values);
// Маска запроса
$sql =
"INSERT INTO `%s` (%s)
VALUES (%s)";
// Экранируем и форматируем переменные в запросе
$query = sprintf($sql,
$this->mysqli->real_escape_string($table),
$columns_s,
$values_s);
// Запрос к БД
$result = $this->mysqli->query($query);
// Проверка на успешный результат
if ($this->mysqli->error) {...}

// Возвращаем индификатор новой строки
return $this->mysqli->insert_id;
}

// Изменение строк
// $table - имя таблицы
// $object - ассоциативный массив с парами вида "имя столбца - значение"
// $where_column - имя столбца для WHERE (часть SQL запроса)
// $where_value - значение столбца для WHERE (часть SQL запроса)
// результат - число измененных строк ($this->mysqli->affected_rows)
public function Update($table, $object, $where_column, $where_sign, $where_value)
{
// аналогичный код.
}

// Удаление строк
// $table - имя таблицы
// $where_column - имя столбца для WHERE (часть SQL запроса)
// $where_value - значение столбца для WHERE (часть SQL запроса)
// результат - число удаленных строк ($this->mysqli->affected_rows)
public function Delete($table, $where_column, $where_sign, $where_value)
{
// и так далее.
}

// Количество строк в таблице
// $table - имя таблицы
// результат - число строк из массива
public function Count($table)
{
// и так далее.
}
Далее пример функции, которые пишутся под конкретный вызов для конкретного раздела. Их хотелось бы выделить в отдельный класс:mysqli->real_escape_string($var1),
$this->mysqli->real_escape_string($var2),
$this->mysqli->real_escape_string($id));
// Подготавливаем результат запроса в метод M_MSQLI
$result = $this->Select($query);
// Возращаем массив
return $result;
}

21 Авг 2019 в 07:06
212 +1
0
Ответы
1

Для создания дополнительного класса M_MSQLI_SELECT, который будет работать с конкретными select'ами для работы с БД и использует функции класса M_MSQLI, можно использовать следующий подход:

Передайте экземпляр класса M_MSQLI в конструктор класса M_MSQLI_SELECT. Это позволит использовать объект M_MSQLI внутри класса M_MSQLI_SELECT для вызова функций класса M_MSQLI, таких как real_escape_string().

Пример кода для класса M_MSQLI_SELECT:

class M_MSQLI_SELECT
{
private $msqli_instance;
public function __construct($msqli_instance)
{
$this->msqli_instance = $msqli_instance; // передача экземпляра класса M_MSQLI
}
// Функция для выполнения специального select запроса
public function SelectSomethingUnusual($var1, $var2, $id)
{
$sql = "SELECT * FROM `table` WHERE `var1` = '%s' AND `var2` = '%s' AND `id` = '%s'";
$query = sprintf($sql,
$this->msqli_instance->real_escape_string($var1),
$this->msqli_instance->real_escape_string($var2),
$this->msqli_instance->real_escape_string($id));
// Вызов функции Select из класса M_MSQLI
$result = $this->msqli_instance->Select($query);
return $result;
}
}При создании экземпляра класса M_MSQLI_SELECT передайте в конструктор объект M_MSQLI, который был создан из синглтона.

Пример использования классов:

// Получаем экземпляр класса M_MSQLI через синглтон
$msqli_instance = M_MSQLI::Instance();
// Создаем экземпляр класса M_MSQLI_SELECT с передачей объекта M_MSQLI
$msqli_select = new M_MSQLI_SELECT($msqli_instance);
// Вызываем функцию SelectSomethingUnusual
$results = $msqli_select->SelectSomethingUnusual($var1, $var2, $id);

Таким образом, вы сможете использовать класс M_MSQLI_SELECT для выполнения специфических select запросов к БД, используя функции класса M_MSQLI, включая real_escape_string(). Главное, чтобы экземпляр M_MSQLI был передан в конструктор M_MSQLI_SELECT для использования его функций.

20 Апр 2024 в 13:07
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир