Отделение кода от функциональности БД

Я разрабатываю объектно-ориентированный веб-сайт на 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), который передается в функцию запроса БД? Этот метод также может помочь с безопасностью, поскольку он ограничит запросы, которые могут быть запущены, только теми, которые зарегистрированы в этом списке, но это еще одна вещь, которую следует помнить при написании всех функций класса. Мысли?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
8
0
415
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Разделение SQL на отдельные функции - хорошее начало. Еще кое-что, что вы можете сделать:

  • Создайте отдельные классы для кода доступа к базе данных. Это поможет убедиться, что у вас нет функций SQL, разбросанных по всем вашим файлам PHP.
  • Загрузите SQL из внешних файлов. Это полностью разделяет ваш код SQL и код PHP, что делает их более удобными в обслуживании.
  • По возможности используйте хранимые процедуры. Это полностью удаляет SQL из вашего кода PHP и помогает повысить безопасность вашей базы данных за счет снижения риска выполнения внешнего SQL.

Разве хранимым процедурам не требуются встроенные операторы SQL для их выполнения, поскольку они существуют только в базе данных? Или я не понимаю, что вы имеете в виду, когда говорите использовать хранимые процедуры?

cmptrgeekken 13.11.2008 06:52

На самом деле MySQL просто добавил хранимые процедуры, и я читал, что синтаксис не такой гибкий, как в SQL Server. ИМО, хранимые процедуры действительно бесполезны, если вам не нужно писать обширный или сложный запрос.

Kevin 13.11.2008 07:03

Вы вызываете хранимые процедуры с вызовом функции, передавая имя и параметры запроса. macronimous.com/resources/…

Bill the Lizard 13.11.2008 07:09

Хороший ответ Билл. Мне нравятся все перечисленные подходы.

Mat Nadrofsky 13.11.2008 19:51

Возможно, вы захотите изучить реализацию Шаблон ActiveRecord. Использование такого шаблона проектирования обеспечивает некоторую последовательность в работе с данными из таблиц. У такого рода подходов могут быть некоторые недостатки, в основном производительность для определенных типов запросов, но это можно обойти.

Я полагаю, что одним из преимуществ использования такого типа шаблона будет то, что вы можете использовать ту же структуру для представления запросов и не беспокоиться о синтаксисе, специфичном для базы данных, при генерации вашего SQL, тем самым добавляя еще один уровень абстракции.

cmptrgeekken 13.11.2008 06:57

Другим вариантом может быть использование ORM, наиболее мощными для PHP являются:

Оба позволяют получить доступ к базе данных с помощью набора объектов, предоставляя простой API для хранения и запроса данных, оба имеют свой собственный язык запросов, который внутренне преобразуется в собственный SQL целевой СУБД, что упростит миграцию приложений с одной СУБД на другой с простыми изменениями конфигурации. Мне также нравится тот факт, что вы можете инкапсулировать логику модели данных для добавления проверки, например, только путем расширения классов вашей модели.

Если вы говорите, что делаете это как OO PHP, то почему у вас вообще SQL разбросан по всем методам? Более распространенные модели:

  1. Используйте ORM и позвольте ему обрабатывать базу данных.
  2. Предоставьте своим классам один или несколько методов загрузки, которые используют один запрос для извлечения всех данных объекта в память, и метод сохранения, который использует один запрос для обновления всего в базе данных. Все остальные методы должны выполнять только операции в памяти, а взаимодействия с базой данных ограничиваются методами загрузки / сохранения.

Первый вариант, как правило, будет более надежным, но второй может работать быстрее и, вероятно, будет казаться более знакомым по сравнению с тем, как вы привыкли делать что-то, если любой из этих вариантов вызывает беспокойство.

Для вашего примера входа в систему я бы сделал это, просто загрузив пользователя по адресу электронной почты, позвонив $user->check_password($entered_password) и выбрасывая исключение / возвращая false / что угодно, если check_password терпит неудачу. Ни check_password, ни какой-либо код обработки входа в систему не должны заботиться о базе данных или даже о том, что база данных - это то место, откуда пользователь загружается.

Другой вариант - рассматривать запросы как данные и сохранять их в базе данных. Например, вы можете создать одну таблицу, в которой будет храниться запрос с именем, и другую таблицу, в которой будут храниться параметры этого запроса. Затем создайте функцию в PHP, которая принимает имя запроса и массив параметров и выполняет запрос, возвращая любые результаты. Вы также можете присоединять к запросам другие метаданные, чтобы ограничить доступ для определенных пользователей, применить пост-функции к результатам и т. д.

Другие вопросы по теме