Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/topic.php on line 737
Форумы портала PHP.SU :: PHP в стиле Delphi VCL

 PHP.SU

Программирование на PHP, MySQL и другие веб-технологии
PHP.SU Портал     На главную страницу форума Главная     Помощь Помощь     Поиск Поиск     Поиск Яндекс Поиск Яндекс     Вакансии  Пользователи Пользователи


 Страниц (1): [1]   

> Описание: компаненты доступа к базам данных
eai
Отправлено: 06 Ноября, 2009 - 11:37:47
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 521
Дата рег-ции: Сент. 2009  
Откуда: Петроград


Помог: 10 раз(а)




Написав десяток проектов на LAMP пришел к выводу, что при всей гибкости PHP код не дает прорачности и простоты понимания.

посему написал небольшую обертку по мотивам организации этого дела в VCL

Итого вышло 4 класса
1. DBException - для генерации исключений
2. db - абстаркный класс предок
3. db_mySQL - потомок от db с реализацией методов для mySQL
4. dataset - класс управления набором записей.

Код подключение к базе
PHP:
скопировать код в буфер обмена
  1. $db = new db_mySQL();
  2. $db->set_params($dbhost, $dbname, $dbuser, $dbpasswd, "utf8");
  3. $db->connect();


Для Insert, Delete и Update метод execute
PHP:
скопировать код в буфер обмена
  1. $db->execute("update sometbl set somefld=0 where anotherfld = 'someval'")

Метод execute возвращает количество обработанных записей.

Для Select класс dataset
В стиле PHP (Все же кое что на PHP красивее ;)
PHP:
скопировать код в буфер обмена
  1. $ds = new dataset();
  2. $ds->set_db($db);
  3. $ds->set_sql("SELECT * FROM sometable ");
  4. $ds->open();
  5. while ($ds->movenext())
  6. {
  7.         print $ds->data("somefield") . "<BR>";
  8. }
  9.  


В стиле VCL
PHP:
скопировать код в буфер обмена
  1. $ds = new dataset();
  2. $ds->set_db($db);
  3. $ds->set_sql("SELECT * FROM sometable ");
  4. $ds->open(true);
  5. while (!$ds->EOF())
  6. {
  7.         print $ds->data("somefield") . "<BR>";
  8.         $ds->movenext();
  9. }
  10.  


Отключиться от базы (можно и не делать)


Есть еще небольшой набор вспомогательных методов

Теоретически кроме db_mySQL можно наделсть db_Interbase, db_MSSQL

Вообще странно что не нашел ничего подобного.
Код соотвесвтенно раздаю по запросу (просто куда забросить в хорошее место не знаю)

(Отредактировано автором: 06 Ноября, 2009 - 11:40:53)

 
 Top
Ch_chov
Отправлено: 06 Ноября, 2009 - 12:42:14
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2121
Дата рег-ции: Июль 2008  
Откуда: из города


Помог: 90 раз(а)




Eai объясни чем твоя обертка лучше DbSimple, MDB2 или PDO?
 
 Top
Мелкий Супермодератор
Отправлено: 06 Ноября, 2009 - 13:54:35
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




И заодно чем оно всё лучше стандартных функций mysql_*?
Можно просто кодом.


-----
PostgreSQL DBA
 
 Top
eai
Отправлено: 06 Ноября, 2009 - 14:24:17
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 521
Дата рег-ции: Сент. 2009  
Откуда: Петроград


Помог: 10 раз(а)




Ch_chov пишет:
Eai объясни чем твоя обертка лучше DbSimple, MDB2 или PDO?


не знаю, потому как эти библиотеки не нашел

P.S.
Специаьно и написал так что бы носом тыкать начали Подмигивание
(Добавление)
Мелкий пишет:
И заодно чем оно всё лучше стандартных функций mysql_*?
Можно просто кодом.


Стандартные функции плохо вписываются в ОО модель и код на них получается не прозрачный. Можно и с ними (собственно говоря долго жил и так) но копаться в котде потом сложнее.
Почему на дельфях прямые выовы не испольуются?
Почему вообще необходимо использовать ООП?
Кроме того такая структура поволяет сделать код портабельным между различными SQL серверами Подмигивание
(Добавление)
Ch_chov пишет:
Eai объясни чем твоя обертка лучше DbSimple, MDB2 или PDO?

PDO - что то надо ставить, не камельфо, не везде стоит
DbSimple - интересно, нашел бы раньше испольовал бы, но все же это стиль PHP а не ООП
MDB2 - опять же надо что то инстаировать Недовольство, огорчение, не каждый хостер согласиться

Тут кстати на DbSimple написали

Чем неудобны другие библиотеки
* PEAR DB, ADOdb: библиотеки не упрощают работу с СУБД, они просто предоставляют единый (и многословный) интерфейс; отладочные возможности в зачаточном состоянии.
* PDO: требует PHP 5; неудобная работа с placeholder-ами и результатами выборки.
* Стандартные функции PHP для работы с СУБД: низкая читабельность кода, значительные неудобства в отладке, подверженность уязвимостям вида SQL Injection.

(Отредактировано автором: 06 Ноября, 2009 - 14:36:30)

 
 Top
Мелкий Супермодератор
Отправлено: 06 Ноября, 2009 - 14:40:25
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




eai пишет:
Можно и с ними (собственно говоря долго жил и так) но копаться в котде потом сложнее.

В вашем коде я вижу лишь только псевдонимы стандартных функций. При том столь отчётливые псевдонимы, что возникает вопрос: а в чём разница?

eai пишет:
Кроме того такая структура поволяет сделать код портабельным между различными SQL серверами

Вот только разве что. Но, это надо учитывать уже на этапе создания запросов.

eai пишет:
Почему вообще необходимо использовать ООП?

Необходимо? Ни в коем случае не необходимость. Использовать нужно только наиболее подходящие методы.

eai пишет:
Почему на дельфях прямые выовы не испольуются?

Не знаю, меня объектный паскаль, а тем более де-факто только виндовый, не интересует.


-----
PostgreSQL DBA
 
 Top
eai
Отправлено: 06 Ноября, 2009 - 14:49:11
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 521
Дата рег-ции: Сент. 2009  
Откуда: Петроград


Помог: 10 раз(а)




Мелкий пишет:

eai пишет:
Можно и с ними (собственно говоря долго жил и так) но копаться в котде потом сложнее.

В вашем коде я вижу лишь только псевдонимы стандартных функций. При том столь отчётливые псевдонимы, что возникает вопрос: а в чём разница?


Вот кусок кода от DBSimle
PHP:
скопировать код в буфер обмена
  1. // Обратите внимание на "@"!
  2. // Также по полю id должен быть создан уникальный индекс.
  3. if (!@$DB->query('INSERT INTO tbl(id, field) VALUES(1, ?)', $field)) {
  4.   // Здесь идет реакция на ошибку, если она возникла.
  5.   // Контекст ошибки можно получить через $DB->error.
  6.   $DB->query('UPDATE tbl SET field=? WHERE id=1', $field);
  7. }

Сточки зрения ООП надо было бы задать свойство базе данных, не сообщать об ошибках. В этом случае код становиться более читабельным и понятным.
$DB->IgnoreError = ....
А если серьезно то вообще ошибку в try catch перехватывать

Мелкий пишет:

eai пишет:
Кроме того такая структура поволяет сделать код портабельным между различными SQL серверами

Вот только разве что. Но, это надо учитывать уже на этапе создания запросов.

А не проще ли просто возложить разницу трактовки запросов на обертку?

Мелкий пишет:

eai пишет:
Почему вообще необходимо использовать ООП?

Необходимо? Ни в коем случае не необходимость. Использовать нужно только наиболее подходящие методы.

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

Мелкий пишет:

eai пишет:
Почему на дельфях прямые выовы не испольуются?

Не знаю, меня объектный паскаль, а тем более де-факто только виндовый, не интересует.

Ну не тока виндовый, они делали сие для линукс, но ен пошо в массы, не нашо спроса к сожалению. Они делают уровни абстракции как раз для унификации кода и его легой читаемости. VB тож самое Подмигивание

(Отредактировано автором: 06 Ноября, 2009 - 15:11:27)

 
 Top
Мелкий Супермодератор
Отправлено: 06 Ноября, 2009 - 15:40:48
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




eai пишет:
Страуструп токачто поперхнулся . Идиологический спор. Для сторонников процедурного программирования все что я пишу полная ахинея, им я доказывать ничего ен собираюсь, они просто идут иным путем и все. Все что я написал только для тех кто любит ООП

Я ничего не имею против ООП, наоборот, считаю, что штука полезная, особенно в области разделения видимости и взаимодействия объектов (в том числе с единым интерфейсом и иерархическими описаниями наследований).
Например, относительно GD, ImageMagick весьма удобный класс. Хотя бы тем, что тип файла распознает самостоятельно Улыбка
Но всё на ООП делать - не стоит. А то может echo надо в класс воткнуть и запретить вывод?

eai пишет:
Ну не тока виндовый, они делали сие для линукс, но ен пошо в массы, не нашо спроса к сожалению.

Ну потому и пишу "де-факто" ;) В далёком 2002 (когда выпустили под линуха делфю) году у меня не то, что линуха не стояло, вообще ПК не было Улыбка

eai пишет:
А не проще ли просто возложить разницу трактовки запросов на обертку?

Не очень... Зачем писать кучу кода, который ещё и выполняться будет, отнимая ресурсы, для достаточно постоянной СУБД?

eai пишет:
if (!@$DB->query('INSERT INTO tbl(id, field) VALUES(1, ?)', $field)) {

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

И по самому классу:
Я так понимаю, что конструктор инициализирует соединение с БД по дефолтным значениям, определённым в классе?
А $db->set_params($dbhost, $dbname, $dbuser, $dbpasswd, "utf8"); - просто возможность сделать коннект к другой базе? А почему бы не передавать эти данные сразу конструктору, чтобы класс не создавал дважды соединение?
Почему бы закрытие соединения не вынести в метод __destruct? Тогда будет закрываться самостоятельно. (или я плохо понимаю, когда этот метод вызывается?)
Выбор БД я бы определил тоже по-умолчанию, т.к. в рамках 1 проекта БД меняется не слишком часто и в крайнем можно обратиться к ней по полному имени - т.е. база.таблица.имя_поля


-----
PostgreSQL DBA
 
 Top
eai
Отправлено: 06 Ноября, 2009 - 16:28:00
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 521
Дата рег-ции: Сент. 2009  
Откуда: Петроград


Помог: 10 раз(а)




Мелкий пишет:

Не очень... Зачем писать кучу кода, который ещё и выполняться будет, отнимая ресурсы, для достаточно постоянной СУБД?

Опять же потому что СУБД может меняться и ГЛАВНОЕ для прозрачности кода и его четкой структуры

Мелкий пишет:

Ну потому и пишу "де-факто" ;) В далёком 2002 (когда выпустили под линуха делфю) году у меня не то, что линуха не стояло, вообще ПК не было Улыбка

А знаете сколько с тех пор именилось Подмигивание Достаточно постоянные быза мхом порасли Подмигивание


Мелкий пишет:

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

Ну я же не писал и то что dataset может иметь наседников, а это реально воможно.

Мелкий пишет:

И по самому классу:
Я так понимаю, что конструктор инициализирует соединение с БД по дефолтным значениям, определённым в классе?
А $db->set_params($dbhost, $dbname, $dbuser, $dbpasswd, "utf8"); - просто возможность сделать коннект к другой базе? А почему бы не передавать эти данные сразу конструктору, чтобы класс не создавал дважды соединение?
Почему бы закрытие соединения не вынести в метод __destruct? Тогда будет закрываться самостоятельно. (или я плохо понимаю, когда этот метод вызывается?)
Выбор БД я бы определил тоже по-умолчанию, т.к. в рамках 1 проекта БД меняется не слишком часто и в крайнем можно обратиться к ней по полному имени - т.е. база.таблица.имя_поля

Вообще по уму нужно 2 конструктора, пустой и с параметрами, но к сожалению PHP это не поддерживает. Создайте наседника который имел тот конструктор который вам нужен Подмигивание

Про деструктор, может быть вы и правы, но нужно иметь "насильный" метод тоже
Баа.таблица - плохой вариант, потому что не таблица а запрос!
Кроме того это нарушает принцип абстракции, апрос независит от БД

P.S.
Извиняюсь за орфографию, клавиатура умирает потихоньку Недовольство, огорчение

(Отредактировано автором: 06 Ноября, 2009 - 16:32:19)

 
 Top
Мелкий Супермодератор
Отправлено: 06 Ноября, 2009 - 16:58:29
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




eai пишет:
А знаете сколько с тех пор именилось


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


eai пишет:
Вообще по уму нужно 2 конструктора, пустой и с параметрами, но к сожалению PHP это не поддерживает.

А значения по-умолчанию для чего ещё даны? Это-то как раз не сложно сделать.

eai пишет:
но нужно иметь "насильный" метод тоже

Это не спорю, нужно. Можно даже его же в деструкторе и вызывать. Это просто к тому, что пускай класс сам закрывает соединение, раз уж его можно этому научить Улыбка

eai пишет:
Баа.таблица - плохой вариант, потому что не таблица а запрос!
Кроме того это нарушает принцип абстракции, запрос независит от БД

Да, это не самый верный вариант, но, в некоторых случаях единственный возможный. А в случае класса, реализующего соединение с БД, наоборот, указание БД по-умолчанию, такое же логичное действие, как и указание пользователя, хоста, пароля соединения. Или же, нелогичное, т.к. тогда не видно, куда коннектится и под чьим именем скрипт. Может он под рутовым пользователем сидит в базе?

eai пишет:
Кроме того это нарушает принцип абстракции, апрос независит от БД

А ведь всё равно надо будет шерстить скрипты при изменении имени БД, хоть для указания set_db($db);, хоть для запросов.
Либо, аналогично, тянуть переменную с именем вторичной БД и вставлять это имя в запросы через обычную конкатенацию.


-----
PostgreSQL DBA
 
 Top
eai
Отправлено: 06 Ноября, 2009 - 17:10:53
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 521
Дата рег-ции: Сент. 2009  
Откуда: Петроград


Помог: 10 раз(а)




Мелкий пишет:
А значения по-умолчанию для чего ещё даны? Это-то как раз не сложно сделать.
Это совсем не одно и тоже

Мелкий пишет:
Да, это не самый верный вариант, но, в некоторых случаях единственный возможный. А в случае класса, реализующего соединение с БД, наоборот, указание БД по-умолчанию, такое же логичное действие, как и указание пользователя, хоста, пароля соединения. Или же, нелогичное, т.к. тогда не видно, куда коннектится и под чьим именем скрипт. Может он под рутовым пользователем сидит в базе?

Как это под рутовым, кто его пустил то туда Подмигивание
База по умолчанию нужна, в 90% она еинственная.
По уму в ООП реализуется статическое свойство класса.
В PHP я думаю нужно реалиовать глобальную функцию currentDB().

Мелкий пишет:
А ведь всё равно надо будет шерстить скрипты при изменении имени БД, хоть для указания set_db($db);, хоть для запросов.
Либо, аналогично, тянуть переменную с именем вторичной БД и вставлять это имя в запросы через обычную конкатенацию.

Ну батенька, я про абстракцию иное имел ввиду.
Вот вы содали класс который занимается форматирование вывода, ему скормили dataset (или наследника) и даже не паритесь что а БД. А то что если у вас что то кардинально меняется то код менять придется .. от ентого ничего не избавит Улыбка
 
 Top
Мелкий Супермодератор
Отправлено: 06 Ноября, 2009 - 17:45:02
Post Id



Активный участник


Покинул форум
Сообщений всего: 11926
Дата рег-ции: Июль 2009  
Откуда: Россия, Санкт-Петербург


Помог: 618 раз(а)




eai пишет:
Это совсем не одно и тоже

Поясните, почему не сделать например так:
PHP:
скопировать код в буфер обмена
  1.  
  2. publick function __construct($db = "database1", $host = "localhost", $user="bduser",$passw = "password") {
  3. mysql_connect($host,$user,$passw);
  4. }
  5.  

Или, чтобы не указывать непосредственно в методах имена, можно дать им незначащие значения (например, false) и затем проверить, если передали отличный от дефолтного параметр, то его и использовать. Если нет - взять сохранённый в классе.

eai пишет:
Как это под рутовым, кто его пустил то туда

Это я просто даю пример в другую крайность - класс слишком абстрактен и даже непонятно, с чьими правами скрипт работает Улыбка


-----
PostgreSQL DBA
 
 Top
Ch_chov
Отправлено: 06 Ноября, 2009 - 18:26:02
Post Id



Постоянный участник


Покинул форум
Сообщений всего: 2121
Дата рег-ции: Июль 2008  
Откуда: из города


Помог: 90 раз(а)




Цитата:
PDO: требует PHP 5; неудобная работа с placeholder-ами и результатами выборки.
Eai, там дата 2006-03-03. Т.е. прошло уже 3.5 года.
Сейчас PHP5 это стандарт.
На счёт не удобной работы placeholder-ами и результатами выборки, то это просто мнение.
Имхо, как раз в этом плане в PDO очень даже удобная штука.

Если дело только в объектно-ориентированном стиле, то это поддерживается практически всеми известными библиотеками для работы с БД, включая MySQLi.

Цитата:
Вообще странно что не нашел ничего подобного.

Погляди здесь, найдешь пару сотен подобных. Радость
 
 Top
eai
Отправлено: 09 Ноября, 2009 - 08:04:53
Post Id



Частый посетитель


Покинул форум
Сообщений всего: 521
Дата рег-ции: Сент. 2009  
Откуда: Петроград


Помог: 10 раз(а)




[quote=Ch_chov]
Цитата:

Погляди здесь, найдешь пару сотен подобных. Радость


Спасибо Улыбка
 
 Top
Champion Супермодератор
Отправлено: 09 Ноября, 2009 - 09:02:42
Post Id



Активный участник


Покинул форум
Сообщений всего: 4350
Дата рег-ции: Авг. 2008  
Откуда: Москва


Помог: 57 раз(а)




По-моему, штука удобная для использования в своих проектах. А для массы - очередной велосипед. Я вот вобще не понимаю, зачем работу с БД делать в ООП. Коннект вынес в отдельный файлик и всё. А все эти обертки на выполнение запросов не нужны совсем.
 
 Top
Страниц (1): [1]
Сейчас эту тему просматривают: 0 (гостей: 0, зарегистрированных: 0)
« SQL и Архитектура БД »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 



Powered by PHP  Powered By MySQL  Powered by Nginx  Valid CSS  RSS

 
Powered by ExBB FM 1.0 RC1. InvisionExBB