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)
{
// и так далее.
}
Далее пример функции, которые пишутся под конкретный вызов для конкретного раздела. Их хотелось бы выделить в отдельный класс:= '%s' AND `some_field` 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
174 +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 Апр в 13:07
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 84 749 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир