PHP ile MySQL Verilerini Sayfalama Sınıfı

Sniper tarafından 14 Haziran 2009 tarihinde yazıldı.

Bir site ya da projeye başladığımda, yazması en sıkıcı gelen işlerin başında veri sayfalama gelir. Her seferinde sayfalama işlemlerini bu yüzden en sona bırakırım. Daha önceki sayfalama makalelerimi okuduysanız hep karmaşık kodlardan oluştuğunu görebilirsiniz. Her seferinde bu kodları tekrar tekrar yazmak nedendir bilmem beni hep bunaltmıştır, öyle ki kopyala-yapıştır bile angarya gelir. Buna bir son vermem gerektiğini düşünüp, hazır OOP programlamaya kendimi alıştırmaya başladığım şu zamanlarda bununla ilgili bir sınıf yazmak istedim ve birşeyler karaladım. Benim can sıkıntımı fazlasıyla ortadan kaldıran bir sınıf hazırladım ve bunu sizlerle paylaşmak istedim.

Sınıfıma SAYFALAYICI ismini verdim. 3 temel özelliğe değer atadıktan sonra bir fonksiyon çalıştırarak istediğim aralıktaki kayıtlara ulaşabiliyor, dolayısıyla sayfalama işlemlerini daha rahat bir şekilde icra edebiliyorum. Özellik isimlendirmede eski bir ASP’ci olarak Recordset nesneleriyle benzer isimler kullandım. Sınıf dosyasını ve örnek uygulamayı buraya tıklayarak indirebilirsiniz. Örnek uygulamanın çalışır halini görmek için ise buraya tıklayabilirsiniz.

Örnek uygulamaya geçmeden önce sınıfımın özellik ve metodlarını kısaca tanımlayayım. Sınıf 8 özellik ve 1 metoddan oluşuyor.

  • sorgu: İşlenecek SQL cümleciği bu özelliğe atanmalıdır. Dikkat edilmesi gereken tek husus SQL cümleciği içinde kesinlikle LIMIT kullanılmamasıdır. Sınırlamayı sınıf kendi içinde halledecektir.
  • pageSize: Bir sayfada gösterilmek istenen kayıt sayısı bu özellikte belirtilir.
  • absolutePage: Halihazırda gösterilecek olan sayfanın numarası burada tanımlanır.

Bu 3 özelliğe değer atandıktan sonra sayfala() metodunun çağırılması verilerin düzenlenmesi için yeterlidir. Bundan sonraki özellikler sadece okunabilir. Üzerine yazmaya zorlarsanız kodların çalışmasında hata oluşabilir. (OOP metoduyla kod yazmaya yeni başladığımdan sadece okunabilir bir özellik tanımlamayı henüz bilmiyorum.)

  • recordCount: Uygulanan işlem sonucunda dönen kayıtların toplam sayısını verir.
  • veri: Uygulanan işlem sonucunda aralığı belirlenmiş kayıtlar bu özelliğe depolanır. Bu özellik dizi türünde olup, eleman isimleri tablonun alan isimleriyle aynıdır.
  • EOF: Döngüyle uygulandığında kayıt setinde yeni bir kaydın olup olmadığını gösterir. Kayıt varsa 1, yoksa 0 değeri döndürür.
  • pageCount: Uygulanan işlem sonucunda kaç sayfanın oluştuğunu gösterir.
  • recordRange: O anda gösterilmekte olan kayıt aralığını belirtir. (Örn: 1-10, 21-28, 42-50)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
< ?php
/**
 * @author 		Tuncay KINALI ( Sniper ) <tkinali [at] hotmail [dot] com>
 * @copyright 		2009
 * @filename 		sayfalayici.class.php
 * @version		0.1
 *
 * MySQL verilerini sayfalama sınıfı
 *
 * Copyright 2009 tuncay.kinali.net
 * Licensed under the GNU General Public License, version 2.
 * See the file http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
 */
 
class SAYFALAYICI {
	/**
	 * @param 	recordCount	İşlenen sorgu sonrası dönen kayıtların toplamını verir.
	 */
	public $recordCount;
 
	/**
	 * @param 	pageSize	Sonuçların kaçar adetlik sayfalara bölüneceğini belirtir.
	 */
	public $pageSize = 1000;
 
	/**
	 * @param 	absolutePage	Gösterilmek istenen sayfa numarasını belirtir.
	 */
	public $absolutePage = 1;
 
	/**
	 * @param 	sorgu	Sorgulanacak SQL cümleciği burada belirtilir.
	 */
	public $sorgu;
 
	/**
	 * @param 	veri	SQL cümleciği işletildikten sonra dönen kayıtlar bu özelliğe atanır. Okuma bu özellik üzerinden yapılır.
	 */
	public $veri;
 
	private $topRS;
	private $tmpSQL;
 
	/**
	 * @return	Kendisi bir değer döndürmez fakat işlenen SQL cümleciğinin döndürdüğü kayıtları hafızaya alır.
	 */
	public function sayfala() {
		try {
			$this->topRS = @mysql_query($this->sorgu);
 
			if(!$this->topRS) {
				throw new Exception('SQL sorgusu işlenemedi');
			}
 
			$this->recordCount = mysql_num_rows($this->topRS);
 
			if($this->pageSize>0) {
				$this->tmpSQL = @mysql_query($this->sorgu . ' LIMIT ' . (($this->pageSize*$this->absolutePage)-($this->pageSize)) . ', ' . $this->pageSize);
			} else {
				$this->tmpSQL = @mysql_query($this->sorgu);
			}
		} catch(Exception $e) {
			echo('Bir hata oluştu: '. $e);
		}
	}
 
	function __get($isim) {
		switch($isim) {
			/**
			 * @param	EOF	Elden geçirilmiş SQL cümleciğini işletir, kayıt bulunursa kaydı $veri özelliğine atar ve 1 (TRUE) değer döndürür. Kayıt bulunamazsa 0 (FALSE) değer döndürür
			 */
			case 'EOF':
				return(($this->veri = mysql_fetch_assoc($this->tmpSQL)) ? 0 : 1);
				break;
 
			/**
			 * @param	pageCount	İşlenen SQL cümleciği sonucunda kaç sayfanın oluştuğu bilgisini verir.
			 */
			case 'pageCount':
				$sayfa = preg_replace('/[^0-9]+/mis', '.', strval($this->recordCount/$this->pageSize));
				$sayfa = strpos($sayfa, '.')===FALSE ? $sayfa : intval(substr($sayfa, 0, strpos($sayfa, '.')))+1;
				return($sayfa);
				break;
 
			/**
			 * @param	recordRange	Gösterilmekte olan kayıtların aralığını verir. Örn: <strong>1-10</strong>, <strong>15-19</strong> gibi.
			 */
			case 'recordRange':
				$ilk = (($this->pageSize*$this->absolutePage)-($this->pageSize))+1;
				$son = $this->recordCount > (($ilk-1)+$this->pageSize) ? (($ilk-1)+$this->pageSize) : $this->recordCount;
				return($ilk < = $this->recordCount ? $ilk.' - '.$son : '');
				break;
		}
	}
}
?>

Örnek uygulamada kullanmak üzere kütüphanemdeki kitapları, yazarlarını ve yayın evlerini bir veritabanında topladım. Bunu söylerken utanmalı mıyım bilmiyorum ama sizin de göreceğiniz üzere kütüphanemde bilgisayar ve bilişim dışında hiç kitap yok. Veritabanı yapısı ve içeriği şöyle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
-- MySQL Administrator dump 1.4
--
-- ------------------------------------------------------
-- Server version	5.0.75-0ubuntu10.2
 
 
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
 
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
 
 
--
-- Create schema sniper
--
 
CREATE DATABASE IF NOT EXISTS sniper;
USE sniper;
 
--
-- Definition of table `sniper`.`tblkitaplar`
--
 
DROP TABLE IF EXISTS `sniper`.`tblkitaplar`;
CREATE TABLE  `sniper`.`tblkitaplar` (
  `fldID` int(11) NOT NULL auto_increment,
  `fldKitapAdi` varchar(255) NOT NULL,
  `fldYazar` varchar(50) NOT NULL,
  `fldYayinEvi` varchar(50) NOT NULL,
  PRIMARY KEY  (`fldID`)
) ENGINE=MyISAM AUTO_INCREMENT=37 DEFAULT CHARSET=utf8;
 
--
-- Dumping data for table `sniper`.`tblkitaplar`
--
 
/*!40000 ALTER TABLE `tblkitaplar` DISABLE KEYS */;
LOCK TABLES `tblkitaplar` WRITE;
INSERT INTO `sniper`.`tblkitaplar` VALUES  (1,'Macromedia Flash 4 Windows ve Macintosh İçin','Katherine Ulrich','Sistem Yayıncılık'),
 (2,'Enine Boyuna Windows Server 2003','William R. Stanek','Arkadaş Yayınları'),
 (3,'Borland C++ Builder 6','İhsan Karagülle & Zeydin Pala','Türkmen Kitabevi'),
 (4,'Java SE 6','Herbert Schildt','Alfa Yayınları'),
 (5,'Java Ağ Programcılığı','Haluk Gümüşkaya & Ömer Boyacı','Alfa Yayınları'),
 (6,'Javascript Örnekleri','Mehmet Eğitmen','Alfa Yayınları'),
 (7,'C/C++ Programcının Rehberi','Chris H. Pappas & William H. Murray','Sistem Yayıncılık'),
 (8,'Nesne Yönelimli C++ Programlama Kılavuzu','Robert Lafore','Alfa Yayınları'),
 (9,'Visual Basic.Net ile Yazılım Geliştirme','Prof. Dr. Mithat Uysal','Beta Yayınları'),
 (10,'Swing','Herbert Schild','Alfa Yayınları'),
 (11,'ASP.Net','Zafer Demirkol','Pusula Yayıncılık'),
 (12,'Java Programlama Dili Yazılım Tasarımı','Altuğ B. Altıntaş','Papatya Yayıncılık'),
 (13,'Visual Basic 6.0','İhsan Karagülle & Zeydin Pala','Türkmen Kitabevi');
INSERT INTO `sniper`.`tblkitaplar` VALUES  (14,'Macromedia Flash 5 Windows ve Macintosh İçin','Katherine Ulrich','Sistem Yayıncılık'),
 (15,'Macromedia Freehand MX','Patti Schuzle','Macromedia Press'),
 (16,'PHP 5','Mehmet Şamlı','Pusula Yayıncılık'),
 (17,'ASP ile Web Programcılığı ve Elektronik Ticaret','Zafer Demirkol','Pusula Yayıncılık'),
 (18,'Görsel İletişim ve Grafik Tasarım','Tevfik Fikret Uçar','İnkılap Yayınevi'),
 (19,'ASP.Net','Mehmet Nuri Çankaya','Seçkin Kitabevi'),
 (20,'Linux Doktoru','Görkem Çetin','Seçkin Kitabevi'),
 (21,'Linux Ağ Yönetimi','Görkem Çetin & Barış Metin','Seçkin Kitabevi'),
 (22,'Flash Web Tasarımı','Hillman Curtis','Alfa Yayınları'),
 (23,'Macromedia Dreamweaver 8','Osman Gürkan','Nirvana Yayıncılık'),
 (24,'Macromedia Flash 8.0 Professional','Osman Gürkan','Nirvana Yayıncılık'),
 (25,'Macromedia Fireworks 8','Osman Gürkan','Nirvana Yayıncılık'),
 (26,'GTK+/Gnome Programlama','M. Ali Vardar','Papatya Yayıncılık'),
 (27,'Java Programlama Dili','Dr. Turhan Çoban','Fotokopi Yoluyla Çoğaltım');
INSERT INTO `sniper`.`tblkitaplar` VALUES  (28,'GTK+ 2.0 Tutorial','Tony Gale & Ian Main & the GTK Team','Fotokopi Yoluyla Çoğaltım'),
 (29,'Assembly Programlama Dili','Fehmi Noyan İsi','Fotokopi Yoluyla Çoğaltım'),
 (30,'J2ME','Asin Akdeniz','Fotokopi Yoluyla Çoğaltım'),
 (31,'Win32 Sistem Programlama Ders Notları','Kaan Arslan & Deniz Kürümoğlu','Fotokopi Yoluyla Çoğaltım'),
 (32,'MFC Ders Notları','Kaan Arslan & Deniz Kürümoğlu','Fotokopi Yoluyla Çoğaltım'),
 (33,'C++ Ders Notları','Necati Ergin','Fotokopi Yoluyla Çoğaltım'),
 (34,'Windows API Ders Notları','Kaan Arslan & Deniz Kürümoğlu','Fotokopi Yoluyla Çoğaltım'),
 (35,'Programlamaya Giriş Ders Notları','H. Turgut Uyar','Fotokopi Yoluyla Çoğaltım'),
 (36,'C++ Uygulamaları Ders Notları','Kaan Arslan & Deniz Kürümoğlu','Fotokopi Yoluyla Çoğaltım');
UNLOCK TABLES;
/*!40000 ALTER TABLE `tblkitaplar` ENABLE KEYS */;
 
 
 
 
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

Bunu kullanarak hazırladığım demo sayfanın kodları ise aşağıda:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
< ?php
// Sınıfı sayfamıza ekliyoruz.
require('sayfalayici.class.php');
 
// Veritabanı bağlantımızı kuruyoruz.
$bag = mysql_connect('localhost', 'sniper', 'sniper');
mysql_select_db('sniper');
 
// Türkçe karakterlerde sorun çıkmaması için birkaç tedbir.
mysql_query("SET NAMES 'latin5'");
 
mysql_query("SET CHARACTER SET latin5");
 
mysql_query("SET COLLATION_CONNECTION = 'latin5_turkish_ci'");
 
// Bir sayfada gösterilecek kayıt sayısını ve,
// halihazırda gösterilecek olan sayfayı öğreniyoruz.
// İki değer de girilmemişse varsayılanları atıyoruz.
$pageSize 	= is_numeric($_GET['p']) && $_GET['p']>0 ? $_GET['p'] : 10;
$sayfa 		= is_numeric($_GET['s']) && $_GET['s']>0 ? $_GET['s'] : 1;
?>
 
 
<html>
<head>
<title>Sayfalayıcı Sınıfı Demo Sayfası</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-9" />
<style type="text/css">
	body {
		font: normal normal normal 13px verdana, sans;
	}
 
	table {
		border-collapse: collapse;
		font: normal normal normal 13px verdana, sans;
	}
 
	thead td {
		background-color: #FF0000;
		color: #FFF;
		font-weight: bold;
	}
</style>
</head>
<body>
 
 
< ?php
// Sayfalayıcı sınıfımızı tanımlıyoruz
$pager = new SAYFALAYICI;
 
// Sayfalanacak verileri getirecek SQL cümleciğimizi bildiriyoruz.
$pager->sorgu = 'SELECT * FROM tblkitaplar';
 
// Bir sayfada gösterilecek kayıt sayısını bildiriyoruz.
$pager->pageSize = $pageSize;
 
// Hangi sayfanın gösterileceğini bildiriyoruz.
$pager->absolutePage = $sayfa;
 
// Yukarıdaki bilgileri kullanarak gerekli kayıt aralığını getirmesi için 'sayfala' metodumuzu çağırıyoruz.
$pager->sayfala();
?>
 
 
<table width="780" border="1" cellpadding="4">
	<thead>
		<tr>
		<td width="10">
			ID
		</td>
		<td width="400">
			Kitap Adı
		</td>
		<td width="190">
			Yazar
		</td>
		<td width="180">
			Yayın Evi
		</td>
		</tr>
	</thead>
	<tbody>
 
 
		< ?php
			/* 
			 * sayfala metodu gerekli bilgileri topladıktan sonra
			 * SQL cümleciğimizi kendi içinde düzenleyerek veritabanı
			 * üzerinde yürütür. Dönen değerleri ise 'veri' ismindeki
			 * dizi elemanına yükler. Bizim burada yapmamız gereken
			 * nesnemizi, EOF özelliğini kontrol ederek kayıtların
			 * sonuna gelene dek bir döngüye sokmak ve 'veri' elemanından
			 * verileri alıp sayfaya bastırmak.
			 * 
			 * Kodlardan da anlaşılacağı üzere 'veri' dizisinin eleman 
			 * isimleri, tablomuzun alan isimleriyle aynı olacaktır.
			 */
			while(!$pager->EOF) {
				echo('
		<tr>
		<td width="10">
			'.$pager->veri['fldID'].'
		</td>
		<td width="250">
			'.$pager->veri['fldKitapAdi'].'
		</td>
		<td width="150">
			'.$pager->veri['fldYazar'].'
		</td>
		<td width="140">
			'.$pager->veri['fldYayinEvi'].'
		</td>
		</tr>
		');
			}
		?>
 
 
		<tr>
		<td colspan="4">
			< ?php
				/*
				 * Döngüden çıktıktan sonra bazı bilgileri sayfamıza bastırmak
				 * isteyebiliriz. Benim sıkça kullandığım ve sınıfa eklediğim
				 * bilgiler şöyle:
				 *
				 * pageCount: Uygulanan işlem sonucunda toplam kaç sayfanın 
				 * oluştuğunu bu özellik ile öğrenebilirsiniz.
				 *
				 * absolutePage: Halihazırda gösterilen sayfanın numarasını verir
				 *
				 * recordCount: Uygulanan işlem sonucunda kaç kaydın bulunduğunu
				 * öğrenmek için bu özelliği okutabilirsiniz.
				 *
				 * recordRande: Gösterilen verilerin bulunan veriler arasıda hangi
				 * aralıkta olduğunu bu özellik sayesinde öğrenebilirsiniz.
				 */
				echo('<strong>' . $pager->pageCount . ' sayfa arasında <strong>'. $pager->absolutePage. '.</strong> sayfadasınız. Bulunan <strong>' . $pager->recordCount . '</strong> kaydın <strong>' . $pager->recordRange . '</strong> arası gösteriliyor.');
			?>
			&nbsp; Sayfalar: 
			<select onchange="location.href='index.php?p=<?=$pageSize?>&s='+this.options[this.selectedIndex].value">
				< ?php
					for($i=0; $i<$pager->pageCount;$i++) {
					$sel = ($i+1)==$pager->absolutePage ? ' selected="selected"' : '';
 
					echo('
				<option value="' . ($i+1) . '"' . $sel . '>' . ($i+1) . '</option>
						');
					}
				?>
			</select>
		</td>
		</tr>
	</tbody>
</table>
<br />
Bir sayfada 
<select onchange="location.href='index.php?p='+this.options[this.selectedIndex].value">
	<option value="5">5</option>
	<option value="10" selected="selected">10</option>
	<option value="15">15</option>
	<option value="20">20</option>
	<option value="25">25</option>
	<option value="30">30</option>
</select>
 kayıt göster.
</body>
</html>

Kod içerisine yorum eklediğimden burada bunları tekrar etme gereği duymadım. Yine de bir sorunuz ya da sorununuz olursa yorum yazmaktan çekinmeyin.

18 kişi bunu beğendi.

Etiketler: , ,

“PHP ile MySQL Verilerini Sayfalama Sınıfı” yazısına 7 yorum yapılmış

  1. Abi her zamanki gibi döktürmüşsün. Ellerine sağlık.

    Seni unuttuğumu sanıyorsan yanılıyorsun :) Siten hayırlı olsun :)

  2. Teşekkür ederim Ahmet’im…
    Elimden geldiğince birşeyler yapmak ve bunu paylaşmak halen zevk veriyorken yapayım diyorum.

  3. Samir (baku)

    mukemmel olmuş. teşekkürler!

  4. Allah razı olsun çalışmalarında başarılar.

  5. [...] [...]

  6. bbakirtas

    Parse error: parse error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or ‘}’ in c:\inetpub\wwwroot\new_pany\onlineservices\sayfalayici.class.php on line 18

  7. Bu hatayı almana neden olan kodları da görebilir miyim?

Yorum Ekle