php.de

Zurück   php.de > Webentwicklung > PHP-Fortgeschrittene

PHP-Fortgeschrittene Arbeiten mit PHP ohne Einschränkungen

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 01.02.2012, 17:51  
archer42
Gast
 
Beiträge: n/a
Standard Paginator Kritik

Hallo,
nach einer langen Krise habe ich endlich einen eigenen Paginator fertig. Hierbei muss ich mich auch nochmal bei einigen entschuldigen, dass ich mich beratungsresistent gezeigt habe und den Paginator als ein geheimen Zauber betrachtet habe.

PHP-Code:
<?php

namespace AcmeAppBundleHelpers
;

class 
Paginator {
    protected 
$limit;
    protected 
$entityManager;
    protected 
$entity;

    public function 
setEntityManager($entityManager) {
        
$this->entityManager $entityManager;
    }

    public function 
setLimit($limit) {
        
$this->limit $limit;
    }

    public function 
setEntity($entityLocation$orderByColumn$orderByDirection) {
        
$this->entity $this->entityManager
            
->createQuery('SELECT e FROM ' $entityLocation ' e ORDER BY e.' $orderByColumn ' ' $orderByDirection)
            ->
getResult();
    }

    public function 
getCurrentPage($currentPage) {
        
$offset $this->limit * ($currentPage 1);
        
$length $offset $this->limit;
        return 
array_slice($this->entity$offset$length);
    }

}
PHP-Code:
public function indexAction($orderByColumn$orderByDirection$page) {
        
$em $this->getDoctrine()->getEntityManager();

        
$paginator = new Paginator();
        
$paginator->setLimit('5');
        
$paginator->setEntityManager($em);
        
$paginator->setEntity('AcmeAppBundle:Customer'$orderByColumn$orderByDirection);
        
$customers $paginator->getCurrentPage($page);

        return 
$this->render('AcmeAppBundle:Customer:index.html.twig', array(
            
'customers' => $customers,
        ));
    } 
Folgende Fragen ergeben sich nun noch zum Paginator:
1. Sollte die Pagination per PHP oder lieber SQL (Doctrine) gemacht werden?
2. Sollte ich den DBAL Teil aus dem Paginator entfernen und im Controller belassen?
3. Weitere Kritik?

Gruß,
archer

Geändert von archer42 (01.02.2012 um 18:06 Uhr).
  Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

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

Alt 01.02.2012, 20:45  
archer42
Gast
 
Beiträge: n/a
Standard

Mal etwas verfeinert:
PHP-Code:
public function indexAction($orderByColumn$orderByDirection$page) {
        
$em $this->getDoctrine()->getEntityManager();

        
$customers $em->getRepository('AcmeAppBundle:Customer')
            ->
findAllOrderedBy($orderByColumn$orderByDirection);

        
$paginator = new Paginator($customers5);
        
$customersPaged $paginator->getCurrentPage($page);
        
$pageIndex $paginator->getPageIndex();

        return 
$this->render('AcmeAppBundle:Customer:index.html.twig', array(
           
'customers' => $customersPaged,
            
'pageIndex'    => $pageIndex,
        ));


    } 
PHP-Code:
class Paginator {
    protected 
$limit;
    protected 
$pages;
    protected 
$entity;

    public function 
__construct($entity$limit) {
        
$this->entity $entity;
        
$this->limit $limit;
        
$this->getPages();
    }

    public function 
getCurrentPage($currentPage) {
        if (
$currentPage || $currentPage $this->pages) {
            
$currentPage 1;
        }
        
$offset $this->limit * ($currentPage 1);
        
$length $offset $this->limit;
        return 
array_slice($this->entity$offset$length);
    }

    protected   function 
getPages() {
        
$this->pages ceil(count($this->entity) / $this->limit);
    }

    public function 
getPageIndex() {
        
$pageIndex = array();
        for (
$i 1$i $this->pages +1$i++) {
            
$pageIndex[] = $i;
        }
        if (
$this->pages 4) {
            
$pageIndex[] = '... ' $this->pages;
        }
        return 
$pageIndex;
    }


  Mit Zitat antworten
Alt 01.02.2012, 20:48  
archer42
Gast
 
Beiträge: n/a
Standard

Wie könnte ich nun das Umschalten zwischen ASC und DESC lösen?
Clientseitig (Javascript(jQuery)) der Serverseitig(Allerdings mit langer Rede kurzer Sinn)?

Sollte die Paginierung (Limitierung) über MySQL gelöst werden?
Würde die Performance minimal erhöhen allerdings auf Kosten der Flexibilität
  Mit Zitat antworten
Alt 01.02.2012, 22:55  
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

Zitat:
Zitat von archer42 Beitrag anzeigen
Würde die Performance minimal erhöhen allerdings auf Kosten der Flexibilität
Minimal? Ähem... an was für ein Einsatzgebiet dachtest du denn? Davon sind dann auch Fragen wie "sortieren client- oder serverseitig" abhängig.

Zitat:
Sollte ich den DBAL Teil aus dem Paginator entfernen und im Controller belassen?
IMHO hat die Pagination nichts direkt mit der Datenbank zu schaffen, das würde ich also auf jeden Fall entkoppeln. Du siehst ja schon, zu was für einer unnötigen Einschränkung bezüglich des Queries das geführt hat. Für Sortierung ist der Paginator dann auch so und so nicht mehr zuständig.
fab ist offline   Mit Zitat antworten
Alt 01.02.2012, 23:31  
Erfahrener Benutzer
 
Registriert seit: 28.05.2008
Beiträge: 2.094
PHP-Kenntnisse:
Fortgeschritten
rudygotya ist einfach richtig nettrudygotya ist einfach richtig nettrudygotya ist einfach richtig nettrudygotya ist einfach richtig nettrudygotya ist einfach richtig nett
Standard

Zitat:
IMHO hat die Pagination nichts direkt mit der Datenbank zu schaffen, das würde ich also auf jeden Fall entkoppeln.
Wie entkoppelst du diese 2 Dinge? Heißt das, du holst dir immer den kompletten Ergebnissatz ohne offset?

@archer42:
Php validieren lassen, bei nicht vorhanden values würde ich mit default-Werten für die Sortierung verwenden (bspw. offset 1 + 2, order by ), dann meinen Modellayer füttern und meinen controller ausliefern lassen, was der zurückliefert.
__________________
++++ Wieder einer ins Netz gegangen: Phishers Fritz zufrieden ++++
Blog
rudygotya ist offline   Mit Zitat antworten
Alt 02.02.2012, 00:35  
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

Zitat:
Zitat von rudygotya Beitrag anzeigen
Wie entkoppelst du diese 2 Dinge? Heißt das, du holst dir immer den kompletten Ergebnissatz ohne offset?
Auf keinen Fall! Das hatte ich ja schon mit dem ersten Teil meiner Antwort angedeutet...

Für mich sind Pagination und Abholen der Daten einfach zwei Paar Schuhe, ersteres ist dabei nur eine Angelegenheit der Präsentations-Schicht.

Das heißt, bei mir kennt ein Paginations-Model nicht mal die konkreten Datensätze sondern nur die Meta-Informationen (Anzahl Daten, Anzahl Seiten, aktuelle Seite, Daten pro Seite,...). Diese können dann gleichermaßen zum konstruieren der Datenbank-Abfrage als auch zur Anzeige der Pagination (also der Navigations-Elemente) verwendet werden.

Edit: das war etwas unklar ausgedrückt, also hier einmal visuell:
Code:
+------------+  <<use>> +------+
| Pagination |<---------| View |
+------------+          +------+
      ^                     |
      |<<create>>           |<<use>>
      |                     v
+------------+          +------------------+
| Controller |----------| EntityCollection |
+------------+          +------------------+
      |
      |<<use>>
      v           - Controller erstellt Pagination basierend auf Eingabe
+------------+    - Controller holt Daten (DB-Abfrage passiert ganz woanders)
| Data Layer |    - Controller aktualisiert Pagination basiert auf tatsächlicher Anzahl
+------------+    - View greift auf Pagination und Daten unabhängig voneinander zu

Geändert von fab (02.02.2012 um 00:51 Uhr).
fab ist offline   Mit Zitat antworten
Alt 02.02.2012, 09:38  
archer42
Gast
 
Beiträge: n/a
Standard

Zitat:
Minimal? Ähem... an was für ein Einsatzgebiet dachtest du denn? Davon sind dann auch Fragen wie "sortieren client- oder serverseitig" abhängig.
Clientseitig hatte ich vorher übergangsweise benutzt. Ist natürlich was die Einträge angeht begrenzt.
Wie würde den eine Pagination über MySQL aussehen?
Welche Werte bräuchte man von MySQL (Anzahl Einträge - Was noch?)

Zitat:
Php validieren lassen, bei nicht vorhanden values würde ich mit default-Werten für die Sortierung verwenden (bspw. offset 1 + 2, order by ), dann meinen Modellayer füttern und meinen controller ausliefern lassen, was der zurückliefert.
Für die Seitenanzahl geschieht das schon, für das Umschalten zwischen ASC und DESC, sowie die Validierung der Spalte könnte man ein array mit dem deutschen Spaltennamen, den Variabelnamen (firstName...) und dem Modus (ASC). Nun werden die Routing parameter auf vorhanden sein geprüft, sowie ASC == ASC wird zu DESC usw. das Array wird dann über foreach im Tabellenkopf abgebildet. Lange rede kurzer Sinn. Wie durchsuche ich dieses array nach $orderByColumn (array_search gilt nur für eindimensionalle Arrays):
PHP-Code:
 $columns = array(
        
'id' => array('name' => 'ID''order' => 'asc'),
        
'lastName' => array('name' => 'Nachname''order' => 'asc'),
        
'firstName' => array('name' => 'Vorname''order' => 'asc'),
        
'birth' => array('name' => 'Geb.''order' => 'asc'),
        
'street' => array('name' => 'Straße''order' => 'asc'),
        
'nr' => array('name' => 'Nr.''order' => 'asc'),
        
'zipCode' => array('name' => 'PLZ''order' => 'asc'),
        
'email' => array('name' => 'Email''order' => 'asc'),
        
'phone' => array('name' => 'Telefon''order' => 'asc'),
        
'mobile' => array('name' => 'Mobil''order' => 'asc'),
        ); 
Zitat:
Das heißt, bei mir kennt ein Paginations-Model nicht mal die konkreten Datensätze sondern nur die Meta-Informationen (Anzahl Daten, Anzahl Seiten, aktuelle Seite, Daten pro Seite,...). Diese können dann gleichermaßen zum konstruieren der Datenbank-Abfrage als auch zur Anzeige der Pagination (also der Navigations-Elemente) verwendet werden.
Das stellt aufjedenfall den besseren Style dar. Welche Parameter übergebst du dabei dabei der Pagination bzw. aus was berechnest du die Seiten?

Geändert von archer42 (02.02.2012 um 09:43 Uhr).
  Mit Zitat antworten
Alt 02.02.2012, 09:39  
Erfahrener Benutzer
 
Registriert seit: 26.05.2008
Beiträge: 200
PHP-Kenntnisse:
Fortgeschritten
[-UFO-]Melkor befindet sich auf einem aufstrebenden Ast
Standard

Also mir wäre dein Paginator viel zu unflexibel. Wenn ich die angezeigten Datensätze irgendwie einschränken müsste, bräuchte ich ja direkt wieder einen neuen Paginator. Ich würde eher eine Doctrine\ORM\Query Objekt übergeben. Der Paginator braucht sich dann nur noch darum zu kümmern der Query die Limits mitzuteilen (setFirstResult(), setMaxResults()) und die Query auszuführen.
__________________
Programming PHP
[-UFO-]Melkor ist offline   Mit Zitat antworten
Alt 02.02.2012, 09:56  
Erfahrener Benutzer
 
Benutzerbild von tr0y
 
Registriert seit: 26.07.2010
Beiträge: 4.874
PHP-Kenntnisse:
Fortgeschritten
tr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblicktr0y ist ein wunderbarer Anblick
tr0y eine Nachricht über MSN schicken
Standard

Ein Paginator stellt nichts dar und bestellt auch keine Daten, er limitiert eine Anzahl an verfügbaren Daten aufgrund eines Offsets und einer maximalen Anzahl an Einträgen und gibt diesen Ausschnitt weiter. Ein Paginator ist also ein Filter-Konstrukt das auf eine Existierende Menge Daten angewendet wird.

Mögliche Fälle von Pagination:
- Pagination via Javascript ohne Nachladen von Content: Der Paginator selbst ermittelt hier nur die Gruppierung der Daten und teilt dem View mit das es eine neue "Pseudo-Page" gibt
- Pagination via Javascript mit Nachladen von Content oder Pagination via normalem Request: Der Paginator kennt hier die Offset und Max-Count-Per-Page-Daten und gibt diese bspw. an ein Model weiter, das wiederum die bestellte Menge im jeweiligen Offset an den Paginator weitergibt, jener wirft diese dann dem View hin zum darstellen.

Einem flexiblen Paginator ist es egal ob du ihm ein Array mit Daten als Grundlage stellst, ein Datenbank-Repository, ein ResultSet aus einem Model, ein Sprite-Grid oder sonstwas. Er extrahiert nur beginnend mit einem offset eine (maximale) Menge X aus einem Datenpool Y.
__________________
Lasse mir ohne Anwendung von Gewalt Dinge schenken, Amazon weiß darüber bald mehr.
tr0y ist offline   Mit Zitat antworten
Alt 02.02.2012, 10:20  
archer42
Gast
 
Beiträge: n/a
Standard

Ich schätze mal, dass das die "beste" Lösung darstellt:
Zitat:
Pagination via Javascript mit Nachladen von Content
Kann mir jemand für solche Fälle ein Ajax(+Symfony2) Tutorial empfehlen?
  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
jquery zwei voneinander abhängige pagination, paginator, archer42 rudygotya

Alle Zeitangaben in WEZ +2. Es ist jetzt 22:55 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