как отделить sql от кода php

У меня есть класс, который помогает мне обращаться с пользователями. Например:

$user = new User("login","passw");
$name = $user->getName();
$surname = $user->getSurname();
$table = $user->showStats();

Внутри всех этих методов есть SQL-запросы. Для некоторых действий требуется только один sql-запрос, для некоторых - более одного. Если структура базы данных изменится - все запросы будет сложно изменить (класс длинный). Поэтому я решил держать SQL-запросы подальше от этого класса. Но как это сделать?

Прочитав этот вопрос, я узнал о хранимых процедурах. Означает ли это, что теперь для одного действия требуется только один SQL-запрос (вызов хранимой процедуры)? Но как организовать отделение sql от php? Стоит ли хранить sql-запросы в массиве? А может быть это должен быть класс sql-запросов. Если да, то как организовать этот класс (возможно, какой шаблон мне следует изучить)


person Larry Cinnabar    schedule 08.05.2011    source источник
comment
Если ваша схема базы данных изменится, вы будете вынуждены изменить код, который отображает эту схему на PHP. Нет волшебной пыли, которая сделает это автоматически. В этом случае хранимые процедуры ничего не меняют, потому что затем вы переносите проблему на необходимость редактирования хранимых процедур.   -  person Jon    schedule 08.05.2011
comment
@Jon: Как могло произойти разделение. Я имею в виду, что изменение не произойдет в один момент, но если вам придется просмотреть каждый файл PHP, это может быть исчерпывающим.   -  person Shamim Hafiz    schedule 08.05.2011
comment
@Jon, я понимаю это. Но если у меня есть sql-запросы внутри PHP-кода, и это около 2k строк кода (но sql-запросы составляют около сотни строк), вы будете прокручивать свой код и можете пропустить некоторые sql-запросы. Но если у вас есть файл (класс или массив) только с sql-запросами - их проще изменить   -  person Larry Cinnabar    schedule 08.05.2011
comment
Если код хорошо структурирован, у вас действительно не будет такой проблемы. Если каждый метод просто выполняет свой жестко запрограммированный SQL, то проблема наверняка возникнет.   -  person Jon    schedule 08.05.2011


Ответы (4)


Это на удивление обширная тема, но у меня есть несколько советов, которые помогут вам в пути:

Вам следует изучить объектно-реляционное сопоставление, при котором объект автоматически генерирует SQL-запросы. Взгляните на объектно-реляционное сопоставление и Active Record. Это позволит сохранить минимальный объем кода базы данных и упростить задачу при изменении структуры таблицы.

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

В любом случае, какой бы метод вы ни выбрали, я рекомендую вам хранить логику базы данных в нескольких классах «Модель». Похоже, вы уже делаете что-то подобное. Основная идея состоит в том, что каждая модель инкапсулирует логику для определенной области базы данных. Традиционно каждая модель сопоставляется с одной таблицей в БД - так работает класс активной записи Ruby on Rails. Это хорошая стратегия, поскольку она разбивает логику вашей базы данных на простые маленькие «куски». Если вы сохраните всю логику запросов к базе данных в одном файле, она может быстро выйти из-под контроля и превратиться в кошмар обслуживания - поверьте мне, я был там!

Чтобы лучше понять «общую картину», я рекомендую вам потратить некоторое время на чтение веб-архитектуры модель-представление-контроллер (MVC). Вы также захотите ознакомиться с установленными фреймворками PHP MVC, такими как CodeIgniter, Kohaha, CakePHP и т. д. Даже если вы не используете один - хотя я рекомендую вам это сделать - было бы полезно посмотреть, как эти фреймворки организуют ваш код.

person Justin Ethier    schedule 08.05.2011

Я бы сказал, что вам следует изучить возможность реализации шаблона проектирования «репозиторий» в вашем коде.

Хороший ответ на вопрос, как это реализовать, будет слишком длинным для этого места, поэтому я опубликую пару ссылок на PHP:

travis swicegood - шаблон репозитория в PHP

Джон Лебенсольд - шаблон репозитория в PHP

person Faust    schedule 08.05.2011

Вы на правильном пути, если используете разделение задач, чтобы отделить бизнес-логику от доступа к данным. логика тебе будет в лучшем месте.

person amelvin    schedule 08.05.2011
comment
Есть ссылки на изучение того, как это должно быть сделано с PHP и MySQL? - person Shamim Hafiz; 08.05.2011
comment
У меня есть разделение php и html, но как насчет php и sql? - person Larry Cinnabar; 08.05.2011
comment
@Innuendo Если вы разделите весь свой код доступа к данным на группу классов доступа к данным (так, чтобы они были отделены от кода бизнес-логики), ваши бизнес-классы могут затем вызывать их для создания, чтения, обновления или удаления данных. Как и все хорошие шаблоны, это работает практически для любого языка высокого уровня. Мне нравится использовать хранимые процедуры, но независимо от того, используете ли вы хранимые процедуры или параметризованный sql, встроенный в классы доступа к данным, более важной отправной точкой является разделение доступа к sql. - person amelvin; 08.05.2011
comment
Разделение функций @Gunner не является специфической для языка концепцией - оно работает для всех языков высокого уровня. Но это IBM разделяет обязанности в php - ibm.com / developerworks / opensource / library / os-php-objectorient. - person amelvin; 08.05.2011

Судя по вашему утверждению «уже есть 2К строк кода», вы либо что-то поддерживаете, либо что-то разрабатываете на полпути.

И Фауст, и Джастин Этье дают хорошие рекомендации: «как мне отделить доступ к базе данных от кода приложения» - это один из старейших и наиболее часто задаваемых вопросов в веб-разработке.

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

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

В любом случае, вам нужно прочитать о рефакторинге - добраться от того места, где вы находитесь, к тому месту, где вы хотите быть, будет непросто. Для начала рекомендую книгу Фаулера.

Не могли бы вы подробнее объяснить, почему схема вашей базы данных может измениться? Обычно это означает, что впереди неприятности ...

person Neville Kuyt    schedule 08.05.2011
comment
Это мой первый большой проект. Был написан код php (от бывшего программиста) - ужасный код (html + php + sql в нескольких файлах). Я выбросил этот код и написал новую разметку html и код php (без html внутри - с движком шаблонов). Но база данных очень большая и беспорядочная (mysql db + pgsql db с отношениями между ними), и я слышал, что новый программист базы данных хочет переписать всю базу данных. Так что в ближайшее время мне придется изменить все запросы = ( - person Larry Cinnabar; 08.05.2011
comment
тогда я определенно посмотрю, сможете ли вы перейти на платформу MVC - хорошие новости о таких вещах, как CakePHP и т. д., заключаются в том, что они забирают у вас большую часть кода физического доступа к базе данных. Плохая новость в том, что они не вносят изменений в схему базы данных лучше, чем любой другой фреймворк ... - person Neville Kuyt; 08.05.2011
comment
Да, я понимаю - переход на MVC - это мой путь (я уже читал о MVC и заглядывал в сторону Zend Framework). Но мне некогда изучать это (именно для этого проекта, для следующего - успею =)). Русский бизнес - дают плохой код, просят переписать или написать новый, а времени очень мало =) - person Larry Cinnabar; 09.05.2011