Универсальные 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, если хочется часто обращаться к элементам по внешнему коду (хотя это не обязательно, ведь мы можем обращаться к элементами по любому параметру)

Это позволяет использовать приведенные ниже функции и не повторять одинаковые функции для каждой сущности.

Универсальные функции

Далее просто привожу список некоторых используемых мной функций. Прошу комментировать и критиковать :)

Чтение всех элементов из базы

public function GetAllItems($table)
{
   $query = "SELECT * FROM $table";

   return $this->msql->Select($query);
}

Выбор элемента по идентификатору

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];
}

Выбор элемента по внешнему коду

public function GetItemByCode($table, $code_item)
{
   $t = "SELECT * FROM $table WHERE code = '%s'";
   $query = sprintf($t, mysql_real_escape_string($code_item));
   $result = $this->msql->Select($query);

   return $result[0];
}

Выбор элементов по параметру

public function GetItemsByParam($table, $param, $value)
{
   $t = "SELECT * FROM $table WHERE $param = '%s'";
   $query = sprintf($t, mysql_real_escape_string($value));
   $result = $this->msql->Select($query);

   return $result;
}

Удаление элемента по идентификатору

public function DeleteItemById($table, $id_item)
{
   $t = "id_$table = '%d'";
   $where = sprintf($t, $id_item);
   $this->msql->Delete($table, $where);

   return true;
}

Удаление элементов по параметру

public function DeleteItemsByParam($table, $param, $value)
{
   $t = "$param = '%s'";
   $where = sprintf($t, mysql_real_escape_string($value));
   $this->msql->Delete($table, $where);

   return true;
}

Генерация пагинации (разбивка на страницы)

Отдаёт массив с общим количеством страниц, позицией начального элемента, значением текущей страницы

public function Paginate($table, $page, $num)
{
   // Находим общее количество элементов
   $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;
}

Выбор списка элементов с пагинацией

На основании результата работы прошлой функции выбираем элементы из таблицы.

public function GetPaginatedList($table, $start, $num)
{
   $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 написал советы интернет инвесторам. Я и сам собираюсь заняться инвестированием, потому подобные статьи мне интересны.

Подпишитесь на обновления блога

Получить в подарок мини-книги и 21-дневный тренинг по личностному росту.

Подписаться на рассылку «Инструменты Интернет для онлайн бизнеса»

Поделиться ссылкой:


Комментарии:

18.07.2011 15:10:00

Чтобы не повторять getById(), getByCode(), и т.д. можно заюзать метод __call(). А так наверное у каждого разработчика со временем появляется такой класс.

18.07.2011 15:11:54

Блин забыл поставить чекбокс :)

18.07.2011 15:58:04

А я вот как раз отошел от такой универсальности. Стараюсь теперь каждый класс оформлять более-менее полноценно. А что если понадобится для одной какой-то страницы поменять формат вызова. Однажды очень жестко столкнулся с подобным, после чего решил все-таки писать такой вот «однотипный» код.

>> Но мы то давно не пишем сами SQL запросы в функциях. Верно? :)
Конечно :) Даже уже забыл стандартные функции для работы с мускулем. Все вызывается через обертки.

18.07.2011 17:16:12

Велосипеды — наше все :)

18.07.2011 17:32:49

как всегда, сколько людей, столько мнений
я придерживаюсь правил, что первичный ключ всегда должен называться id
новости и статьи сами по себе могут быть довольно разнообразны. соответственно, введя дополнительное поле в новости, на него нужно будет расширить и остальные таблицы. либо придётся в коде ограничивать запрос к статьям и прочему, что приведёт к началу: можно было бы сразу написать отдельные классы для новостей и статей, а то придётся аналогичные вещи прописать в коде.
но по существу всё зависит от требуемой задачи. если заранее определена структура на все будущие проекты, то такой метод, конечно, подойдёт замечательно (особенно в целях уменьшения кода)

18.07.2011 17:52:30

Я кстати в последнее время тупо юзаю ZendDbAdapter, основанный на PDO. Ну и у меня есть один базовый класс модели, с универсальными методами, остальные наследуются от него.

18.07.2011 17:53:45

Блин обратные слеши повырезались. Короче там Zend_Db_Adapter

18.07.2011 20:36:15

M_DB лучше сделать базовым классом и все остальные унаследовать от него.
В методах нету абсолютно никаких проверок получаемых параметров. А если вместо int случайно передано string или наоборот?
Насчет пагинации вот в этой книге http://www.kodges.ru/76943-obektno-orientirovannoe-programmirovanie-na-php-5.html есть замечательный класс, книгу кстати тоже очень рекомендую.

пс. успехов вам в велосипедостроении)) это полезно и познавательно но на практике намного эффективнее пользоваться уже готовыми, отлаженными инструментами.

18.07.2011 22:12:25

Я тоже пользуюсь самописным классом-оберткой, за основу брал Котеровский метод с placeholder-ами, довольно удобно вышло =) И расширяется легко...

19.07.2011 07:07:07
#10 Cepj

Все приходит с опытом! По мере прогресса в написании кода, появляются личные предпочтения, привычки и собоственный стиль! Хотя он может показать не совсем логичным, но человек просто так привык!

19.07.2011 09:17:56
#11 Lap

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

19.07.2011 09:42:25

Алексей, поправь ссылку http://ficolab.ru/krossbrauzernoe-zakruglenie-uglov/

19.07.2011 13:36:21
#13 cll

сколько людей, столько мнений. Я в последнее время юзаю ZendDbAdapter, основанный на PDO

19.07.2011 14:27:53
#14 Павел

Да, рано или поздно каждый приходит к таким методам :)
Причем если работа с базой напрямую в каждом новом проекте напрягает не очень сильно, то каждый раз заново писать пейджер (паджинатор) просто сил никаких нет. И все равно получается чаще всего так, что каждый заказчик хочет видеть разбивку по страницам по-своему, и каждый раз функции приходится переписывать и корректировать.
Вообще, статья хорошая, у автора стиль мышления немного отличается от моего. Поэтому всегда интересно посмотреть на другую реализацию привычных вещей.

19.07.2011 22:37:47
#15 yurcheHk0

посоветуйте пожалуйста хорошую книжку для изучения PHP с нуля. Решил завести блог. На вордпрессе вроди все просто но когда хочешь что то изменить ,возникает туча вопросов..

20.07.2011 01:48:41
#16 FashionLady

Я тоже начинаю работать с блогом. Но есть куча всего, что бывает непонятно.

20.07.2011 04:18:17
#17 Saint_Byte

Хм - Нормальные разработчики давно используют ORM и не помнят уже как писать SQL запросы

20.07.2011 05:15:11

Saint_Byte, с чего это? Sql цветет во всю!

20.07.2011 06:00:42
#19 Saint_Byte

Ильшат, ну ну , иди почитай что есть ORM

20.07.2011 07:15:42

Saint_Byte, читал http://ru.wikipedia.org/wiki/ORM, и все равно останусь при своем!
Может потому, что мне так легче! Закрыли бессмысленный холивар!

20.07.2011 08:18:42
#21 Saint_Byte

Ильшат, правильно оставайся - мне не нужны конкуренты

20.07.2011 10:18:59
#22 Катя

Saint_Byte, :-) Конкуренты никому не нужны...))))

Я почему-то привыкла к постам на вашем блоге более философской тематики... Удивил такой темы пост.

21.07.2011 06:31:58

Saint_Byte, какую ORM юзаешь?

21.07.2011 07:10:05
#24 Saint_Byte

Канат Гайлимов, я зендовскую пользую

21.07.2011 07:57:06

Saint_Byte, ну у Зенда там не совсем ORM. Кстати у них в пропозалах появился ActiveRecord :).

Я искал легкую ORM умеющую нормально работать с отношениями, пока выбрал PHP ActiveRecord. Вроде прикольная штука, только подчеркивания в названиях методов не нравятся :).

21.07.2011 08:09:35
#26 Saint_Byte

Канат Гайлимов, да не совсем , я насколько понимаю там оно заточено по SQL языки - поэтому с чем-нить более чем mongoBD работать не будет

25.07.2011 21:41:33
#27 Metallikus

Хм, занятно. В help.php добавлю, который у меня ко всем проектам подключается.

26.07.2011 11:44:15

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

27.07.2011 18:43:52
#29 Александр

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

29.07.2011 16:42:32
#30 dobrik

public function GetAllItems($table)
{
$query = «SELECT * FROM $table»;

return $this->msql->Select($query);
}

Есть ещё одна фнкция подобной этой!

31.07.2011 10:24:38
#31 Gary

Я пока от пхп далёк (только хтмл изучаю пока) Но всё равно интересно было почитать)

01.08.2011 19:56:29
#32 programist

Gary, На самом деле php не чуть не сложнее html, по крайней мере мне так показалось.

05.08.2011 14:02:14

programist, ага, сравнил лошадь со сковородкой

07.08.2011 10:31:18
#34 Юля

programist, да, «сравнил лошадь со сковородкой» - прямо в точку!

Я для работы предпочитаю использовать готовые проверенные инструменты. Но хочу отметить, что этот инструмент как раз содержит вот такой вот класс, который позволяет работать с базой данных и не писать одно и тоже для класса каждого объекта. Думаю, это один из лучших вариантов и каждый программист, который предпочитает «изобретать велосипед» рано или поздно создает такой вот универсальный класс.

10.08.2011 09:31:13
#35 Spek

Хороший пост, помогло в изучении MySQL.

11.08.2011 10:12:08
#36 Brisk

Видите, сколько разных языков программирования. Мне очень, почему-то нравится PHP. Просто, недавно перешел с uCoz, так там, также есть «если что-то», «то», «все». типа <?php user_loged_in ();>, <?php else : ?>, <?php endif : ?>. Вроде так. Если что, исправьте :) .

16.08.2011 18:13:42

для пагинации пользовал sql_calc_found_rows() для вычисления общего количества
+ возможность задавать условие - condition ( к примеру, status=’active’ или category=3)
А в целом - да.. велосипеды, наверное, у всех похожие...

17.08.2011 11:37:26
#38 Elena

Изучаю PHP и эта инф очень популярна и при этом очень полезная!

17.08.2011 12:07:32
#39 Александр

Спасибо Ваша статья по php помогла мне сделать одну фитчу к своему сайту

19.08.2011 03:02:19
#40 Александр

Вроде всё так знакомо, но кое-что в памяти освежил

23.08.2011 20:32:36
#41 Несвиж

Только поверхностно изучал php, поэтому статья очень пригодится)

25.08.2011 06:02:48
#42 Владимир

Долго искал такой сборник php кодов, пытался как то один себе найти так целые сутки его правил т.к. не особо разбираюсь в программировании

09.09.2011 14:46:17
#43 Артурс

Я бы это все построил объектами, это гораздо удобнее, так как методы более структурированны.

07.11.2011 19:57:28
#44 lokilok

тоже ищу годную книжку по php, чтобы с нуля можно было учиться, ато не всегда понятно что делать с кодом, сутки приходиться гугл мучать.

16.11.2011 15:42:01
#45 Николя

Я с php не слишком дружу, но идея с библиотекой стандартных функций мне понравилась.

23.12.2011 14:50:17

Оно то хорошо, но когда у вас в каждой таблице по 50к+ записей, да по 30 полей - выбирать все записи емко как-то.
А если вы еще и используете какие-нить JOIN’ы, а потом надо в них 1 поле добавить - это что, весь проект переписывать? Параметры ф-ии изменяться...

15.03.2012 08:14:54

В функции
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];
}

15.03.2012 08:20:52

Xarakiry, согласен.

14.04.2012 15:06:51

это все очень хорошо, но помоему давно пора доверить это фраймворкам, а уж если вам не нужен кухонный комбайн используйте микроворки, так сказать обезжиренные типа fatfree :)

15.05.2012 08:35:22

PHP все таки рулит...

08.09.2012 21:14:01

Объясните чайнику, почему все-таки обязательно «таблицы в единственном числе»? Я что-то не догоняю, какая принципиальная разница, в единственном или множественном! Заранее спасибо

09.09.2012 08:14:45

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

03.04.2013 13:42:49

Я также использую собственную PHP функцию, которую написал уже лет 6 назад и до сих пор не переделывал ее. Она вырезает кусок строки из текста по маркерам. Указываю текст, признак начала, признак конца и получаю серединку. preg_replace не предлагать! А другой встроенной функции в php нет.

15.04.2013 16:40:28

Блин столько всего оказывается еще не знаю... Все времени не хватает выучить до конца PHP. Спасибо автору :)

03.12.2013 22:49:09

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

15.01.2014 14:45:00
#56 Batya

Spasibo

19.04.2014 11:06:04

Спасибо очень полезная статья.

05.12.2015 11:13:21

Спасибо за статью. А можно ли как-нибудь прописать в PHP, чтобы адресе статьи вместо тире автоматически проставлялись символы подчёркивания? Заранее благодарю.

05.12.2015 13:20:32

Андрей, использовать функцию str_replace()? :)

05.01.2016 19:31:44

Спасибо, давно искал подобную статью

Оставьте комментарий [форматирование]

Пожалуйста, воздержитесь от спама и идиотских высказываний. Жёсткая модерация. Ссылки закрыты атрибутом nofollow, а значит не несут пользы для продвижения!
Ссылки на всё кроме личных блогов и тематических блогов, сходных по тематике с данным, вырезаются.



Мой Telegram канал
Мой RSS фид