Я разрабатываю объектно-ориентированный веб-сайт на PHP прямо сейчас и пытаюсь определить лучший способ абстрагировать функциональность базы данных от остальной системы. Прямо сейчас у меня есть класс DB, который управляет всеми подключениями и запросами, которые использует система (это в значительной степени интерфейс для MDB2). Однако при использовании этой системы я понял, что в моем коде повсюду появляется множество строк SQL-запросов. Например, в моем классе User у меня есть что-то вроде этого:
function checkLogin($email,$password,$remember=false){
$password = $this->__encrypt($password);
$query = "SELECT uid FROM Users WHERE email=? AND pw=?";
$result = $this->db->q($query,array($email,$password));
if (sizeof($result) == 1){
$row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
$uid = $row['uid'];
}else{
return false;
}
/* Rest of the login script */
}
Я хотел бы найти лучший способ уменьшить количество встроенного SQL. Я понимаю, что один из способов сделать это - написать функции в User для каждого из запросов, которые использует User (что-то вроде следующего), но это может привести к довольно большому количеству функций.
function checkLogin($email,$password,$remember=false){
$password = $this->__encrypt($password);
$uid = $this->do_verify_login_query($email,$password);
/* Rest of the login script */
}
function do_verify_login_query($email,$encpw){
$query = "SELECT uid FROM Users WHERE email=? AND pw=?";
$result = $this->$db->q($query,array($email,$encpw));
if (sizeof($result) == 1){
$row = $result->fetchRow(MDB2_FETCHMODE_ASSOC);
return $row['uid'];
}else{
return false;
}
}
Итак ... мой вопрос. Каков наилучший метод управления большим количеством запросов, который может использовать типичное приложение базы данных? Будет ли описанный мною способ справиться с этой ситуацией надлежащим образом? Или как насчет регистрации списка запросов в классе БД и связывания с каждым уникальным идентификатором (например, USER_CHECKLOGIN), который передается в функцию запроса БД? Этот метод также может помочь с безопасностью, поскольку он ограничит запросы, которые могут быть запущены, только теми, которые зарегистрированы в этом списке, но это еще одна вещь, которую следует помнить при написании всех функций класса. Мысли?






Разделение SQL на отдельные функции - хорошее начало. Еще кое-что, что вы можете сделать:
На самом деле MySQL просто добавил хранимые процедуры, и я читал, что синтаксис не такой гибкий, как в SQL Server. ИМО, хранимые процедуры действительно бесполезны, если вам не нужно писать обширный или сложный запрос.
Вы вызываете хранимые процедуры с вызовом функции, передавая имя и параметры запроса. macronimous.com/resources/…
Хороший ответ Билл. Мне нравятся все перечисленные подходы.
Возможно, вы захотите изучить реализацию Шаблон ActiveRecord. Использование такого шаблона проектирования обеспечивает некоторую последовательность в работе с данными из таблиц. У такого рода подходов могут быть некоторые недостатки, в основном производительность для определенных типов запросов, но это можно обойти.
Я полагаю, что одним из преимуществ использования такого типа шаблона будет то, что вы можете использовать ту же структуру для представления запросов и не беспокоиться о синтаксисе, специфичном для базы данных, при генерации вашего SQL, тем самым добавляя еще один уровень абстракции.
Другим вариантом может быть использование ORM, наиболее мощными для PHP являются:
Оба позволяют получить доступ к базе данных с помощью набора объектов, предоставляя простой API для хранения и запроса данных, оба имеют свой собственный язык запросов, который внутренне преобразуется в собственный SQL целевой СУБД, что упростит миграцию приложений с одной СУБД на другой с простыми изменениями конфигурации. Мне также нравится тот факт, что вы можете инкапсулировать логику модели данных для добавления проверки, например, только путем расширения классов вашей модели.
Если вы говорите, что делаете это как OO PHP, то почему у вас вообще SQL разбросан по всем методам? Более распространенные модели:
Первый вариант, как правило, будет более надежным, но второй может работать быстрее и, вероятно, будет казаться более знакомым по сравнению с тем, как вы привыкли делать что-то, если любой из этих вариантов вызывает беспокойство.
Для вашего примера входа в систему я бы сделал это, просто загрузив пользователя по адресу электронной почты, позвонив $user->check_password($entered_password) и выбрасывая исключение / возвращая false / что угодно, если check_password терпит неудачу. Ни check_password, ни какой-либо код обработки входа в систему не должны заботиться о базе данных или даже о том, что база данных - это то место, откуда пользователь загружается.
Другой вариант - рассматривать запросы как данные и сохранять их в базе данных. Например, вы можете создать одну таблицу, в которой будет храниться запрос с именем, и другую таблицу, в которой будут храниться параметры этого запроса. Затем создайте функцию в PHP, которая принимает имя запроса и массив параметров и выполняет запрос, возвращая любые результаты. Вы также можете присоединять к запросам другие метаданные, чтобы ограничить доступ для определенных пользователей, применить пост-функции к результатам и т. д.
Разве хранимым процедурам не требуются встроенные операторы SQL для их выполнения, поскольку они существуют только в базе данных? Или я не понимаю, что вы имеете в виду, когда говорите использовать хранимые процедуры?