vielleicht ist es ja nicht nur mir aufgefallen, daß wenn man durch große Datenbestände blättern will, z.B. bei den eingerichteten Usern, es sehr lange dauert bis etwas angezeigt wird. Das liegt hauptsächlich daran, daß erst alle Benutzer aus der Datenbank ausgelesen werden und danach nur eine bestimmte Anzahl angezeigt wird.
Folgende Klasse schafft da Abhilfe. Um sie zu nutzen muss der Code natürlich angepasst werden, ist aber nicht allzu wild. Zuerst wird ganz normal eine Klasse von Typ ItemCollection (oder eine Abgeleitete) initialisiert, und die Sortierreihenfolge, etc. gesetzt.
Dann kann mittels der Funktion queryFromItemCollection der neuen Klasse das Ergebnis generiert werden. Die Sortierung und Limitierung übernimmt hier die Datenbank. Das Ergebnis wird in der _data Variable der Klasse gespeichert und kann weiterverwendet werden.
Der Code ist relativ gut dokumentiert und kann auch mittels Doxygen ausgelesen werden.
Klasse FastBackendList:
Code: Alles auswählen
<?php
/** Klasse fastBackendScrollList
*
* Eigene Implementierung im Stil der cScrollList (nur schneller)
*
* @author Florian Born
*/
class fastBackendScrollList extends cScrollList
{
var $query; ///< Speichert die DB-Abfrage zum Erstellen der Liste
var $db; ///< Datenbankinstanz zum Ausführen der Query
var $recordCount; ///< Speichert Anzahl der Datensätze
var $recordsPerPage; ///< Anzahl der Einträge pro Seite
var $currentPage; ///< Aktuelle Seite
var $numPages; ///< Anzahl der Seiten
/** Konstruktor
* \param rpp Integer recordsPerPage - Anzahl der Einträge pro Seite - Standard = 25
*/
function fastBackendScrollList($rpp = 25)
{
parent::cScrollList();
$this->db = new DB_Contenido();
$this->recordsPerPage = $rpp;
$this->currentPage=1;
}
/** Aktuelle Seite zum anzeigen angeben
* \param page Integer
*/
function setCurrentPage($page)
{
$this->currentPage = $page;
}
/// Gibt aktuelle Seite zurück
function getCurrentPage()
{
return $this->currentPage;
}
/// Gibt die Gesamtseitenanzahl zurück
function getNumPages()
{
return $this->numPages;
}
/** Anzahl der Einträge pro Seite setzen
* \param rpp Integer
*/
function setResultsPerPage($rpp)
{
$this->recordsPerPage = $rpp;
}
/** Query setzen
* \param query String Komplette Abfrage (SELECT ... FROM ... WHERE ... [GROUP|ORDER] BY)
*/
function setQuery($query)
{
$this->query = $query;
}
/** Holt die Ergebnisse
* \param oCol ItemCollection
* Original Code von Timo Hummel, four for business AG (www.4fb.de)
*/
function queryFromItemCollection($oCol)
{
$groupWhereStatements = $oCol->_buildGroupWhereStatements();
$whereStatements = $oCol->_buildWhereStatements();
$parameters = $oCol->_fetchJoinTables(get_class($oCol));
$statement = array( "SELECT",
"*",
"FROM",
$oCol->table . " AS ".strtolower(get_class($oCol)));
if (count($parameters["tables"]) > 0)
{
$statement[] = implode(", ", $parameters["tables"]);
}
if (count($parameters["joins"]) > 0)
{
$statement[] = implode(" ", $parameters["joins"]);
}
$wheres = array();
if (count($parameters["wheres"]) > 0)
{
$str = implode(", ", $parameters["wheres"]);
$wheres[] = str_replace('%25','%',$str);
}
if ($groupWhereStatements != "")
{
$str = $groupWhereStatements;
$wheres[] = str_replace('%25','%',$str);
}
if ($whereStatements != "")
{
$str = $whereStatements;
$wheres[] = str_replace('%25','%',$str);
}
if (count($wheres) > 0)
{
$statement[] = "WHERE ".implode(" AND ", $wheres);
}
if ($oCol->_order != "")
{
$statement[] = "ORDER BY ".$oCol->_order;
}
$sql = implode(" ", $statement);
$this->query = $sql;
$this->getResults(false);
}
/** Tabellenheader setzen
* \param header Array - Bsp.: Array("Name", "Adresse", "Email", ...)
*/
function setHeader($header)
{
if (!is_array($header))
die ("Error in class ".get_class($this)."::setHeader : Übergebener Header ist kein Array");
$this->header = $header;
}
/** Interne Funktion
*/
function getLimit()
{
return ($this->recordsPerPage * ($this->currentPage-1)).",".$this->recordsPerPage;
}
/** Funktion zum generieren der Tabelle mit Header und Seitenwechsellinks
* wird direkt von QueryFromItemCollection aufgerufen
* \param return bool Ausgabe zurückgeben oder in interne Variable speichern? Standard = speichern
*/
function getResults($return = false)
{
$this->db->query($this->query);
$this->recordCount = $this->db->num_rows();
if ($this->recordCount > $this->recordsPerPage)
$this->db->query($this->query." LIMIT ".$this->getLimit());
$this->numPages = ceil($this->recordCount / $this->recordsPerPage);
$this->query = $this->query." LIMIT ".$this->getLimit();
$cnt = 0;
while ($this->db->next_record())
{
$arr = $this->db->copyResultToArray();
foreach ($arr as $key => $value)
{
$arr[$key] = urldecode($value);
}
$resultArr[$cnt] = $arr;
$cnt++;
}
if ($return)
return $resultArr;
else
$this->_data = $resultArr;
}
function getNumResults()
{
return $this->recordCount;
}
/* Sollte nicht mehr gebraucht werden
function updateCScrollList($oSL)
{
if (get_class($oSL) != 'cscrolllist')
die ("Falsche Klasse für updateCScrollList. Muss vom Typ cScrollList sein");
else
{
//$oSL->listStart = $this->currentPage;
$oSL->numPages = $this->numPages;
return $oSL;
}
}
*/
}
?>
Code: Alles auswählen
$oList = new fastBackendScrollList;
// set paging
if ($_GET['action'] == 'pageNav')
{
$oList->setCurrentPage($_GET['page']);
} else
{
$oList->setCurrentPage(1);
}
$oList->setResultsPerPage(25);
$oTeile = new tApiTeileverwaltung;
$oTeile->setWhere('tApiTeileverwaltung.idclient', $client);
...
$header = Array('Spalte1', 'Spalte2',...);
$oList->setHeader($header);
$oList->queryFromItemCollection($oTeile);
if ($oList->getNumResults() == 0)
{
$oList->setData(0, 'keine Daten',...);
}
else
{
$cnt = 0;
foreach ($oList->_data as $key => $value)
{
$oList->setData($cnt, $value['data1'], $value['data2'], ...);
$cnt++;
}
}
$oList->render();