Создал класс (ООП PHP5) для работы с БД MySQL - покритикуйте, похвалите

Volmir

Новичок
Создал класс (ООП PHP5) для работы с БД MySQL - покритикуйте, похвалите

Создал класс (ООП PHP5) для работы с БД MySQL - покритикуйте или похвалите.

Интересует, можно ли использовать его в проектах с средней и высокой посещаемостью (нет ли в нем каких-либо неточностей, внутренних ошибок и т.п.)?
наколько корректным и "правильным" вы считаете код данного класса с точки зрения PHP5 ООП?

Так же интересует, надо ли закрывать соединение с БД MySQL 5.XX в конце PHP-скрипта (mysql_close)? Или это и так произойдет автоматически?

И еще вопрос по классу: надо ли в конце, в деструкторе класса делать unset() для всех внутренних переменных класса? Или это (освобождение памяти и ресурсов системы) будет происходить автоматически по завершению работы php-скрипта и на производительности не скажется (имеется в виду использование на проектах с средней и большой посещаемостью, от 20000 уникальных посетителей в сутки, 4-5 хитов на 1-го посетителя).

Так же из "вкусностей" в классе реализован подсчет количества прошедших через него запросов (и запоминание их SQL). В debug режиме, конечно. Для отлавливания "медленных" запросов (хорошо было бы еще и время их выполнения записывать!).

А так класс составлен из минимума необходимых функций и синтаксис работы с ним ориентирован на "похожесть" работы с родными MySQL-функциями PHP.


Собственно адрес залитого архива с классом, примерами для его использования и дампом базы данных (для удобства тестирования):
http://slil.ru/28010620
 

fixxxer

К.О.
Партнер клуба
>Так же интересует, надо ли закрывать соединение с БД MySQL 5.XX в конце PHP-скрипта (mysql_close)? Или это и так произойдет автоматически?

[m]mysql_close[/m]

>надо ли в конце, в деструкторе класса делать unset() для всех внутренних переменных класса?

не надо

>Собственно адрес залитого архива с классом

всем лень качать и распаковывать, хочешь отзывов, выложи так, чтобы читать можно было одним кликом
 

DiMA

php.spb.ru
Команда форума
и че там, тока класс? Нафиг надо. Приведи для начала прямо здесь кучу примеров использования. Этого уже хватит для вагона крикити .-)
 

Volmir

Новичок
всем лень качать и распаковывать, хочешь отзывов, выложи так, чтобы читать можно было одним кликом
PHP:
class Db {

private $host = 'localhost';
private $username = 'root';
private $pass = '';
private $dbname = 'test';

private $result;
private $currentindex;
private $query;

public $debug = 0;
public $queries = array();


function connect() {
    if (!@mysql_pconnect($this->host, $this->username, $this->pass)) {
        echo $this->error();
        return FALSE;
    }

    if (!@mysql_select_db($this->dbname)) {
        echo $this->error();
        return FALSE;
    }
}

function query($query) {
    if ($this->debug) {
        $this->queries[] = $query;
    }

    $res = @mysql_query($query);
    if (!$res) {
        echo "Error: " . $this->error() . "<br />
              Query: <b>" . $query . "</b><br />";
        return 0;
    }

    if (eregi("^select", trim($query))) {
        $result = array();
        //while ($row = mysql_fetch_array($res)) {
        while ($row = mysql_fetch_assoc($res)) {
            $result[] = $row;
        }

        $this->result = $result;
        $this->currentindex = 0;
        $this->query = $query;

        return $res;
    } else {
        return $res;
    }
}

function fetch_array() {
    if ($this->currentindex >= sizeof($this->result)) {
        return ;
    } else {
        $this->currentindex++;
        return $this->result[($this->currentindex - 1)];
    }
}

function fetch_assoc()  {
    return $this->fetch_array();
}

function result($index, $field) {
    if ($index < 0 || $index >= sizeof($this->result)) {
        echo "DB error: " . $index . ": no such index (query: <b>" . $this->query . "</B>).";
        return ;
    }
    return $this->result[$index][$field];
}

function numrows() {
    return sizeof($this->result);
}

function error() {
    return mysql_error();
}

function insert_id() {
    return mysql_insert_id();
}

}
-~{}~ 23.09.09 22:16:

Пример использования данного класса.


PHP:
$db = new db();
$db->connect();
$db->debug = 1;



//-------- SELECT -------//
$sql = "SELECT * FROM news";
$result = $db->query($sql);
//$numrows = $db->numrows();
//echo $numrows . "<br />";
if ($db->numrows()) {
    while ($row = $db->fetch_array()) {
        print_r($row);
    }
}

//-------- UPDATE -------//
$sql = "UPDATE news SET nid=3 WHERE nid=3";
$result = $db->query($sql);

//-------- INSERT + LAST_INSERT_ID -------//
$sql = "INSERT INTO news (nid, dt, title, full_text)
        VALUES ('', NOW(), 'Example title', 'Example text')";
$result = $db->query($sql);
echo 'LAST_INSERT_ID = ' . $db->insert_id() . "<br />";

//-------- DELETE -------//
$sql = "DELETE FROM arg_news WHERE nid=5";
$result = $db->query($sql);

//------- DEBUG, show count of queries, list of all queries ----------
if ($db->debug && is_array($db->queries)) {
    echo "Count of queries: " . count($db->queries) . '<br />';
    foreach ($db->queries as $key=>$val) {
        echo $val . '<br />';
    }
}
 

varan

Б̈́̈̽ͮͣ̈Л̩̲̮̻̤̹͓ДͦЖ̯̙̭̥̑͆А͇̠̱͓͇̾ͨД͙͈̰̳͈͛ͅ
1) Класс почти ничего не делает.
2) ооп здесь почти нет
3) параметры доступа к базе хранятся прямо в классе, что исключает его нормальное использование
4) eregi - deprecated
 

DiMA

php.spb.ru
Команда форума
ооп здесь не почти, а вообще нет, это обычный процедурный подход

к примеру, как выполнить сначала 2 инсерта, а потом получить оба insert_id?

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

Volmir

Новичок
Автор оригинала: DiMA
ооп здесь не почти, а вообще нет, это обычный процедурный подход
.
На ООП я начал переходить вот только что, в недавнее время.
Пробую писать разные классы, разбираюсь с мануалами и учебниками.
А так до этого - только процедурный подход ...

Для начала надо изменить тип мышления, с процедурного, на объектный (это я так себе представляю процедуру перехода).
А вообще, многие вещи в ООП таки делать легче и получается понятней и удобней (до этого я критиковал ООП, как излишне "навороченную" методику программирования).


к примеру, как выполнить сначала 2 инсерта, а потом получить оба insert_id?
Да, действительно... Как? :)
Типа, "качай PEAR DB смотри исходники и разбирайся"?!
 

Beavis

Banned
Да, класс вообще ни о чем) Просто обертка над стандартными функциями, причем АБСОЛЮТНО ненастраиваемая, т.е код класса надо будет постоянно редактировать.
 

Volmir

Новичок
Автор оригинала: varan
1) Класс почти ничего не делает.
2) ооп здесь почти нет
3) параметры доступа к базе хранятся прямо в классе, что исключает его нормальное использование
4) eregi - deprecated
Ответы по пунктам
1 - согласен, но я его таким и задумывал - быстрым и маленьким по объему. А чем еще можно дополнить класс? Проверкой на запрещенные символы в SQL или разбором и подстановкой значений отдельно от тела запроса (placeholder, пример: $DB->select('SELECT name FROM tbl WHERE id IN(?a)', $ids);)

2 - ну хоть чуть-чуть есть? :)

3 - это для теста, собираюсь написать конфиг (чтение значений через parse_ini_file()) и передавать параметры при соединении с БД.

4 - да, таки надо делать 2 отдельные функции (одну - для SELECT, другую - для остальных запросов, в которых не надо возвращать данные)
И еще одну - для возвращения единичного значения отдельного столбца (иногда нужно получить отдельное значение из таблицы)

-~{}~ 23.09.09 23:12:

Автор оригинала: Beavis
Да, класс вообще ни о чем) Просто обертка над стандартными функциями.
А куда тогда смотреть? Какие приоритеты есть для класса работы с БД (если он задумывается не только как "обертка"-"прослойка")?
 

whirlwind

TDD infected, paranoid
Volmir смотри, любой класс должен позволять абстрагироваться до определенного уровня. Если это например доступ к данным, то он должен абстрагировать как минимум для элементарных атомарных типов данных. Если в случае с БД атомарный тип = record, то и результат должен быть соответственно абстрактным record set. Если в record каждый элемент может приводиться к базовому типу, то и обращение к ним должно быть через интерфейс. Эти абстракции позволяют тебе рассматривать представление одних сущностей через другие. Ну или трансформировать сущности друг в друга. Например User с конкретными атрибутами трансформировать в record и передать его классу БД. И наоборот - record полученный от БД, трансформировать в атрибуты класса User. Вот это и есть абстракция - логический срез, где сущности пересекаются через состояния.
 

zerkms

TDD infected
Команда форума
whirlwind
а должен? это не генератор запросов, а интерфейс доступа к субд.
 

r4sh

Новичок
я думаю что zerkms имел ввиду использование PDO как базы вместо стандартной библиотеки mysql :)
 

whirlwind

TDD infected, paranoid
к субд или к субд конкретного вендора? если я в датамаппере буду дрочиться с кодом для разных вендоров субд, то нахер мне такой dbal?
 

zerkms

TDD infected
Команда форума
whirlwind
нахер мне такой dbal?
чтобы при использовании в проекте 10 разных субд у тебя был единообразный интерфейс, а не тонна mysql_query, mssql_query, и прочие oci_

я думаю что zerkms имел ввиду использование PDO как базы вместо стандартной библиотеки mysql
я говорил о PDO как об адекватной альтернативе поделке автора (http://phpclub.ru/talk/showthread.php?postid=872030#post872030)
 

r4sh

Новичок
В таком случае можно не использовать драйверы для разных БД (postgre, mysql), которые как помню имеют довольно различный интерфейс, что не удобно, а использовать в DataMapper PDO. Плюс PDO хотя бы исключения умеет выбрасывать. Что тоже несомненно удобно.
 

whirlwind

TDD infected, paranoid
лучше вот этой "поделки" http://creole.phpdb.org/trac/ я еще не встречал, хоть оно уже и сдохло полтора года как. вот это dbal, а pdo - поделка, которая абстрагирует от маразма разрабов пыха, а не от субд.
 
Сверху