Универсальные PHP функции
Сегодня хочу поговорить немного об универсальных функциях. В данном случае это касается PHP.
Как всегда тема статьи выходит из проблемы, которую я в своё время решал, а теперь хочу поделиться решением со своими читателями.
Итак, проблема. Пишете вы скрипт, в котором должно присутствовать множество сущностей (статьи, товары, категории, заказы и т.д.). Конечно, как грамотный программер, вы разобьёте модели сущностей на классы и приметесь писать для них методы. Получится кучка файлов (M_Articles.php, M_Products.php, M_Categories.php, M_Orders.php).
И скорее всего, вам понадобятся стандартные функции, одинаковые для каждой сущности. Например, выборка всех элементов таблицы, выборка или удаление по идентификатору или другому параметру, разбивка элементов на страницы.
Можно конечно прописать их для каждой сущности отдельно. Например, GetAllProducts() и GetAllArticles(), GetArticleById() и GetProductById(). Но есть ли в этом смысл? Я предпочитаю написать специальный класс универсальных методов M_DB.php.
Это будет библиотека стандартных функций, которые принимают название таблицы в качестве параметра.
Для корректного использования этого метода следует следовать определённым правилам:
- называть таблицы в единственном числе (order, product, article, category)
- называть идентификатор таблицы как название таблицы с приставкой id_ (id_order, id_product, id_article, id_category)
- ввести поле code, если хочется часто обращаться к элементам по внешнему коду (хотя это не обязательно, ведь мы можем обращаться к элементами по любому параметру)
Это позволяет использовать приведенные ниже функции и не повторять одинаковые функции для каждой сущности.
Универсальные функции
Далее просто привожу список некоторых используемых мной функций. Прошу комментировать и критиковать :)
Чтение всех элементов из базы
{
$query = "SELECT * FROM $table";
return $this->msql->Select($query);
}
Выбор элемента по идентификатору
{
$t = "SELECT * FROM $table WHERE id_$table = '%d'";
$query = sprintf($t, $id_item);
$result = $this->msql->Select($query);
return $result[0];
}
Выбор элемента по внешнему коду
{
$t = "SELECT * FROM $table WHERE code = '%s'";
$query = sprintf($t, mysql_real_escape_string($code_item));
$result = $this->msql->Select($query);
return $result[0];
}
Выбор элементов по параметру
{
$t = "SELECT * FROM $table WHERE $param = '%s'";
$query = sprintf($t, mysql_real_escape_string($value));
$result = $this->msql->Select($query);
return $result;
}
Удаление элемента по идентификатору
{
$t = "id_$table = '%d'";
$where = sprintf($t, $id_item);
$this->msql->Delete($table, $where);
return true;
}
Удаление элементов по параметру
{
$t = "$param = '%s'";
$where = sprintf($t, mysql_real_escape_string($value));
$this->msql->Delete($table, $where);
return true;
}
Генерация пагинации (разбивка на страницы)
Отдаёт массив с общим количеством страниц, позицией начального элемента, значением текущей страницы
{
// Находим общее количество элементов
$query = "SELECT COUNT(*) as count FROM $table";
$result = $this->msql->Select($query);
$items = $result[0]['count'];
// Если записей нет, то отдаём false
if (empty($items))
return false;
// Находим общее количество страниц
$total = (($items - 1) / $num) + 1;
$navi['total'] = intval($total);
// Находим начальный элемент
// Если значение текущей страницы больше максимального или меньше нуля, то отдаём false
$page = intval($page);
if (empty($page) or $page < 0)
return false;
if ($page > $total)
return false;
$navi['start'] = $page * $num - $num;
// Сохраняем также в массив текущую страницу
$navi['page'] = $page;
return $navi;
}
Выбор списка элементов с пагинацией
На основании результата работы прошлой функции выбираем элементы из таблицы.
{
$t = "SELECT * FROM $table ORDER BY id_$table DESC LIMIT %d, %d";
$query = sprintf($t, $start, $num);
return $this->msql->Select($query);
}
Такие вот функции. Что думаете по этому поводу?
Конечно, указанные функции предполагают наличие специальной модели (прослойки) для работы с MySQL. Но мы то давно не пишем сами SQL запросы в функциях. Верно? :)
Обмен ссылками
Ильшат написал про Кроссбраузерное закругление углов. Только для пущей кроссбраузерности я бы добавил ещё правило -khtml-border-radius.
Виталий, автор блога ZarabotokEst.ru написал советы интернет инвесторам. Я и сам собираюсь заняться инвестированием, потому подобные статьи мне интересны.
Поделиться ссылкой:
Комментарии:
А я вот как раз отошел от такой универсальности. Стараюсь теперь каждый класс оформлять более-менее полноценно. А что если понадобится для одной какой-то страницы поменять формат вызова. Однажды очень жестко столкнулся с подобным, после чего решил все-таки писать такой вот «однотипный» код.
>> Но мы то давно не пишем сами SQL запросы в функциях. Верно? :)
Конечно :) Даже уже забыл стандартные функции для работы с мускулем. Все вызывается через обертки.
как всегда, сколько людей, столько мнений
я придерживаюсь правил, что первичный ключ всегда должен называться id
новости и статьи сами по себе могут быть довольно разнообразны. соответственно, введя дополнительное поле в новости, на него нужно будет расширить и остальные таблицы. либо придётся в коде ограничивать запрос к статьям и прочему, что приведёт к началу: можно было бы сразу написать отдельные классы для новостей и статей, а то придётся аналогичные вещи прописать в коде.
но по существу всё зависит от требуемой задачи. если заранее определена структура на все будущие проекты, то такой метод, конечно, подойдёт замечательно (особенно в целях уменьшения кода)
Я кстати в последнее время тупо юзаю ZendDbAdapter, основанный на PDO. Ну и у меня есть один базовый класс модели, с универсальными методами, остальные наследуются от него.
Блин обратные слеши повырезались. Короче там Zend_Db_Adapter
M_DB лучше сделать базовым классом и все остальные унаследовать от него.
В методах нету абсолютно никаких проверок получаемых параметров. А если вместо int случайно передано string или наоборот?
Насчет пагинации вот в этой книге http://www.kodges.ru/76943-obektno-orientirovannoe-programmirovanie-na-php-5.html есть замечательный класс, книгу кстати тоже очень рекомендую.
пс. успехов вам в велосипедостроении)) это полезно и познавательно но на практике намного эффективнее пользоваться уже готовыми, отлаженными инструментами.
Я тоже пользуюсь самописным классом-оберткой, за основу брал Котеровский метод с placeholder-ами, довольно удобно вышло =) И расширяется легко...
Все приходит с опытом! По мере прогресса в написании кода, появляются личные предпочтения, привычки и собоственный стиль! Хотя он может показать не совсем логичным, но человек просто так привык!
В основном стараюсь все делать максимально универсально, помогает человеческая лень. Правда вначале приходиться все хорошо продумать и спроектировать, чтоб в конце не вылезли странные косяки.
Алексей, поправь ссылку http://ficolab.ru/krossbrauzernoe-zakruglenie-uglov/
сколько людей, столько мнений. Я в последнее время юзаю ZendDbAdapter, основанный на PDO
Да, рано или поздно каждый приходит к таким методам :)
Причем если работа с базой напрямую в каждом новом проекте напрягает не очень сильно, то каждый раз заново писать пейджер (паджинатор) просто сил никаких нет. И все равно получается чаще всего так, что каждый заказчик хочет видеть разбивку по страницам по-своему, и каждый раз функции приходится переписывать и корректировать.
Вообще, статья хорошая, у автора стиль мышления немного отличается от моего. Поэтому всегда интересно посмотреть на другую реализацию привычных вещей.
посоветуйте пожалуйста хорошую книжку для изучения PHP с нуля. Решил завести блог. На вордпрессе вроди все просто но когда хочешь что то изменить ,возникает туча вопросов..
Я тоже начинаю работать с блогом. Но есть куча всего, что бывает непонятно.
Хм - Нормальные разработчики давно используют ORM и не помнят уже как писать SQL запросы
Saint_Byte, читал http://ru.wikipedia.org/wiki/ORM, и все равно останусь при своем!
Может потому, что мне так легче! Закрыли бессмысленный холивар!
Saint_Byte, :-) Конкуренты никому не нужны...))))
Я почему-то привыкла к постам на вашем блоге более философской тематики... Удивил такой темы пост.
Saint_Byte, ну у Зенда там не совсем ORM. Кстати у них в пропозалах появился ActiveRecord :).
Я искал легкую ORM умеющую нормально работать с отношениями, пока выбрал PHP ActiveRecord. Вроде прикольная штука, только подчеркивания в названиях методов не нравятся :).
Канат Гайлимов, да не совсем , я насколько понимаю там оно заточено по SQL языки - поэтому с чем-нить более чем mongoBD работать не будет
Хм, занятно. В help.php добавлю, который у меня ко всем проектам подключается.
Мне давно были известны указаные Вами методы, но все же спасибо, что Вы мне их напомнили. Никогда не помешает лишний раз прочесть интересную и полезную статью!
замечательная статья))) побольше бы таких авторов, желаю вам творческих успехов)))
public function GetAllItems($table)
{
$query = «SELECT * FROM $table»;
return $this->msql->Select($query);
}
Есть ещё одна фнкция подобной этой!
Я пока от пхп далёк (только хтмл изучаю пока) Но всё равно интересно было почитать)
programist, да, «сравнил лошадь со сковородкой» - прямо в точку!
Я для работы предпочитаю использовать готовые проверенные инструменты. Но хочу отметить, что этот инструмент как раз содержит вот такой вот класс, который позволяет работать с базой данных и не писать одно и тоже для класса каждого объекта. Думаю, это один из лучших вариантов и каждый программист, который предпочитает «изобретать велосипед» рано или поздно создает такой вот универсальный класс.
Видите, сколько разных языков программирования. Мне очень, почему-то нравится PHP. Просто, недавно перешел с uCoz, так там, также есть «если что-то», «то», «все». типа <?php user_loged_in ();>, <?php else : ?>, <?php endif : ?>. Вроде так. Если что, исправьте :) .
для пагинации пользовал sql_calc_found_rows() для вычисления общего количества
+ возможность задавать условие - condition ( к примеру, status=’active’ или category=3)
А в целом - да.. велосипеды, наверное, у всех похожие...
Спасибо Ваша статья по php помогла мне сделать одну фитчу к своему сайту
Долго искал такой сборник php кодов, пытался как то один себе найти так целые сутки его правил т.к. не особо разбираюсь в программировании
Я бы это все построил объектами, это гораздо удобнее, так как методы более структурированны.
тоже ищу годную книжку по php, чтобы с нуля можно было учиться, ато не всегда понятно что делать с кодом, сутки приходиться гугл мучать.
Я с php не слишком дружу, но идея с библиотекой стандартных функций мне понравилась.
Оно то хорошо, но когда у вас в каждой таблице по 50к+ записей, да по 30 полей - выбирать все записи емко как-то.
А если вы еще и используете какие-нить JOIN’ы, а потом надо в них 1 поле добавить - это что, весь проект переписывать? Параметры ф-ии изменяться...
В функции
public function GetItemById($table, $id_item)
{
$t = «SELECT * FROM $table WHERE id_$table = ’%d’»;
$query = sprintf($t, $id_item);
$result = $this->msql->Select($query);
return $result[0];
}
идентификатор у статьи один и единственный. Используйте limit 1
public function GetItemById($table, $id_item)
{
$t = «SELECT * FROM $table WHERE id_$table = ’%d’ LIMIT 1»;
$query = sprintf($t, $id_item);
$result = $this->msql->Select($query);
return $result[0];
}
это все очень хорошо, но помоему давно пора доверить это фраймворкам, а уж если вам не нужен кухонный комбайн используйте микроворки, так сказать обезжиренные типа fatfree :)
Объясните чайнику, почему все-таки обязательно «таблицы в единственном числе»? Я что-то не догоняю, какая принципиальная разница, в единственном или множественном! Заранее спасибо
Я также использую собственную PHP функцию, которую написал уже лет 6 назад и до сих пор не переделывал ее. Она вырезает кусок строки из текста по маркерам. Указываю текст, признак начала, признак конца и получаю серединку. preg_replace не предлагать! А другой встроенной функции в php нет.
Блин столько всего оказывается еще не знаю... Все времени не хватает выучить до конца PHP. Спасибо автору :)
Уже не однажды использовал эту функцию в своих скриптах. Могу только сказать что она работает превосходно и ее быстродействие доказывает ее результативность.
Спасибо за статью. А можно ли как-нибудь прописать в PHP, чтобы адресе статьи вместо тире автоматически проставлялись символы подчёркивания? Заранее благодарю.
Чтобы не повторять getById(), getByCode(), и т.д. можно заюзать метод __call(). А так наверное у каждого разработчика со временем появляется такой класс.