[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Критикуем пагинатор
starpom
Название конечно прикол, просто есть пару мыслей по функции createMenu, хотелось обсудить. Это ваш класс с моими коментами :

function createMenu($rewrite = false, $level = '')
{
if(!empty($level))
$this->LevelPage = $level;

$this->SetRewrite = $rewrite;

$this->StartLink = $rewrite ? $this->LevelPage .'/' : '?'. $this->LevelPage .'=';

$count = ceil($this->TableTotal / $this->NumRows / $this->NumColumns);
$menu = "\n<!-- IRB_Paginator begin -->\n";

if($count < 13)
{
$i = 1;
$cnt = $count;
}
else
{
if($this->NumPage > 10)
$menu .= $this->createLink(($this->NumPage - 10), '-10<', '_top');

if($count > 12) // мы и так в этом куске меню (учитывая выше else)
{
if($this->NumPage == 7)
$menu .= $this->createLink(1, 1);
elseif($this->NumPage == 8)
$menu .= $this->createLink(1, 1)
.
$this->createLink(2, 2);
elseif($this->NumPage > 7)
$menu .= $this->createLink(1, 1)
.
$this->createLink(2, 2)
.
$this->createLink(0, '...', '_top', false);
}


if($this->NumPage - 5 < 1) // if($this->NumPage < 6) легче читать
{
$i = 1;
$cnt = 10;
}
elseif($this->NumPage >= $count)
{
$i = $count - 10;
$cnt = $count;
}
else
{
$i = $this->NumPage - 5;
$cnt = $count; // $cnt = $i + 10;
}


if($this->NumPage < 6) // это дублирует условие выше (где легче читать), а значит лишнее
$cnt = $i + 9;
elseif($count - $i > 10) // если выше переписать $cnt = $i + 10; , то это тоже лишнее
$cnt = $i + 10;
elseif($count > $count) // это я вообще не понял о чем это и соответсвенно весь блок обоезки ссылок лишний (имхо)
$cnt = $count;
}


while($i <= $cnt)
{
if($i == $this->NumPage)
$menu .= $this->createLink($i, $i, '_active', false);
else
$menu .= $this->createLink($i, $i);

$i++;
}

if($count > 12)
{
if($this->NumPage < $count - 6)
$menu .= $this->createLink(0, '...', '_top', false) // если я нахожусь на седьмой странице от последней (13 из 20), то ссылки 14,15,16,17,18
. $this->createLink(($count - 1), ($count - 1)); // выведет диапазон, а потом последует троеточие и 19, 20 (троеточие здесь лишнее)

if($this->NumPage < $count - 5)
$menu .= $this->createLink($count, $count);
}

$end = ($this->NumPage + 10 > $count) ? $count : $this->NumPage + 10; // непонятны причины ввода дополнительной $end (усложняет скрипт)

if($this->NumPage < $count - 5 && $count - $this->NumPage >= 10) // вторая часть условия включает первую
$menu .= $this->createLink($end, '>+10', '_top');

return $menu ."\n\n<!-- IRB_Paginator end -->\n";
}


Это мое предложение :

function createMenu($rewrite = false, $level = '')
{
if(!empty($level))
$this->LevelPage = $level;

$this->SetRewrite = $rewrite;

$this->StartLink = $rewrite ? $this->LevelPage .'/' : '?'. $this->LevelPage .'=';

$count = ceil($this->TableTotal / $this->NumRows / $this->NumColumns);

$menu = "\n<!-- IRB_Paginator begin -->\n";

if($count < 13)
{
$i = 1;
$cnt = $count;
}
else
{
if($this->NumPage > 10)
$menu .= $this->createLink(($this->NumPage - 10), '-10<', '_top');

// НОВОЕ убрал проверку (15.11.2010)
if($this->NumPage == 7)
$menu .= $this->createLink(1, 1);
elseif($this->NumPage == 8)
$menu .= $this->createLink(1, 1)
.
$this->createLink(2, 2);
elseif($this->NumPage > 8)
$menu .= $this->createLink(1, 1)
.
$this->createLink(2, 2)
.
$this->createLink(0, '...', '_top', false);



if($this->NumPage < 6)
{
$i = 1;
$cnt = 10;
}
elseif($this->NumPage >= $count)
{
$i = $count - 10;
$cnt = $count;
}
else
{
$i = $this->NumPage - 5;
$cnt = $i + 10;
if ($cnt > $count) // ограничиваем $cnt (НОВОЕ 15.11.2010)
$cnt = $count;
}
}



while($i <= $cnt)
{
if($i == $this->NumPage)
$menu .= $this->createLink($i, $i, '_active', false);
else
$menu .= $this->createLink($i, $i);

$i++;
}

if($count > 12)
{
if($this->NumPage < $count - 7)
$menu .= $this->createLink(0, '...', '_top', false)
.
$this->createLink(($count - 1), ($count - 1))
.
$this->createLink($count, $count);

if($this->NumPage == $count - 7)
$menu .= $this->createLink(($count - 1), ($count - 1))
.
$this->createLink($count, $count);

if($this->NumPage == $count - 6)
$menu .= $this->createLink($count, $count);
}

if($count - $this->NumPage >= 10)
$menu .= $this->createLink($this->NumPage + 10, '>+10', '_top');


return $menu ."\n\n<!-- IRB_Paginator end -->\n";
}

Таким образом мы убрали блок обрезки ссылок, убрали $end со скучным тернарным оператором и подкорректировали по мелочи меню.

Есть также вопрос , зачем в createLimit() мы вводим переменную TableTotal,
поясните если не трудно арифметику ее определения, и чем нас не устраивает
TableCount для определения правой возможной границы $page.



Спустя 58 минут, 21 секунда (3.11.2010 - 14:32) twin написал(а):
Полностью согласен, кроме одного.
Цитата
со скучным тернарным оператором

На мой взгляд он наоборот достаточно веселенький. smile.gif

Скрипт писался из нескольких наработок, ни кто его толком не смотрел и не тестил. А по сему огромное спасибо за анализ и доработку.

Что касается TableTotal, то она нужна для корректного подсчета результата при выводе его в табличном виде (несколько рядов и колонок на одной странице)
Если подумать, можно и это место упростить.

Спустя 36 минут, 16 секунд (3.11.2010 - 15:08) starpom написал(а):
И вам спасибо за класс.
Я не понимаю арифметику в определении $TableTotal, а значит не уверен какие варианты развития событий хотел предусмотреть автор, поэтому спрошу
вот такой createLimit я могу использовать с тем же успехом? или же он чего-то не учтет:

public function createLimit()
{
if($this->NumPage < 1)
$this->NumPage = 1;

$count = ceil($this->TableCount/$this->NumRows/$this->NumColumns);

if($this->NumPage > $count)
$this->NumPage = $count;

$start = $this->NumPage * $this->NumRows * $this->NumColumns - $this->NumRows * $this->NumColumns;

if($start < 0)
$start = 0;

return ' LIMIT '. $start .', '. $this->NumRows * $this->NumColumns;

}

Спустя 4 минуты, 38 секунд (3.11.2010 - 15:13) twin написал(а):
На первый взгляд норм. Более детально сейчас некогда разбираться.
Если всплывет баг - отпишись плиз, подумаем.

Спустя 27 минут, 55 секунд (3.11.2010 - 15:41) starpom написал(а):
Баг появился, отписываюсь как просили, подправил в моем варианте с простановкой сегодняшней даты, убрал еще проверку одну (не уверен но показалась лишней)

Спустя 1 месяц, 13 дней, 2 часа, 35 минут, 12 секунд (16.12.2010 - 18:16) gidrosoldat написал(а):
Доброе время суток, я сюда не критиковать собственно ...
Пытаюсь осмыслить пагинатор! Старательно пытаюсь! Но пока что результаты оставляют желать лучшего!
Итак, я так понял этот скрипт упрощает просмотр списка строк из БД. Мол если список большой - показываем его установленными малыми порциями, а для передвижения между этими порциями формируем динамическое меню. Верно?
Открываю файл. Переменные. Публичные и внутриклассовые. Значения публичные $NumPage, $NumRows, $NumColumns и $LevelPage переменных получаем извне, а внутриклассовые $TableTotal и $TableCount вычислим походу. Так?

Смотрю на функции и сразу появляются вопросы (видимо пропустил что-то в курсе)
в функции countQuery($query) строка
$res = mysqlQuery($query . $this->createLimit());

Как так? Функция createLimit(); еще не определена, а ее значение мы уже используем. Или в классе очередность написания уже не имеет значения?
Дальше в countQuery($query);
preg_match("#FROM(.+)#i", $query, $table);

тут мы из $query достаем все (не смотря на регистр) после слова FROM и кладем в $table. Из дальшейшего контекста я понимаю что результатом этой функции будет массив. Мы вставляем $table[1] в строку запроса.
$result = mysqlQuery("SELECT COUNT(*) AS `cnt`
FROM "
. $table[1]);

Почему слово 'guest' идущее сразу после FROM попадает в [1] ячейку (по сути, вторую по счету!). Что тогда будет в [0]?
Функцию calcQuery($query) я пропустил, думаю в дальнейшем станет ясно зачем она.
Функция createLimit() - вот тут я на 10 минут залип, ощущал себя умственно неполноценным и подумывал бросить это програмирование пока не поздно ))
Суть функции установить границы запроса, то бишь LIMIT <начальная строка>, <количество строк в результате>. Ок, начальную можно определить умножив номер страницы($GET['num']) на заданное количество строк (IRB_NUM_POSTS) + 1. Количество строк в результате еще проще - это будет заданное количество строк (IRB_NUM_POSTS). То есть грубо говоря она должна быть:
 public function createLimit()
{
$start = $this->NumPage * $this->NumRows + 1;

return ' LIMIT '. $start .', '. $this->NumRows;

}

А то что у вас написано я вообще не понял. Увы, мне сложно уловить вашу логику - тем более описания этой функции у вас в курсах нету.

Спустя 45 минут, 38 секунд (16.12.2010 - 19:02) twin написал(а):
Цитата
Функция createLimit(); еще не определена, а ее значение мы уже используем. Или в классе очередность написания уже не имеет значения?
Не только в классе. Вот так тоже будет работать:
echo foo();

function foo()
{
return 'О как';
}

Цитата
Почему слово 'guest' идущее сразу после FROM попадает в [1] ячейку (по сути, вторую по счету!). Что тогда будет в [0]?
сделай
print_r($table);
и посмотри. А лучше почитай про функцию.
Цитата
А то что у вас написано я вообще не понял. Увы, мне сложно уловить вашу логику - тем более описания этой функции у вас в курсах нету.
Ничего там сложного, обычная арифметика. Там просто ограничители реализованы. Если меньше, то. Если больше то. Чтобы за диапазон не выскочить.

Спустя 15 дней, 4 часа, 11 минут, 10 секунд (1.01.2011 - 23:13) shadwar написал(а):
Только начал читать курсы, очень познавательно для начинающего.

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

Пробовал в пагинаторе в разных местах отследить лимит, и откуда берется - вроде переменная устанавливается правильно. Специально включил лог mysql, так там лимит передается с разницей не на 10, а на 1.


Где в скрипте может быть проблема? Или это какая-то настройка php шалит?

Спустя 1 час, 3 минуты, 53 секунды (2.01.2011 - 00:17) twin написал(а):
Кактак((((((((((
Ниченепонимаю.
Неможетбыть.
Застрелюсь.

Спустя 6 минут (2.01.2011 - 00:23) inpost написал(а):
twin
Нееее, не надо! Ты нам ещё нужен =)

Спустя 2 часа, 3 минуты, 37 секунд (2.01.2011 - 02:26) shadwar написал(а):
Мда, вот так работает. Наверняка есть решение более красивое.


/**
* Operates a cache of difficult inquiries
*
@param string $query
*
@access public
*
@return void
*/

public function countQuery($query)
{
$query = str_replace("\n", " ", $query);
preg_match("#FROM(.+)#i", $query, $table);

$result = mysql_query("SELECT COUNT(*) AS `cnt`
FROM "
. $table[1]);
$this->TableCount = mysql_result($result, 0);

// вынес из createLimit
$start = $this->NumPage * $this->NumRows * $this->NumColumns - $this->NumRows * $this->NumColumns;
if($start < 0)
$start = 0;
$res = mysql_query($query . ' LIMIT '. $start .', '. $this->NumRows * $this->NumColumns);


$this->createLimit();
return $res;
}

/**
* Operates a cache of difficult inquiries
*
@param string $query
*
@access public
*
@return void
*/

public function calcQuery($query)
{
$query = preg_replace('#SELECT#i', 'SELECT SQL_CALC_FOUND_ROWS ', $query);

// вынес из createLimit
$start = $this->NumPage * $this->NumRows * $this->NumColumns - $this->NumRows * $this->NumColumns;
if($start < 0)
$start = 0;
$res = mysql_query($query . ' LIMIT '. $start .', '. $this->NumRows * $this->NumColumns);


$this->TableCount = mysql_result(mysql_query('SELECT FOUND_ROWS()'), 0);

$this->createLimit();
return $res;
}

/**
* Calculates a position and prepares a limit for inquiry
*
@param int $page
*
@access public
*
@return string
*/

public function createLimit()
{

$this->TableTotal = intval(($this->TableCount - $this->NumColumns) / $this->NumRows * $this->NumColumns) - 1;

if($this->NumPage < 1)
$this->NumPage = 1;

if(empty($this->TableTotal) || $this->TableTotal < $this->TableCount)
$this->TableTotal = $this->TableCount;

if($this->NumPage > $this->TableTotal)
$this->NumPage = $this->TableTotal;
}

Спустя 6 часов, 37 минут, 25 секунд (2.01.2011 - 09:04) twin написал(а):
Не в этом дело. Что то где то было напутано. Работает класс вполне нормально в том виде, в котором представлен.

Спустя 2 часа, 55 минут, 43 секунды (2.01.2011 - 11:59) shadwar написал(а):
Брал с нуля образец с сайта, ничего не менял. Базу накатил ту, что в архиве.

Простой запрос работает как должен, сложный передает неправильные лимиты.
В уже адаптированном под ядро такой проблемы может нет, но в отдельном примере есть.
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.