Hey PHP-ers,

Vandaag heb ik mijn eerste OOP script geschreven.
Zouden jullie mij feedback kunnen geven op de code? Is het misschien iets voor in het script library?

Hier is het script
<?php
class Pagination {
/*
usage:
$pagination = new Pagination($qry, "index.php?page=overzicht", $itemsPerPage, $numbersLeftNav);
options
$pagination->firstLabel = '<< eerste';
$pagination->prevLabel = '< vorige';
$pagination->nextLabel = 'volgende >';
$pagination->lastLabel = 'laatste >>';


render each item
echo $pagination->renderFirst().' ';
echo $pagination->renderPrev().' ';
foreach($pagination->renderLeftNav() as $key => $val) {
echo $val.' ';
}
echo $pagination->renderCurrentNav().' ';
foreach($pagination->renderRightNav() as $key => $val) {
echo $val.' ';
}
echo $pagination->renderNext().' ';
echo $pagination->renderLast();


or render all items
echo $pagination->render();

foreach ($pagination->getRecords() as $key => $row) {
echo strip($row["naam"]);
}
*/
public $firstLabel = '<< first';
public $lastLabel = 'last >>';
public $nextLabel = 'volgende >';
public $prevLabel = '< vorige';
protected $_sql = '';
protected $_itemsPerPage = '';
protected $_allRecords = '';
protected $_allPages = '';
protected $_append = ''; // items in the nav on the left and right from the current
protected $_currentPage = '';

public function __construct($_sql, $_self, $_items_per_page = 10, $_append = 3) {
$this->_sql = $_sql;
$this->_self = $_self;
$this->_itemsPerPage = $_items_per_page;
$this->_append = $_append;
if (!isset($_GET["pagination"]) || (isset($_GET["pagination"]) && !is_numeric($_GET["pagination"]))) {
if (preg_match("/\?/", $this->_self)) {
header("Location: ".$this->_self."&pagination=1&limit=".$this->_itemsPerPage);
}
else {
header("Location: ".$this->_self."?pagination=1&limit=".$this->_itemsPerPage);
}
}
else {
$this->_currentPage = $_GET["pagination"];
}
}

protected function database() {
include '../inc/connect.php';
$output = array();
$sql = $this->_sql;

$all_records = $db->query($sql);
if ($all_records == TRUE) {
$this->_allRecords = $all_records->num_rows;
$this->_allPages = ceil($this->_allRecords / $this->_itemsPerPage);
}
else {
return 'Error: '.$db->error;
}

$start = $this->_currentPage * $this->_itemsPerPage - $this->_itemsPerPage;
$sql .= "LIMIT ".$start.", ".$this->_itemsPerPage;

$sql = $db->query($sql);
if ($sql == TRUE) {
while ($row = mysqli_fetch_assoc($sql)) {
$output[] = $row;
}
return $output;
}
else {
return 'Error: '.$db->error;
}
}

public function renderFirst() {
if ($this->_currentPage != 1) {
return '<a href="'.$this->_self.'&pagination=1&limit='.$this->_itemsPerPage.'">'.$this->firstLabel.'</a>';
}
}

public function renderPrev() {
$prev = $this->_currentPage - 1;
if ($prev != 0) {
return '<a href="'.$this->_self.'&pagination='.$prev.'&limit='.$this->_itemsPerPage.'">'.$this->prevLabel.'</a>';
}
}

public function renderLeftNav() {
$this->database();
$current = $this->_currentPage;
$navLeft = array();

if ($this->_currentPage > 1) {
$i = 0;
while($i != $this->_append) {
$i++;
$current--;
if ($current >= 1) {
$navLeft[] = '<a href="'.$this->_self.'&pagination='.$current.'&limit='.$this->_itemsPerPage.'">'.$current.'</a>';
}
}
asort($navLeft);
}
return $navLeft;
}

public function renderCurrentNav() {
return $this->_currentPage; // output current page
}

public function renderRightNav() {
$this->database();
$current = $this->_currentPage;
$navRight = array();

if ($this->_currentPage < $this->_allPages) {
$i = 0;
while($i != $this->_append) {
$i++;
$current++;
if (($current -1) != $this->_allPages && ($current -1) < $this->_allPages) {
$navRight[] = '<a href="'.$this->_self.'&pagination='.$current.'&limit='.$this->_itemsPerPage.'">'.$current.'</a>';
}
}
}
return $navRight;
}

public function renderNext() {
$next = $this->_currentPage + 1;
if (($next - 1) != $this->_allPages) {
return '<a href="'.$this->_self.'&pagination='.$next.'&limit='.$this->_itemsPerPage.'">'.$this->nextLabel.'</a>';
}
}

public function renderLast() {
if ($this->_currentPage != $this->_allPages) {
return '<a href="'.$this->_self.'&pagination='.$this->_allPages.'&limit='.$this->_itemsPerPage.'">'.$this->lastLabel.'</a>';
}
}

public function getRecords() {
return $this->database();
}

public function render() {
$output = '';

$output .= $this->renderFirst().' ';

$output .= $this->renderPrev().' ';

foreach($this->renderLeftNav() as $key => $val) {
if ($val <= $this->_allPages) {
$output .= $val.' ';
}
}
$output .= $this->renderCurrentNav();
foreach($this->renderRightNav() as $key => $val) {
if ($val <= $this->_allPages) {
$output .= ' '.$val;
}
}

$output .= ' '.$this->renderNext().' ';

$output .= $this->renderLast();
return $output;
}
}
?>

Bedankt alvast!
Maar ook Zend Framework heeft een paginator: http://framework.zend.com/manual/2.0/en/modules/zend.paginator.introduction.html En YII, Lithium, ect. zullen ze ook wel hebben.
Hij vraagt of zijn script goed is, niet of je een andere Paginator weet...
[hr]
Joost, het is een leuke klasse, maar heeft nu nog niks met OO te maken. In OO is er 1 belangrijke regel waarin je je altijd moet houden: Elke klasse en elke method heeft maar 1 verantwoordelijkheid, zijn er meerdere dan splits je hem op. Je Paginator klasse heeft nu enorm veel verantwoordelijkheden: Hij maakt connectie met database, houdt items vast, zorgt voor het renderen, zorgt voor de pagination, ect. Dat moet allemaal in een eigen klasse gedaan worden.

Nu heeft Pim een tijdje geleden een erg mooi opzetje gemaakt voor een Paginator in OO. Kijk eens naar dat opzetje, of je het begrijpt en of je hem af kunt maken: http://www.phphulp.nl/php/forum/topic/paginering-oop/84869/#605327 (eventuele uitleg)
Thnx voor jullie reacties!

@Wouter, ik kan wel kijken naar het script, maar ik snap dat abastract en implements nog niet helemaal.
Ik zal er nog wat op door moeten leren voordat ik het OOP goed begrijp, het is allemaal nog een beetje onduidelijk voor me, vind het ook best moeilijk om te snappen moet ik eerlijk zeggen.

Maargoed, komt vast goed, blijven oefenen en lezen :D
Iemand misschien nog wat goed materiaal? Boek, tutorials of wat dan ook?
Okee, ik jullie feedback doorgenomen en ben dan dus maar begonnen met het maken van een Database class.
Ondertussen ben ik een boek aan het doornemen wat ik van een collega heb gekregen. Het boek gaat over het object georiƫnteerd programmeren in de taal Java.

Dit is de code die ik tot nu toe heb voor het maken van de Database class:
<?php
class Database {
private $_db;
private $_host;
private $_user;
private $_password;
private $_dbName;

protected $_result;
protected $_qry;
protected $_qryArray = array();

/*
Construct and optionally connect to database
*/
public function __construct($_CONFIG) {
if (isset($_CONFIG["db"]["connect"]) && extract($_CONFIG["db"]["connect"])) {
$this->_host = $host;
$this->_user = $user;
$this->_password = $password;
$this->_dbName = $db;
}
$this->_connect();
}

/*
connect to database and use parameters from class
*/
private function _connect() {
$this->_db = mysqli_connect($this->_host, $this->_user, $this->_password, $this->_dbName);
if (!$db->connect_errno) {
return TRUE;
}
}
/*
escapes string if magic quotes = off
@return string escaped string
*/
private function _add($string) {
if (get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
if (!is_numeric($string) && !preg_match("/{(.*?)}/", $string)) {
$string = "'".mysqli_real_escape_string($this->_db, $string)."'";
}
if (preg_match("/{(.*?)}/", $string)) {
$string = mysqli_real_escape_string($this->_db, $string);
}
return $string;
}

/*
Sets Query parameters
@param $qry SQL
@sets var qry
@sets array qryArray
*/
public function setQry($qry) {
$this->_qryArray = array();
$arg_list = func_get_args();
for ($i = 0; $i < func_num_args(); $i++) {
if ($i == 0) {
$this->_qry = $arg_list[$i];
}
else {
$this->_qryArray[] = $this->_add($arg_list[$i]);
}
}
$this->_query();
}

/*
Gets parameters and make nice Query
@sets var qry
*/
private function getQry() {
foreach ($this->_qryArray as $name => $val) {
$this->_qry = preg_replace("/\?/", $val, $this->_qry, 1);
}
$this->_qry = preg_replace("/{(.*?)}/", "\$1", $this->_qry, -1);
}

/*
excecutes query
*/
private function _query() {
$this->getQry();
$this->_result = $this->_db->query($this->_qry);
if ($this->_result == FALSE) {
trigger_error("Error: ".$this->_db->error);
}
}

/*
Get single result [SQL: LIMIT 0, 1]
@param $qry SQL
@return string $rows => all rows
*/
public function getRow() {
return mysqli_fetch_assoc($this->_result);
}

/*
Get several rows from database
@param $qry SQL
@return array $rows => all rows
*/
public function getRows() {
while ($rows = mysqli_fetch_assoc($this->_result)) {
$row[] = $rows;
}
return $row;
}

/*
Get num rows from last query
@return int num_rows
*/
public function numRows() {
return $this->_result->num_rows;
}

/*
Get num rows from last query
@return int num_rows
*/
public function affectedRows() {
return $this->_db->affected_rows;
}

}
?>

en dan uiteraard het index.php bestand


<?php
include 'class/config.php';
include 'class/database.class.php';
?>
<h1>Home</h1>
<?php
$db = new Database($_CONFIG);



$db->setQry("SELECT * FROM gebruikers ORDER BY ? ASC", "{voornaam}");
$rows = $db->getRows();
echo 'Aantal records: '.$db->numRows().'<br />';

foreach ($rows as $row) {
	echo $row["voornaam"].' '.$row["achternaam"].' - '.$row["email"].'<br />';
}





echo '<hr />';


$sql = "SELECT * FROM gebruikers WHERE id = ? AND achternaam = ?";
$id = 4;
$achternaam =  "van der Test";
$db->setQry($sql, $id, $achternaam);
$row = $db->getRow();
echo $row["voornaam"];


echo '<hr />';





$test = "test van der Test";
$db->setQry("UPDATE gebruikers SET naam = 'test van der Test' WHERE naam = ?", $test);
echo 'Affected rows: '.$db->affectedRows();
?>


Ik hoop dat het er nu al wat meer op lijkt, het ziet er misschien simpel uit maar ben er best lang mee bezig geweest.
Hopelijk hebben jullie weer wat feedback waarmee ik mezelf kan verbeteren :)

Reageren