php.de

Zurück   php.de > Lösungen durch Skripte > Scriptbörse

Scriptbörse PHP Lösungen für nen schmalen Taler

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 16.11.2010, 19:26  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.269
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard Paginator Algorithmus

Hallo,

habe einen neuen Paginator-Algorithmus (Alpha Version ). Ist noch nicht ausgereift, aber scheint zu funktionieren. Er erstellt abhängig von der aktuellen Seite ($currentPage) und der Gesamtzahl aller Seiten ($pageCount) einen Array mit Seitenzahlen, die darzustellen sind.

Könnte so aussehen:
1 .. 17 18 [19] 20 21 .. 50

currentPage=19, pageCount=50, smartRange=5 (unterstrichen)

Der erste und letzte Wert sind immer Seite 1 bzw. die letzte Seite.
Wenn möglich wird ".." durch die passende Seitenzahl ersetzt, also z.B.

1 2 [3] 4 5 6 7 .. 50

Ungetestet sind andere Werte für smartRange, sollte aber auch so gehen, solang die Zahl ungerade ist!


PHP-Code:
<?php
class Util_Paginator
{
    const 
DOT_DOT '..';
    
    protected 
$_currentPage;
    protected 
$_pageCount;
    protected 
$_smartRange 5;
    
    public function 
__construct($pageCount$currentPage)
    {
        
$this->_pageCount   10;$pageCount;
        
$this->_currentPage 1;$currentPage;
    }
    
    public function 
render()
    {
        
set_time_limit(3);
        
        if (
$this->_pageCount <= 1) {
            return 
$this->_renderPages();
        }
        
$pagesToDisplay $this->_smartRange 4;
        if (
$this->_pageCount <= $pagesToDisplay) {
            
$pages range(1$this->_pageCount);
            return 
$this->_renderPages($pages);
        }
        
        
$maxRange  $this->_smartRange 4;
        
$firstPage max($this->_currentPage $maxRange1);
        
$lastPage  min($this->_currentPage $maxRange$this->_pageCount);
        
        do {
            
$dropLeft = ($this->_currentPage $firstPage) > ($lastPage $this->_currentPage);
            if (
$dropLeft) {
                ++
$firstPage;
            } else {
                --
$lastPage;
            }
            
$diff $lastPage $firstPage;
        } while ((
$diff 1) > $pagesToDisplay);
        
        
        
$pages        range($firstPage$lastPage);
        
$pages[0]     = 1;
        if (
$pages[1] != 2) {
            
$pages[1] = self::DOT_DOT;
        }
        if (
$pages[$diff 1] != ($this->_pageCount 1)) {
            
$pages[$diff 1] = self::DOT_DOT;
        }
        
$pages[$diff] = $this->_pageCount;
        
        return 
$this->_renderPages($pages);
    }
    
    protected function 
_renderPages(array $pages = array())
    {
        echo 
'<pre>'print_r($pagestrue), '</pre>';
    }
    
    protected function 
_isValidPage($page)
    {
        return 
<= $page && $page <= $this->_pageCount;
    }
}
?>
Die Rendering-Logik fehlt noch, sollte aber das kleinste Problem darstellen.
__________________
"Nuschel ich?" - "Was?"
Chriz ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 16.11.2010, 19:39  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.994
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Hatte ich auch mal vor, sowas zu schreiben. Werd ich bei Gelegenheit mal nachholen.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 16.11.2010, 20:01  
Moderator¹
 
Registriert seit: 28.03.2010
Beiträge: 7.470
PHP-Kenntnisse:
Fortgeschritten
ChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer AnblickChrisB ist ein wunderbarer Anblick
Standard

Zitat:
Zitat von Chriz Beitrag anzeigen
Die Rendering-Logik fehlt noch, sollte aber das kleinste Problem darstellen.
Ist aber m.E. die Hauptaufgabe, die diese Klasse überhaupt zu erfüllen hat.

Die Daten an sich liegen bereits vor. Die Aufgabe, die noch zu erfüllen ist, ist das Rendering dieser Daten. Außerdem überlässt du wieder einen wesentlichen Teil der Logik der aufrufenden Stelle, wenn die noch entscheiden muss, ob ein Array-Eintrag nun eine Seitenzahl ist und damit verlinkt werden muss, oder ob der Eintrag nur '..' ist, damit nur Füllzeichen und nicht verlinkt werden sollte.
Würde ich also so umbauen, dass das auch die Hauptfunktionalität dieser Klasse ist - die fertigen Links zurückgeben. Um das ganze flexibel zu halten, ggf. per printf ein Mini-„Templating“ für die Ausgabe einbauen.


Ob's dazu eine eigene Klasse braucht, wäre die andere Frage - tut's als Funktion m.E. genauso gut. Sowas hab ich auch noch rumfliegen,
PHP-Code:
function paginationLinks($num$step$act$before) {
  
$output '';
  
$numLinks ceil($num/$step);
  if(
$act || $act $numLinks) return 'paginationLinks error: param out of bounds!';
  if(
$numLinks 1) {
    
$output .= $act == '<u>[1]</u> ' '[1] ';
    if(
$act $before 2) {
      
$output .= '... ';
    }
  }
  for(
$i=max(2$act-$before); $i<=min($numLinks-1$act+$before); ++$i) {
    
$output .= $act == $i '<u>['.$i.']</u> ' '['.$i.'] ';
  }
  if(
$act $before $numLinks-1) {
    
$output .= '... ';
  }
  
$output .= $act == $numLinks '<u>['.$numLinks.']</u>' '['.$numLinks.']';
  return 
$output;
}

echo 
paginationLinks(
    
500// Anzahl der Einträge
    
10// Anzahl Einträge pro Seite
    
49// aktuelle Position (Seitennummer)
    
// Anzahl zu erzeugender Links vor/nach aktueller Seite
); 
Die Funktion will nicht die Anzahl Seiten als Parameter, sondern die Anzahl an Einträgen und wie viele pro Seite dargestellt werden sollen. Kommt zwar in etwa auf's gleiche raus, ist aber m.E. etwas praxisnäher. Außerdem damit flexibler, wenn man dem Nutzer der Seite eine Auswahl zur Verfügung stellt, wie viele Einträge er pro Seite dargestellt haben will.
__________________
RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?

Geändert von ChrisB (16.11.2010 um 20:15 Uhr).
ChrisB ist offline   Mit Zitat antworten
Alt 16.11.2010, 20:30  
Moderator
 
Benutzerbild von Chriz
 
Registriert seit: 11.05.2008
Beiträge: 6.269
Chriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer AnblickChriz ist ein wunderbarer Anblick
Standard

Danke für eure Antworten.

Also ich finde die Ausgabe und das geschickte "Templating" eigentlich weniger anspruchsvoll. Sicherlich machen es fast alle Klassen (inklusive Zend) falsch, da sie Implikationen vornehmen, die unsinnig sind. Aber mit abstrakten CSS-Angaben lässt sich doch eine relativ flexible Ausgabe erzeugen (die noch folgen wird).

Und um ehrlich zu sein - ich finde die geschickte Zusammenfassung und "Errechnung" von anzuzeigenden Seitenzahlen das schwierigste daran. Mit einem Decorator o.ä. kann der Anwender meinetwegen auch sein eigenes Templating machen.

Im übrigen ist die do-while-Schleife unnötig, im Prinzip kann man mathematisch berechnen wieviele Werte links und rechts entfernt werden müssen, damit die gewünschte Ausgabe erzeugt wird.

Dein Skript ChrisB teste ich morgen bei der Arbeit.

Zitat:
Außerdem überlässt du wieder einen wesentlichen Teil der Logik der aufrufenden Stelle, wenn die noch entscheiden muss, ob ein Array-Eintrag nun eine Seitenzahl ist und damit verlinkt werden muss, oder ob der Eintrag nur '..' ist, damit nur Füllzeichen und nicht verlinkt werden sollte.
sehe ich eigentlich nicht so, Bedingungen müssen so oder so her. Für Verlinkung, aktuelle Seite markieren, zurück und weiter etc. Ich meine eine einfachere Erzeugung als ein Array mit den Seitenzahlen und einem potentiellen Placeholder ist doch wirklich schwer zu unterbieten.

Na jedenfalls mir gefällts. Endergebnis wird gepostet, natürlich bereinigt um einige Fehler und das set_time_limit kommt natürlich auch noch raus. Das ist nur der Rettungsanker für Endlosschleifen.
__________________
"Nuschel ich?" - "Was?"
Chriz ist offline   Mit Zitat antworten
Alt 16.11.2010, 21:19  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.994
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Habs gerade mal ausprobiert. Sinnvoll wäre imho noch ein min/max-Filter für den current-Wert. Sonst werden seltsame Effekte außerhalb des Grenzbereichs erzeugt.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--
nikosch ist offline   Mit Zitat antworten
Alt 16.11.2010, 21:30  
moderatives Dielektrikum
 
Benutzerbild von nikosch
 
Registriert seit: 21.05.2008
Beiträge: 35.994
PHP-Kenntnisse:
Fortgeschritten
nikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunftnikosch hat eine strahlende Zukunft
Standard

Und bei kleinen Werten scheint mir die smart-range nicht zu stimmen. Ist aber viell. auch nur eine Definitionsfrage.

[edit]
Ok, geht wohl nicht anders.
__________________
--
One pixel is still too big. Please make it smaller. ASAP.

Initiative Mittelstand.
Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers.
--

Geändert von nikosch (16.11.2010 um 21:37 Uhr).
nikosch ist offline   Mit Zitat antworten
Alt 16.11.2010, 21:56  
fab
Erfahrener Benutzer
 
Benutzerbild von fab
 
Registriert seit: 28.07.2010
Beiträge: 2.308
PHP-Kenntnisse:
Fortgeschritten
fab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblick
Standard

Dann werfe ich nochmal die Pagination-Klasse in den Raum, die ich fürs Gästebuch-Quiz erstellt habe:

PHP-Code:
<?php
class SlimGb_Pagination
{
    
/**
     * @var SlimGb_Page[]
     */
    
private $pages = array();
    
/**
     * @var string
     */
    
private $info;

    private 
$totalEntries;
    private 
$offset;
    private 
$totalPages;
    private 
$currentPage;
    private 
$entriesPerPage;
    private 
$maxPageLinks;
    private 
$pageLinkFormat;
    
    public function 
__construct(SlimGb_Service_Config  $config$totalEntries$offset)
    {
        
$this->entriesPerPage $config['entries']['per_page'];
        
$this->maxPageLinks $config['entries']['max_page_links'];
        
$this->pageLinkFormat $this->getPageLinkFormat($config['application']['link']);
        
        
$this->totalEntries $totalEntries;
        
$this->offset $offset;

        
$this->totalPages ceil(bcdiv($this->totalEntries,$this->entriesPerPage1));
        
$this->currentPage round(bcdiv($this->offset$this->entriesPerPage1)) + 1;
        
$this->currentPage min($this->totalPages$this->currentPage);
        
$this->currentPage max(1$this->currentPage);
        
        
$this->createPages();
        
$this->info sprintf('Showing %d-%d out of %d entries.'$this->pages[$this->currentPage]->from$this->pages[$this->currentPage]->to$totalEntries);
    }
    
    public function 
getPages()
    {
        return 
$this->pages;
    }
    public function 
getInfo()
    {
        return 
$this->info;
    }
    public function 
getCurrentPage()
    {
        return 
$this->pages[$this->currentPage];
    }
    
    private function 
getPageLinkFormat($baseLink)
    {
        
$result $baseLink;
        if (
strpos($baseLink'?')!==false) {
            
$result .= '&';
        } else {
            
$result .= '?';
        }
        
$result .= 'SlimGb_offset=%d';
        return 
$result;
    }

    private function 
createPages()
    {
        if (
$this->totalPages <= $this->maxPageLinks) {
            
$this->createAllPages();
            return;
        }
        
$this->createFirstPages();
        
$this->createLastPages();
        
$this->createCurrentPages();
        
ksort($this->pages);
    }
    
    private function 
createAllPages()
    {
        for(
$i 1$i <= $this->totalPages; ++$i)
        {
            
$this->pages[$i] = $this->makePage($this->currentPage == $i SlimGb_Page::ACTIVE SlimGb_Page::LINK$i);
        }
    }
    
    private function 
createFirstPages()
    {
        
$end bcdiv($this->maxPageLinks30);
        for(
$i 1$i $end; ++$i) {
            
$this->pages[$i] = $this->makePage(SlimGb_Page::LINK$i);
        }
        
$this->pages[$end] = new SlimGb_Page(SlimGb_Page::DOTS);
    }
    
    private function 
createLastPages()
    {
        
$start $this->totalPages bcdiv($this->maxPageLinks30) + 1;
        for(
$i $this->totalPages$i $start; --$i) {
            
$this->pages[$i] = $this->makePage(SlimGb_Page::LINK$i);
        }
        
$this->pages[$start] = new SlimGb_Page(SlimGb_Page::DOTS);
    }
    
    private function 
createCurrentPages()
    {
        
$this->pages[$this->currentPage] = $this->makePage(SlimGb_Page::ACTIVE$this->currentPage);
        
$i $this->currentPage;
        
$k 1;
        while(
count($this->pages) < $this->maxPageLinks) {
            
$i += pow(-1$k) * $k;
            ++
$k;
            if (
$i >= && $i <= $this->totalPages) {
                
$this->pages[$i] = $this->makePage(SlimGb_Page::LINK$i);
            }
        }
    }
    
    private function 
makePage($type$pageNumber)
    {
        return new 
SlimGb_Page(
            
$type,
            
$pageNumber,
            
$this->entriesPerPage * ($pageNumber 1),
            
min($this->totalEntries$this->entriesPerPage * ($pageNumber)),
            
sprintf($this->pageLinkFormat$this->entriesPerPage * ($pageNumber -1))
        );
    }
}
Interessant für den Algorithmus sind die create* Methoden. Insgesamt ähnlicher Ansatz aber statt die Anzahl von Links um die aktuelle Seite herum wird die maximale Gesamtzahl festgelegt und diese auf die ersten Seiten, die letzten Seiten und die Seiten links und rechts der aktuellen Seite verteilt, das kann dann z.B. so aussehen (unterstrichen = aktuelle Seite):

1 2 3 ... 10 11 12 ... 18 19 20
1 2 3 4 5 6 7 ... 18 19 20
1 2 3 ... 14 15 16 17 18 19 20
fab ist offline   Mit Zitat antworten
Alt 16.11.2010, 22:04  
Erfahrener Benutzer
 
Benutzerbild von mermshaus
 
Registriert seit: 14.06.2009
Beiträge: 1.733
PHP-Kenntnisse:
Fortgeschritten
mermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz seinmermshaus kann auf vieles stolz sein
Standard

Ihr seid alle die Masters of Commenting. *scnr*
__________________
Blog | Buch | Kaloa
mermshaus ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
paginator php, nikosch chriz mermshaus quiz, php paginator klasse, paginator letzte seite, paginator, function paginationlinks($num, $step, $act, $before) {

Alle Zeitangaben in WEZ +2. Es ist jetzt 01:16 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum