Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Класс работы с базой

5.3K
29 октября 2011 года
Прим Палвер
25 / / 07.02.2008
Доброе время суток.

Переписываю в очередной раз свои заготовки. Хочу посоветоваться и получить порцию конструктивной критики. Класс для работы с mysql.

Код:
class class_db
{
    private $db;

    public function connect()
    {
        try
        {
            include $_SERVER['DOCUMENT_ROOT'].'/../outpost/data.php';
            $this->db=new mysqli($db_data['host'],$db_data['user'],$db_data['password'],$db_data['db']);
            unset($db_data);
            $this->db->query("SET NAMES utf8");
            return $this->db;
        }
        catch (Exception $e)
        {
            error_work('fatal',$e->getMessage(),'Прервана связь с базой данных.');
        }
    }
   
    public function query($query)
    {
        $begin_word=strtolower(substr($query,0,5));
       
        if ($begin_word=='select')
        {
            try
            {
                $result=$this->db->query($query);
                $num=$result->num_rows;
                $row=array();
                if ($num>0)
                    for ($i=0; $i<$num; $i++)
                        $row[$i]=$result->fetch_assoc();
                return $row; // возвращаем массив строк
            }
            catch (Exception $e)
            {
                error_work('fatal',$e->getMessage(),'Возникла ошибка при считывании данных.');
            }
        }
        elseif (in_array($begin_word,array('update','insert','delete')))
        {
            try
            {
                $result=$this->db->query($query);
                $num=$result->affected_rows;
                return $num; // возвращаем количество задействованных строк
            }
            catch (Exception $e)
            {
                error_work('fatal',$e->getMessage(),'Возникла ошибка при изменении данных.');
            }
        }
        else
        {
            error_work('fatal','Запрос: '.$query,'Возникла ошибка при обращении к базе данных.');
        }
    }
}
271
29 октября 2011 года
MrXaK
721 / / 31.12.2002
мне кажется, что писать обёртку итак над достаточно высокоуровневым классом mysqli, но при этом игнорировать его возможности (как минимум placeholders) не стоит))
12
29 октября 2011 года
alekciy
3.0K / / 13.12.2005
Не тянет на полноценный класс работы с БД. Поддержу Mr.Hacker в том смысле, что тут приведены какие то обвертки дублирующие уже то, что и так есть в mysqli. К примеру, зачем делать SET NAMES когда есть метод задания кодировки в самом mysqli? Кстати, сам запрос нужно по хорошему заключать в одиночные, а не двойные кавычки. К стилю оформления кода тоже есть претензии. Не экономим на пробелах и {}. Т.е. все = отбиваются с обеих сторон пробелами, все if/for/... в обязательном порядке должены быть с {}.

Мой совет. Не нужно писать абстракцию над уже готовой абстракцией. Нужно добавлять новый функционал. К примеру, возможность указать значение какого поля нужно использовать как ключ в выходном массиве. Или запрос который может выполнить расчет постраничной навигации.
5.3K
29 октября 2011 года
Прим Палвер
25 / / 07.02.2008
Цитата: alekciy
К примеру, зачем делать SET NAMES когда есть метод задания кодировки в самом mysqli?

Можете сказать, что конкретно имеется в виду? Или ссылкой. Поискал - не нашёл. Или не понял, что искать.

244
29 октября 2011 года
UAS
2.0K / / 19.07.2006
1)
Цитата:
$this->db->query("SET NAMES utf8");

Вот только за это руки оторвать. Пользователь должен сам указать кодировку - она не должна быть вшита.

2) Во вторых, что за "error_work(...)". Сделайте свой Exception и его выбрасывайте, а программист сам должен обработать. Или тогда надо сделать abstract portected метод error_work. Кстати, не error_work, а error_process.

А вообще я сам когда-то мудрил со своими абстракциями. Кстати, на порядок выше данной - с учетом времени исполнения запроса, полными информативными сообщениями со стектрейсами. Для описания результата запроса SELECT тоже надо завести отдельный класс, добавить к нему итераторы и вспомогательные методы для получения результата (типа getInt, getBoolean).

3) Накой смысл вообще в данной приблуде, когда есть PDO? Если уж писать оболочку, то только к PDO. А для неё уже есть качественные обертки типа Doctrine.

4)

Цитата:
include $_SERVER['DOCUMENT_ROOT'].'/../outpost/data.php';
$this->db=new mysqli($db_data['host'],$db_data['user'],$db_data['password'],$db_data['db']);

Этого НЕ должно быть в конструкторе. Вы должны вручную в конструктор передавать данные параметры.

5)

Цитата:
error_work('fatal','Запрос: '.$query,'Возникла ошибка при обращении к базе данных.');

Абсолютно неинформативно.
6) Где комментарии к методам?
7) Почему поддерживаются только SELECT, UPDATE, DELETE, INSERT? А если я хочу выполнить GRANT?


Без обид, но пока что обертка ни о чём и использовать я бы её никогда не стал. От неё никакого толку и она абсолютно бесполезна. Максимум, полезна только для своей домашнего сайта на 5 страничек.
Почитайте лучше про PDO и перейдите на него.

5.3K
29 октября 2011 года
Прим Палвер
25 / / 07.02.2008
Есть образцы кода, с которых можно брать пример? Покажите.
Вы между собой хорошо поговорили, но я-то ещё не вашего уровня - не всё понял.
UAS больше разжевал, спасибо.
244
29 октября 2011 года
UAS
2.0K / / 19.07.2006
Войдите на сайт Doctrine: http://www.doctrine-project.org/projects/orm/1.2/docs/manual/introduction/en. Скачайте библиотеку-обертку для PDO и посмотрите исходники - поймете как надо. Ну или хотя бы гляньте примеры использования.
Та библиотека требует минимум PHP 5.3
5.3K
29 октября 2011 года
Прим Палвер
25 / / 07.02.2008
Цитата: UAS
Войдите на сайт Doctrine: http://www.doctrine-project.org/projects/orm/1.2/docs/manual/introduction/en. Скачайте библиотеку-обертку для PDO и посмотрите исходники - поймете как надо. Ну или хотя бы гляньте примеры использования.
Та библиотека требует минимум PHP 5.3

Скачал. Где именно, в какой папке работа с базами?

И ещё я не понял, почему лучше одинарные кавычки. В ни же заключаются вставляемые строки. Как это?

244
30 октября 2011 года
UAS
2.0K / / 19.07.2006
Цитата:
Скачал. Где именно, в какой папке работа с базами?

Во всех папках, ё-маё. Почитайте вообще для начала, что такое PDO. Затем посмотрите примеры использования и возможности PDO и Doctrine. Затем по всем папкам пробегаете и смотрите в файлах что как реализовано.
Не тыкать же мне Вас в конкретные файлы с описанием работы. Там всё находится за пару минут даже неопытным.

Цитата:
И ещё я не понял, почему лучше одинарные кавычки.

Хотя бы потому, что работа с ними происходит значительно быстрее.

5.3K
30 октября 2011 года
Прим Палвер
25 / / 07.02.2008
Слегка не понял...
Я спросил, какие у меня ляпы.
Использую я mysqli.
Почему разговор перетёк к PDO?
mysqli уже никто не использует? он хуже? устарел?

_ _ _

основная прелесть bind_param в том, что строки можно не обрабатывать самому? как есть и вставлять из формы?
76K
30 октября 2011 года
аюна
3 / / 30.10.2011
Идея, к которой и сама относился скептически. Но эта - РАБОТАЕТ. Сделайте ТЫСЯЧИ ЗА МЕСЯЦ ПРИ ВЛОЖЕНИИ ВСЕГО В 70 руб. Нужно послать 10 руб. на 7 Internet кошельков. Потом вычеркнуть 1-й из списка, куда Вы впишете номер своего кошелька и закидываете данное, сообщение на 200 форумов. Я разместил объявление на 120 форумах - через неделю пришло 100 руб, через 2 - 900. Через месяц деньги стали приходить каждый день, спустя ещё 2 недели на счету было 20000. По прошествии 2 месяцев, я получил 120000 и деньги еще идут. И это - за 70 руб! Геометрическая прогрессия делает свое дело.
ЭТО РАБОТАЕТ - ПОТОМУ ЧТО ЭТО ПИРАМИДА!! Следуйте инструкциям!
1.Зарегистрируйтесь в Яндекс.Деньги и внесите 70 руб. на свой кошелек.
2. Возьмите 1-й кошелек из списка, отправьте на него 10 руб, вписав этот номер в поле Номер счёта, (в поле назначение платежа напишите - Внесите меня в список Яндекс.Кошельков). Начиная со второго, по аналогии отправьте по 10 руб. на следующие 6 кошельков (не забудьте вписывать в поле назначение платежа: Внесите меня в список Яндекс.Кошельков).
1) 410011138756779
2) 410011170094377
3) 410011138770067
4) 410011170097647
5) 410011138773721
6) 410011170311320
7) 41001686359192
ПОВТОРЯЮ, чтобы получать доход, необходимо отправить на каждый из этих 7 кошельков по 10 руб. - иначе,модераторами Яндекс.Кошельков Вы просто не будете включены в систему.
Теперь ВНИМАНИЕ! После того, как Вы выполнили п. 2, скопируйте этот текст и вычеркните из этого списка 1-й кошелёк и переместите на его место 2-й, тем самым сместив список на строку выше, впишите в 7-ую строку Ваш кошелёк. Разместите эту статью не менее чем на 200 форумах. Чем больше вы разместите, тем выше будет ваш доход и это напрямую зависит от Вас.
Все очень просто - Ваши 70 руб. вернут Вам первые же 7 человек, а остальное они сделают за Вас.
Больше размещений - больше доход в геометрической прогрессии. ПОМНИТЕ ЭТО!!! Этот бизнес продолжает существовать и процветать. Желаю Вам ВСЕХ БЛАГ.
244
30 октября 2011 года
UAS
2.0K / / 19.07.2006
Цитата:
Я спросил, какие у меня ляпы.

А ещё вы спросили "Есть образцы кода, с которых можно брать пример? Покажите."
Я вам привел пример - он для PDO, но от этого пример хуже не станет. Посмотрев его - поймете как более-менее правильно надо оформлять и проектировать классы. Идеальный образец.

Цитата:
mysqli уже никто не использует? он хуже? устарел?

Тенденция ведёт к использованию PDO. По крайней мере он намного больше масштабируем, поддерживает все популярные СУБД, и, насколько я помню, быстрее.

Цитата:
основная прелесть bind_param в том, что строки можно не обрабатывать самому? как есть и вставлять из формы?

Да. Вставка данных происходит напрямую в базу, потому SQL-инъекции исключены. Ну и скорость выполнения таких запросов явно должна быть выше, а про удобство я молчу.

5.3K
30 октября 2011 года
Прим Палвер
25 / / 07.02.2008
Цитата: UAS
А ещё вы спросили "Есть образцы кода, с которых можно брать пример? Покажите."
Я вам привел пример - он для PDO, но от этого пример хуже не станет. Посмотрев его - поймете как более-менее правильно надо оформлять и проектировать классы. Идеальный образец.

Тенденция ведёт к использованию PDO. По крайней мере он намного больше масштабируем, поддерживает все популярные СУБД, и, насколько я помню, быстрее.

Не хочу выглядеть неблагодарным, но пока я изучаю mysqli - будем о нём. Поумнею - заинтересуюсь PDO.

Цитата: UAS
Да. Вставка данных происходит напрямую в базу, потому SQL-инъекции исключены. Ну и скорость выполнения таких запросов явно должна быть выше, а про удобство я молчу.

Каковы все удобства и преимущества разделения запроса и данных?
Ну и хотелось бы посмотреть добротный образец кода доступа к db по типу mysqli.

244
30 октября 2011 года
UAS
2.0K / / 19.07.2006
:facepalm:
271
30 октября 2011 года
MrXaK
721 / / 31.12.2002
напишите свою ORMку

а вообще http://stackoverflow.com/questions/1141400/looking-for-a-simple-mysqli-class-example-with-descriptions
5.3K
30 октября 2011 года
Прим Палвер
25 / / 07.02.2008
Как целесообразнее вести себя с переменной $mysqli = new mysqli("localhost", "my_user", "my_password", "world") ?
- делать её глобальной;
- использовать в одном классе и в одном объекте;
- или наследовать класс, в котором используется?
Последнее меня смущает тем, что каждый объект в конструкте будет заново соединяться с базой.

Или я снова ничего не понял? Я видел пару примеров, в том числе в книге, где метод-конструкт наследуется другими классами.
271
30 октября 2011 года
MrXaK
721 / / 31.12.2002
делать класс-синглетон, работать, соответственно через статик (::), получая его инстанс, и далее как с обычным классом
5.3K
02 ноября 2011 года
Прим Палвер
25 / / 07.02.2008
Как получить массив строк из базы , пользуясь $smtp?
 
Код:
$smtp = $this->db->prepare($query);
if (!is_empty($data))
    call_user_func_array(array($stmt, 'bind_param'), refValues($data));
$stmt->execute();
$i=0;
while ($row[$i] = $stmt->fetch_assoc()) $i++;
$stmt->close();
Применимо ли fetch_assoc к $stmt?
Если нет, как мне получить тот же массив?

Или вот так?
 
Код:
$smtp = $this->db->prepare($query);
if (!is_empty($data))
    call_user_func_array(array($stmt, 'bind_param'), refValues($data));
$stmt->execute();
$result = $stmt->get_result();
$i=0;
while ($row[$i] = $result->fetch_assoc()) $i++;
$stmt->close();
Последний пример я содрал с одного образца, где было fetch_array(). Но так же тоже можно?
5.3K
03 ноября 2011 года
Прим Палвер
25 / / 07.02.2008
C синглетонами я совсем пока понять ничего не могу. Буду позже разбираться.

Вот такой образец с глобальной переменной не очень плох?
Код:
class class_db {
 
    public $db;
   
    public function __construct()
    {
        try
        {
            global $db;
            $this->db = &$db;
            if (!is_object($this->db))
            {
                include $_SERVER['DOCUMENT_ROOT'].'/../outpost/data.php';
                $this->db = new mysqli($db_data['host'],$db_data['user'],$db_data['password'],$db_data['db']);
                $db->set_charset("utf8");
                unset($db_data);
            }
        }
        catch (Exception $e)
        {
            //...
        }
    }
//...
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог