Постраничный вывод на PHP из баз данных
Чем мой код отличается от других?
Реализован принцип ООП. Существуют 2 независимых но взаимодополняемых класса. Для постраничного вывода достаточно инициализировать класс и вызвать всего одну функцию.
В классе для работы с базой данных есть одна функция connectNeeded(), которая проверяет, нужно ли вообще соединяться с базой. Таким образом не будет выполнено подключение, если оно не нужно.
Какие есть недостатки?
Страницы выводятся друг за дружкой. Т.е. если будет 60 страниц, то они все и выведутся на навигации.
Будет ли это исправлено?
Да, конечно! Это всего лишь первая версия классов.
В состав классов не включена функция, выводящая контент из базы данных. Это сделано для удобства пользователя (запрос SELECT может быть сколь угодно большим и сколь угодно вложенным и предугадать это в функции крайне сложно).
Код очень большой, (в сообщение не помещается) поэтому прикладываю его отдельным файлом.
Все вопросы по коду, а так же критику, комментарии, предложения, пожелания вы можете задавать в этой теме.
Класс с БД - тоже не нужная вещь. У всех есть свой класс для работы с БД.
Тем более класс Database привязан к глобальному коду (параметры соединения задаются константами, а их лучше передавать в конструктор).
Метод getTotalRecords() в классе Pagination имеет вызов mysql_query, когда, по логике, надо слать запросы через Database.
Если честно, то я вот все это чудо на 236 строчек (класс Pagination) реализую при помощи нескольких строчек на PHP (запрос, обработка, присваивание рез-тов шаблонизатору), а шаблонизатор (Smarty) все это выводит как мне надо.
Вот так. ООП тут совсем не нужно. Нет абстрагирования от внешних данных. Выходная строка формируется в классе - желательно выносить все в шаблон.
UPD: в чем смысл connectNeeded? От неё нет толку. Она вызывается только в конструкторе и опирается на свойство connID. А оно, при инициализации класса всегда неопределено, так что будет создаваться новый коннект к БД.
[quote="UAS"]в чем смысл connectNeeded? От неё нет толку.[/quote]
Согласен, исправлено.
[quote="UAS"]
Метод getTotalRecords() в классе Pagination имеет вызов mysql_query, когда, по логике, надо слать запросы через Database.
[/quote]
Спасибо за то, что обнаружили недочёт! :) Исправлено.
[quote="UAS"]
Выходная строка формируется в классе - желательно выносить все в шаблон.
[/quote]
Вот честно, абсолютно не трудно сделать. Я просто сделал базовый вариант для вывода на печать. Естественно, что всё это будет улучшаться и дополняться.
[quote="UAS"]
Вот так. ООП тут совсем не нужно.
[/quote]
А вот смысла этого утверждения я не понимаю. Тем более, когда практически готов PHP6... может поясните поподробнее?
Новая версия файла будет выложена немножко попозже с соответствующими комментариями.
Итак вопрос повторю - для чего вообще в принципе нужен ООП в проектах?
Нет смысла в том, что вы написали.
Вот у меня в проекте есть класс, управляющий статьями. Т.е. существует сущность "статья", имеющая свойства и методы. Среди этих методов есть и разбиение статьи на страницы. Вот когда желательно использовать ООП - работа с объектом (а класс - это объект, в первую очередь). А уже в его методах имеет смысл писать постраничный вывод, тем более это занимает 5-6 строчек, используя шаблонизатор.
Просто у вас нет знаний, когда действительно и для чего надо использовать ООП. С опытом и временем, это все прийдет.
В данном же проекте - не стоит себя насиловать ненужными вещами. Здесь ООП не нужен. Лучше потратьте ваше время на изучение учебника по Java или пособий по ООП. Толку будет намного больше.
А раз уже пишете на PHP5, то используйте не trigger_error, а Exception, исключения т.е.
ЗЫ: надеюсь, норм объяснил, так как объясняльщик из меня кривой:)
Как бы объяснить... можно разбить на страницы вывод статьи... темы с форума... новости... статичной страницы... всё что угодно, любой контент из базы. Но сам принцип разбиения на страницы остаётся неизменным. Меняется только контент. В вашем случае смотрите что происходит: у вас класс "статья", в нём есть разбиение на страницы. А мне нужен класс "форум", который, естественно, будет иметь совершенно другие методы и свойства. Согласны? И, получается, что мне из вашего класса нужно выдирать одну функцию постраничной разбивки (а может и не одну). И не факт что эта функция (функции) у вас никак не связаны с другими функциями в классе.
В моём случае есть стабильный работающий класс - некий объект, позволяющий выполнить операцию для любого контента и, между прочим, для любой базы данных. Вот вам, кстати, пример того, что ООП здесь действительно нужно. Во-первых можно написать ещё один класс, выполняющий работу постраничной разбивки, но выводящий это в шаблоне. Этот новый класс будет потомком моего класса Pagination. Т.е. принцип действия останется, (отсюда наследственность) а суть чуть-чуть изменится.
Во-вторых можно написать абстрактный класс, (либо интерфейс) реализующий основные методы работы с СУБД. И для каждой конкретной СУБД будет свой класс который, в свою очередь, будет подключаться к классу Pagination.
Недостатки - много кода. Это исправляется, если хорошо его документировать.
Достоинства - все методы, необходимые для работы постраничного вывода находятся в одном файле. Для реализации постраничного вывода достаточно сделать очень немного действий, и не надо будет ни о чём беспокоиться.
[quote="UAS"]А раз уже пишете на PHP5, то используйте не trigger_error, а Exception, исключения т.е.[/quote]
Абсолютно согласен!
[quote="UAS"]
Просто у вас нет знаний, когда действительно и для чего надо использовать ООП. С опытом и временем, это все прийдет.[/quote]
Не спорю :)
Где здесь нужен ООП?? Чтобы просто сделать общую операцию для всех? Да это можно реализовать в 2 строчках или в функции!! Вы всего лишь одну функцию вынесли в класс.
У вас прямо в коде формируется шаблон. Т.е. не придерживаетесь MVC. Если убрать это формирование шаблона, до код это класса можно сократить до 2 строчек: запрос на кол-во чего-то, извлечение данных. Ради двух строчек нет смысла писать класс
[QUOTE=prog_master;275856]Во-первых можно написать ещё один класс, выполняющий работу постраничной разбивки, но выводящий это в шаблоне. Этот новый класс будет потомком моего класса Pagination.
Берете отдельный класс шаблонизатор. Ему передаете в качестве переменных шаблона параметры списка (общее кол-во, текущая страница), и в нем все формируете. Не парьтесь этим не нужным наследованием.
Ещё раз - передавайте указатель на объект уже созданного объекта базы данных. А так, извините, только мозги вы*бите и себе и использующим. Я лично не собираюсь переименовывать методы своего класса БД, чтобы он подходил для вашего интерфейса, так как это совсем не нужно.
Во-вторых, что значит будет подключаться к классу Pagination? Что-то типа child-класса? Тоже бред. Просто в класс передавайте указатель на объект. Почему? Опыт мне говорит, как я писал, в 99% случаях уже будет создан коннект к БД перед тем, как прочитать это кол-во страниц + как написал выше, используется свой класс для БД.
Что хочу сказать:
1) Возможно, этот Pagination будет полезен как часть самописной CMS, но задача сама настолько тривиальна, что написать её может любой. Так что применение она найдет только у самых-самых начинающих. Вы просто пару строчек вынесли в класс. Не более. В этом нет смысла.
2)
Хэй мээээн, ват а фак ызыт?
2 класса? 236 строк? Pagination? ООП? Обращение к БД?
Ну нах*й...
Если требуется написать код, который осуществляет постраничный вывод, то он должен осуществлять постраничный вывод. И больше ничего.
У всех продвинутых товарищей это действительно несколько строчек, оформленных в функцию.
P.S. Надо как следует тряхнуть головой, махнуть рукой и сказать себе: "Хватит prog_master, дорогой, завязывай!". Затем выделить содержащую эти файлы директорию и куяк, на Del, куяк, куяк... Потом обязательно почистить Корзину. Потом воспользоваться поиском, чтобы убедиться в том, что зло уничтожено.
И лишь после этого приступать к новому проекту.
Этим Вы получите основное конкурентое преимущество - Вы сэкономите время.
Как по мне, так лучше вообще завалиться на диван и зачесать вялого...