<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Devlog &#187; How To</title>
	<atom:link href="http://devlog.info/cat/how-to/feed/" rel="self" type="application/rss+xml" />
	<link>http://devlog.info</link>
	<description>One developers blog.</description>
	<lastBuildDate>Tue, 31 Aug 2010 18:45:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PHP Stream Wrappers</title>
		<link>http://devlog.info/2008/10/19/php-stream-wrappers/</link>
		<comments>http://devlog.info/2008/10/19/php-stream-wrappers/#comments</comments>
		<pubDate>Sun, 19 Oct 2008 20:24:53 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[Check It Out]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[stream-wrapper]]></category>

		<guid isPermaLink="false">http://devlog.info/?p=57</guid>
		<description><![CDATA[If you talk to me regularly then you already know how much I love stream wrappers in PHP. The other day I was positively giddy with how easy it was to solve a particular problem by using stream wrappers. 
What are stream wrappers?
PHP 4.3.0 introduced the idea of streams. The PHP manual has a perfect [...]]]></description>
			<content:encoded><![CDATA[<p>If you talk to me regularly then you already know how much I love stream wrappers in PHP. The other day I was positively giddy with how easy it was to solve a particular problem by using stream wrappers. <span id="more-57"></span></p>
<h2>What are stream wrappers?</h2>
<p>PHP 4.3.0 introduced the idea of streams. The <a href="http://php.net/manual/en/intro.stream.php">PHP manual</a> has a perfect explanation:</p>
<blockquote><p>Streams were introduced with PHP 4.3.0 as a way of generalizing file, network, data compression, and other operations which share a common set of functions and uses. In its simplest definition, a stream is a resource object which exhibits streamable behavior. That is, it can be read from or written to in a linear fashion, and may be able to fseek() to an arbitrary locations within the stream. </p></blockquote>
<p>Streams are identified by a particular scheme in the URI. For example, with <code>http://someurl</code> the scheme is 'http' and when no scheme is provided like in <code>/file.php</code>, the scheme is defaulted to 'file' and is expected to be a file in the filesystem (thus <code>file:///file.php</code> would mean the same thing).</p>
<p><strong>Stream wrappers</strong> are bits of code that tell PHP how to handle certain schemes. The interesting thing is that you can create your own custom stream wrappers written in PHP with little effort.</p>
<p>For example, you may have done <code>file_get_contents('file.txt');</code> before. But say you wanted to have the same ease of use but with data from a different source. You could create a custom stream wrapper to get data from wherever you want and use all of the normal PHP functions as usual: <code>file_get_contents('mystream://whatever');</code>.</p>
<p>Almost <em>any</em> function that works on files will work with custom stream wrappers. That includes fopen, fwrite, fseek, is_readable, is_writable, stat, unlink and more. In essence you can create a virtual filesystem in your applications.</p>
<h2>Why create custom stream wrappers?</h2>
<p>So why in the world would you want to create custom stream wrappers? Basically it comes down to decoupling filesystem-coupled interfaces from the filesystem (or any <em>stream</em>, for that matter). That is, make software think it's talking to files when it's talking to your custom PHP class. It's all about abstraction!</p>
<p>You could also use stream wrappers to simplify an interface, though this is less common. If you are using stream wrappers to simplify an interface, you can just as easily create a normal <a href="http://en.wikipedia.org/wiki/Facade_pattern">facade</a> to simplify the interface and leave streams out of it.</p>
<h3>For example</h3>
<p>I wanted to use a newish PHP templating engine called <a href="http://dwoo.org/">Dwoo</a> for an upcoming project. The problem was it expects files everywhere. Template files were read from the filesystem and compiled to the filesystem, and caches were written to the filesystem. There was no easy way to change this.</p>
<p>For this particular project I need to read templates from a string (loaded from an arbitrary source decided at runtime), and I can't use the filesystem for caches, I need to use memcached. The reason being that the application will be run in a cluster. Using shared disks is not practical with this many machines, and disk IO would eventually become a bottleneck. True, we could use RAM disks, but it's a lot easier and portable to manage the data layer from our application instead of pushing it to the OS.</p>
<p>Using custom stream wrappers I created two new schemes for 'tpl://' (for reading) and 'tplc://' (for writing compiled templates). I was able to fill the requirements for the project while still using the awesome templating engine with little modification. The library still thinks it's reading and writing to files but behind the scenes it's reading from a cache of template sources and writing to memcached. Perfect!</p>
<h2>Creating custom stream wrappers</h2>
<p>To create your own custom stream wrappers you need to write a class that implements a set of methods. After you write the class, you can register it with <a href="http://php.net/manual/en/function.stream-wrapper-register.php">stream_wrapper_register</a>. Refer to that manual page for details on the methods you need.</p>
<p>The only problem I encountered was how to get my custom stream working with is_readable() and is_writable(). The trick is to implement the 'url_stat' method and set the 'mode' correctly. The mode is a number that represents what type of file the file is (file or directory etc) and the file permissions -- the usual chmod values. Here's a code snippet that accurately defines how the number should add up:</p>
<pre id="raw-php-2" style="display:none; width: 1px; height: 1px; overflow: hidden;">$dir = 040000;
$file = 0100000;

// Now you can add any permissions you want using the usual chmod octal notation:
$file += 0777; // A file that is readable
$dir += 0222; // A directory that is writable</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-2" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-2'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-2">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$dir</span> = <span style="color:#CC66CC;color:#800000;">040000</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$file</span> = <span style="color:#CC66CC;color:#800000;">0100000</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF9933; font-style:italic;">// Now you can add any permissions you want using the usual chmod octal notation:</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$file</span> += <span style="color:#CC66CC;color:#800000;">0777</span>; <span style="color:#FF9933; font-style:italic;">// A file that is readable</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$dir</span> += <span style="color:#CC66CC;color:#800000;">0222</span>; <span style="color:#FF9933; font-style:italic;">// A directory that is writable </span></div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2008/10/19/php-stream-wrappers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MVC With The Zend Framework</title>
		<link>http://devlog.info/2008/04/08/mvc-with-the-zend-framework/</link>
		<comments>http://devlog.info/2008/04/08/mvc-with-the-zend-framework/#comments</comments>
		<pubDate>Wed, 09 Apr 2008 01:24:52 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[Application Design]]></category>
		<category><![CDATA[Design Patterns]]></category>
		<category><![CDATA[How To]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[zf]]></category>

		<guid isPermaLink="false">http://devlog.info/?p=28</guid>
		<description><![CDATA[I've been using the Zend Framework a lot lately and have come to really appreciate it. Today I want to write about ZF and how to use the MVC components. This post will be all about ZF itself, how the MVC components work, and getting a simple example up and going. I will write another [...]]]></description>
			<content:encoded><![CDATA[<p>I've been using the Zend Framework a lot lately and have come to really appreciate it. Today I want to write about ZF and how to use the MVC components. This post will be all about ZF itself, how the MVC components work, and getting a simple example up and going. I will write another post later on some more advanced usage.<span id="more-28"></span></p>
<h2>About Zend Framework</h2>
<p>The <a href="http://framework.zend.com/">Zend Framework</a> is a free (<a href="http://framework.zend.com/license">BSD-like</a> license) PHP framework. It contains components to tackle many common problems including authentication, cacheing, mail, sessions, and of course MVC.</p>
<p>ZF is simple. It is a "use at will" framework, meaning you can take specific components and use them wherever you want. You can, for example, take just the Mail component and stick it into your already existing PHP application. This decoupled architecture is contrary to some other frameworks (including symfony or CakePHP to certain extents) where you are forced into using a single paradigm.</p>
<p>This framework is written for PHP5 only, so it is not encumbered by the limitations of PHP4. It is written using the best OOP principals, is thoroughly tested, and has a marvelous community of maintainers that keep it up to date.</p>
<h3>Zend Framework versus other frameworks (symfony, CakePHP etc)</h3>
<p>Typically when you think of a framework, you envision a completely developed codebase that includes its own of configuration, its own conventions, and specific programming paradigms. Many frameworks including <a href="http://www.symfony-project.com/">symfony</a>, <a href="http://cakephp.com/">CakePHP</a>, <a href="http://codeigniter.com/">Code Igniter</a> and Ruby's <a href="http://www.rubyonrails.org/">Rails</a>, follow this kind of thinking.</p>
<p>Zend Framework is a collection of loosely coupled components. As mentioned earlier, you can use any one of the components separately without running into any problems. Even so, the components still work very well together (for example, Zend_Auth can seamlessly use Zend_Session for persistence).</p>
<p>You need to do a bit more work to use ZF initially. ZF is not all tied together, so if you want to use MVC  (for example) then you have to create your own bootstrap, and create your own directory structure etc. When you download ZF it's simply a directory that contains the library files, you're the one who has to initialize and use everything. Compare this to symfony (or many others) where everything is ready to go after you edit a couple configuration lines.</p>
<p>I prefer ZF because I feel like I have more control. I am not tied into any one paradigm, I don't need to play around with configuration files and I can mix and match my code to my hearts content. </p>
<p>Please note that I am not belittling the other frameworks, I am just trying to explain what sets ZF apart. If you read some of my previous posts, you'll see I'm also an advocate of symfony.</p>
<h2>The Parts</h2>
<p><a href="http://devlog.info/2007/06/27/php-model-view-controller/">MVC</a> with Zend Framework is quite easy. Here's a brief overview of each part and how they relate to each other.</p>
<h3>1. Front Controller</h3>
<p>Most people will use a <a href="http://www.martinfowler.com/eaaCatalog/frontController.html">Front Controller</a>. Using a Front Controller means that all requests come through a central starting point. Usually a single index.php will instantiate the front controller object and handle all incoming requests to your site. The file is referred to as a "bootstrap" file, and will contain code to initialize other things in your system too (for example, loading configuration settings).</p>
<p>If you've been developing on the web for a while, you've probably seen lots of scripts that have many entry points. For example, you might have index.php, login.php, article.php etc. Most of the time you also have a global.php file that is included at the top of each script. When you have all these entry points, it can quickly become hard to manage and you also start to get a bunch of code duplication.</p>
<p>A Front Controller solves this. Instead of physical files on the disk defining how a request should be handled, the request itself is entered through the Front Controller and then analyzed to see what should be done with it.</p>
<h3>2. The Request Object</h3>
<p>Each request made has a corresponding Request object. This object wraps up the entire request environment. For example, the default HTTP environment contains things like request parameters from GET and POST. The Request object also contains which controller and action should be called upon.</p>
<h3>3. The Router</h3>
<p>The Router is what actually inspects the incoming request and decides which Controller and Action should be called up. For example, it will look at a request of /login and decide that the Login Controller should handle the request, and the Index Action should be called.</p>
<p>ZF comes with a default router, so you don't need to change anything unless you want special behavior. By default, the incoming URL is analyzed and the parts are mapped to specific controllers and actions: /:controller/:action. If they are not provided at all, then they are assumed to be 'index'.</p>
<h3>3. The Dispatcher</h3>
<p>Dispatching is the process of looking at the requested controller and action, and actually including the correct Controller file, instantiating it, and calling on the action. The Dispatcher is in a loop. That means you can run as many controllers and actions as you like.</p>
<p>Again, ZF comes with a default dispatcher that sets down some naming conventions that we'll explore in a bit.</p>
<h3>4. The Controller</h3>
<p>Finally there is your actual controller. A controller handles a specific part of your app (for example, working with articles) and can have multiple actions (for example, listing articles, viewing a single article, viewing a printable version etc).</p>
<h2>The Process</h2>
<p>A request is handled like so:</p>
<ol>
<li>A web request is made to a single entry point (usually an index.php file)
<li>The entry point creates a Front Controller and runs it</li>
<li>The Front Controller creates a Request object that wraps up the environment. At this point there is no controller or action set.</li>
<li>The Front Controller uses a Router to inspect the request to figure out which controller and action should be called upon. It sets these values in the Request object.</li>
<li>The Front Controller starts the Dispatcher loop which includes the correct Controller source file, instantiates it, and runs the correct Action.</li>
<li>A Controller does what it does. It can handle forms, get database info, render HTML etc.</li>
<li>Any Controller can also modify the Request object and set a different Controller or Action, so the Dispatch loop is run again. If no change is made, then the Dispatch loop ends and the result is served to the user</li>
</ol>
<p>You can get a visual representation of the process by viewing <a href="http://framework.zend.com/manual/en/figures/zend.controller.basics.png">this image</a>.</p>
<h2>Let's Get Started</h2>
<h3>The File Structure</h3>
<p>I like to separate my files into two parts. One part for the actual application files (controllers, libs, views, functions etc) and then public files that the user needs access to (javascript, css, images etc).</p>
<p>For the sake of simplicity, I also like to package ZF with my app. If you have a shared directory where you place libraries (PEAR, for example), then you of course don't need to include it with your own files.</p>
<p>Here's the structure I use:</p>
<ul>
<li>root
<ul>
<li>/client
<ul>
<li>/css</li>
<li>/images</li>
<li>/js</li>
</ul>
</li>
<li>/appfiles
<ul>
<li>/application
<ul>
<li>/controllers</li>
<li>/views
<ul>
<li>/scripts</li>
</ul>
</li>
</ul>
</li>
<li>/lib
<ul>
<li>/Zend</li>
</ul>
</li>
</ul>
</li>
<li>/.htaccess</li>
<li>/index.php</li>
</ul>
</li>
</ul>
<p>This also makes it easy to split up the appfiles from the public files. For example, may people like to place the application source files outside of the document root on the webserver.</p>
<p>The /appfiles/application directory contains all of your controller and view files. We'll talk about the naming convention the default Dispatcher expects in a sec.</p>
<p>The /appfiles/lib directory is where I personally like to keep the Zend Framwork files.</p>
<p>You can of course have any other directories you'd like. On one of my recent projects I had /appfiles/functions and /appfiles/classes for some various custom code files.</p>
<h3>Rewrite URLs</h3>
<p>To create friendly URL's like /login or /article/view, you need a way to rewrite all URL's to go through the main index.php file. If you are using an Apache webserver and htaccess is a viable option, then the following simple code snippet should work fine for you:</p>
<pre id="raw-code-7" style="display:none; width: 1px; height: 1px; overflow: hidden;">RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php</pre>
<div class="igBar">
<div class="wrap"><span id="lcode-7" style="float:right"><a href="#" onclick="javascript:showCodeTxt('code-7'); return false;">Plain Text</a></span><span class="langName">CODE:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="code-7">
<div class="code">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">RewriteEngine on</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">RewriteRule !\.<span style="color:#006600; font-weight:bold;">&#40;</span>js|ico|gif|jpg|png|css<span style="color:#006600; font-weight:bold;">&#41;</span>$ index.<span style="">php</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p>
If you are on a different server, there are <a href="http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.introduction">other ways</a> to rewrite URLs.</p>
<p>Note that you can still use ZF's MVC components without rewriting URL's. Refer to the documentation for info on how to do this.</p>
<h3>Create Bootstrap</h3>
<p>The bootstrap file is the "single entry point" I've been talking about. It contains the code that launches the Front Controller. In this case, our bootstrap file is index.php.</p>
<p>Here's the code for a simple bootstrap file:</p>
<pre id="raw-php-8" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;?php

#------------------------------
# Get the paths set
#------------------------------

define('ROOT', realpath(dirname(__FILE__) . '/appfiles'));
set_include_path('.' . PATH_SEPARATOR . ROOT . PATH_SEPARATOR . ROOT.'/lib');

#------------------------------
# Register the Zend autolaoder
#------------------------------

require_once(ROOT . '/lib/Zend/Loader.php');
Zend_Loader::registerAutoload();

#------------------------------
# Dispatch
#------------------------------

Zend_Controller_Front::run(ROOT . '/application/controllers');</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-8" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-8'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-8">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;"># Get the paths set</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/define"><span style="color:#000066;">define</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'ROOT'</span>, <a href="http://www.php.net/realpath"><span style="color:#000066;">realpath</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/dirname"><span style="color:#000066;">dirname</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#000000; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span> . <span style="color:#FF0000;">'/appfiles'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><a href="http://www.php.net/set_include_path"><span style="color:#000066;">set_include_path</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'.'</span> . PATH_SEPARATOR . ROOT . PATH_SEPARATOR . ROOT.<span style="color:#FF0000;">'/lib'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;"># Register the Zend autolaoder</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">require_once</span><span style="color:#006600; font-weight:bold;">&#40;</span>ROOT . <span style="color:#FF0000;">'/lib/Zend/Loader.php'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Zend_Loader::<span style="color:#006600;">registerAutoload</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;"># Dispatch</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#008000; font-style:italic;">#------------------------------</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">Zend_Controller_Front::<span style="color:#006600;">run</span><span style="color:#006600; font-weight:bold;">&#40;</span>ROOT . <span style="color:#FF0000;">'/application/controllers'</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Line 7 defines the <em>ROOT</em> constant to be the full path to the appfiles/ directory. If you were to move the appfiles/ directory somewhere else, you'd want to edit this line so the path stays correct.</p>
<p>Line 8 sets the PHP include path so that the Zend files are all included without any problems. We need this line because we are distributing ZF with the project, we need to tell PHP where to look for the files when we include them.</p>
<p>Line 15 and 16 include Zend_Loader and register it's autoload functionality. PHP5 introduced the ability to <a href="http://php.net/autoload">autoload</a> classes. Whenever a class is used but has not been defined, PHP will try and find the file and include it for you. This saves you from having to manually write all of the require_once()'s you would normally write under PHP4.</p>
<p>Line 23 fires off the Front Controller which starts up your whole application. As a parameter you need to pass the path to your controller files which in our case is /appfiles/application/controllers.</p>
<p>If you run this now (http://yoursite.com/path/to/project/), you'll see an exception because ZF can't find your controller file to handle the request. So let's write it.</p>
<h2>Controllers and Actions</h2>
<h3>What are Controllers? Actions?</h3>
<p>Lets get this question out of the way for those who are new to this kind of website architecture. A Controller is a class that handles the business logic of a given part of your website. It fetches data from a datasource, interacts with output, and then passes any calculations to the View to be displayed to the user (usually as HTML). Some examples of Controllers might be: LoginController, ArticleController and SearchController. Before you might have had files like login.php, article.php and search.php -- now you have classes that control all of this behavior.</p>
<p>Each Controller has a set of Actions, which is just a method you define within the Controller class. An Action is something specific the Controller needs to do. Using our examples listed before, this might be <em>processing</em> a login, <em>displaying</em> an article or <em>performing</em> a search. Before you might have used a variable in the URL to determine what needed to be done. For example, "article.php?do=display" now becomes the ArticleController with the 'display' Action.</p>
<h3>Naming Conventions</h3>
<p>So you know that controllers are classes, and actions are methods in the controllers. Now the only thing left to cover is how ZF knows which file to load, and which method to call.</p>
<p>You defined the location of the controller files when you called Zend_Controller_Front::run() in the bootstrap. In our example, it is /appfiles/application/controllers.</p>
<p>The Dispatcher (explained above) is responsible for loading the appropriate files, instantiating the correct class, and then calling the correct method. The default Dispatcher that comes with ZF uses a naming convention so you can add controllers and actions easily (instead of say, creating a configuration file that defines it all).</p>
<p>There are two very simple rules:</p>
<ul>
<li>All controllers need to be called SomethingController where "Something" can be whatever you want. The class source code needs to be in a file called "SomethingController.php".</li>
<li>All actions need to be called someAction() where "some" is anything you want.</li>
</ul>
<p>The default Router and Dispatcher will route a URL /something/some to the SomethingController and the someAction() action. (Meaning: Remember that the default URLs are /:controller/:action).</p>
<p>If a controller is not specified, then the 'index' controller (IndexController class) will be assumed. If an action is not specified, then the 'index' action is assumed (indexAction() method).</p>
<p>Just to hammer it into your head, let's have a few examples of how some possible URLs might be loaded using the default Router and Dispatcher:</p>
<ul>
<li>/: IndexController class, indexAction() method</li>
<li>/login: LoginController class, indexAction() method</li>
<li>/login/lostpass: LoginController class, lostpassAction() method</li>
<li>/article/new: ArticleController class, newAction() method</li>
</ul>
<p>You can also use hyphens in your URL's if you use camelCase in the naming of controllers or actions:</p>
<ul>
<li>/download/message-attachment: DownloadController class, messageAttachmentAction() method</li>
<li>/sign-up/confirm-email: SignUpController class, confirmEmailAction() method</li>
</ul>
<h2>Views</h2>
<h3>What are Views?</h3>
<p>A View is the thing that you give back to the user after they request something. Usually this is an HTML page, but it can be other things like XML or RSS feeds,  file downloads etc.</p>
<h3>File Locations</h3>
<p>Controllers will try to render a view script automatically. It will search for view scripts in /views/scripts/ in the directory above the controller directory (for us that means /appfiles/applications/views/scripts/). Each controller is expected to have a directory of its own, and each action is expected to have a .phtml file that is the actual PHP script to render. For example, LoginController's indexAction() will have a view in views/scripts/login/index.phtml.</p>
<h3>View Files</h3>
<p>The default view scripts in ZF are plain old PHP. You can add a different templating system if you'd like (like Smarty), but for simplicity, this article will use the default.</p>
<p>In the controller you can set variables to be available to the view, so you can do all of the usual stuff you'd expect like looping, formatting etc.</p>
<h2>An Example Page</h2>
<p>Time for a really simple example page that demonstrates everything you've just read.</p>
<p>First step is creating a new controller. This controller will be located at: /appfiles/application/controllers/IndexController.php with the following code:</p>
<pre id="raw-php-9" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;?php

class IndexController extends Zend_Controller_Action {
    public function indexAction() {

        $this-&gt;view-&gt;name = &quot;Christopher&quot;;

    }
}</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-9" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-9'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-9">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">class</span> IndexController extends Zend_Controller_Action <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; public <span style="color:#000000; font-weight:bold;">function</span> indexAction<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">view</span>-&gt;<span style="color:#006600;">name</span> = <span style="color:#FF0000;">"Christopher"</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Next we need to create a view script to render the HTML page. The view script will be located at: /appfiles/application/views/scripts/index/index.phtml with the following code:</p>
<pre id="raw-html-10" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;h1&gt;Hi, &lt;?php echo $this-&gt;name; ?&gt;&lt;/h1&gt;</pre>
<div class="igBar">
<div class="wrap"><span id="lhtml-10" style="float:right"><a href="#" onclick="javascript:showCodeTxt('html-10'); return false;">Plain Text</a></span><span class="langName">HTML:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="html-10">
<div class="html">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color: #009900;"><a href="http://december.com/html/4/element/h1.html"><span style="color: #000000; font-weight: bold;">&lt;h1&gt;</span></a></span>Hi, <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span></a>?php echo $this-<span style="color: #000000; font-weight: bold;">&gt;</span></a></span>name; ?&gt;<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/h1&gt;</span></span> </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Now if you run this in your browser, you'll get a simple page that displays a name. So what is going on here?</p>
<h3>The Controller</h3>
<p>The IndexController is a class the extends Zend_Controller_Action. All of your controllers must extend this base class (or a child of this base class -- you can create your own if you needed to). And on line 4 we have defined the indexAction() method to handle the default index action.</p>
<p>By defining both the index controller with an index action, we now have a default page do display whenever there was no URL supplied (remember that the dispatcher assumes 'index' if no controller or index was supplied).</p>
<p>On line 6 you'll notice we are assigning a name to a variable $this->view->name. This is how you pass values to your view script. You can assign any values. The view script is just PHP remember, so it doesn't matter if you assign arrays, objects, integers or strings.</p>
<h3>The View</h3>
<p>The view in our case is very simple. I just wanted to highlight how we use the variables assigned in the controller. All values assigned in the controller are available as $this->varname.</p>
<h2>What about Models?</h2>
<p>I haven't discussed anything about the models in this article. That's because the model in ZF's MVC can be just about anything.</p>
<p>A <em>model</em> is an object, or a system of objects, that represent some sort of data. Most often models are objects that represent specific database records, or database tables. For example, if you have a "user" table then you'd also have a "User" object to represent records from the table. You might also have a "UserTable" object to make finding records easier (sometimes called "peer objects"). So you might have classes with methods like User::setPassword() and UserTable::findUserByEmail(). This technique of mapping a table to objects is the <a href="http://martinfowler.com/eaaCatalog/activeRecord.html">ActiveRecord</a> pattern.</p>
<p>You can code these objects yourself, but usually some sort of ORM (Object-relational mapping) tool/library is used. Two of the most popular are <a href="http://www.phpdoctrine.org/">Doctrine</a> and <a href="http://propel.phpdb.org/trac/">Popel</a> (I suggest Doctrine). With these libraries, you define the structure of your database and the rest of the work is done for you. That is, the means of satisfying relationships and filling data objects with actual data form the database is done by the library rather then by hand. In the case of Doctrine, actual SQL is abstracted into so-called "DQL" (Doctrine Query Language) to make your programs 100% portable.</p>
<p>The point of a model is to create a separation between the data-tier and the logic-tier in your application. For example, your application's "change password" controller shouldn't need to know the low-level details of how a password is changed (the hashing, salting etc). That kind of thing should be coded into the model.</p>
<h2>Finished</h2>
<p>That's all there is to it. <a href='http://devlog.info/wp-content/uploads/2008/04/devlog-zf-mvc.zip'>Click here</a> to download the sample files used in this article (note that you need to add your own Zend library to the /appfiles/lib directory).</p>
<p>Next article I will go over some more advanced techniques including subclassing the front controller, action controllers, creating plugins and creating helpers.</p>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2008/04/08/mvc-with-the-zend-framework/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Pagination</title>
		<link>http://devlog.info/2007/06/04/php-pagination/</link>
		<comments>http://devlog.info/2007/06/04/php-pagination/#comments</comments>
		<pubDate>Tue, 05 Jun 2007 04:42:34 +0000</pubDate>
		<dc:creator>Christopher</dc:creator>
				<category><![CDATA[How To]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[page sets]]></category>
		<category><![CDATA[pages]]></category>
		<category><![CDATA[pagination]]></category>

		<guid isPermaLink="false">http://devlog.info/2007/06/04/pagination/</guid>
		<description><![CDATA[Pagination refers to splitting up a large result set into multiple pages. Probably the most recognized use of pagination is that displayed by Google when you perform a search. As long as there have been applications, there has been a need to paginate. Everything from long documents to search results, it's something almost every app [...]]]></description>
			<content:encoded><![CDATA[<p><img src='http://devlog.info/wp-content/uploads/2007/06/pagination.gif' alt='Example Pagination' align="right" class="img_border img_m_right" />Pagination refers to splitting up a large result set into multiple pages. Probably the most recognized use of pagination is that displayed by Google when you perform a search. As long as there have been applications, there has been a need to paginate. Everything from long documents to search results, it's something almost every app you use has in common. Considering just how common pagination is, it's the one thing that seems to trip up many amateur programmers. Today I'm going to go over how to create a simple pagination feature in PHP with data collected from a MySQL database. You can download the sources and example database at the end of the post.<span id="more-11"></span></p>
<h2>The Basics</h2>
<p>Let's start with just displaying the content on the screen in a table. Throughout this post I am going to be using a table called 'users' with fields for an ID, a first name, last name and email address. Here's some basic code that will just output these details into a (very long) table:</p>
<pre id="raw-php-17" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;?php
	$res = mysql_query(&quot;
		SELECT *
		FROM users
	&quot;);
?&gt;
&lt;table cellspacing=&quot;1&quot; cellpadding=&quot;0&quot; width=&quot;100%&quot;&gt;
	&lt;thead&gt;
		&lt;th&gt;ID&lt;/th&gt;
		&lt;th&gt;First Name&lt;/th&gt;
		&lt;th&gt;Last Name&lt;/th&gt;
		&lt;th&gt;Email&lt;/th&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
		&lt;?php while ($user = mysql_fetch_assoc($res)): ?&gt;
			&lt;tr&gt;
				&lt;td&gt;&lt;?php echo $user['id']; ?&gt;&lt;/td&gt;
				&lt;td&gt;&lt;?php echo $user['first']; ?&gt;&lt;/td&gt;
				&lt;td&gt;&lt;?php echo $user['last']; ?&gt;&lt;/td&gt;
				&lt;td&gt;&lt;?php echo $user['email']; ?&gt;&lt;/td&gt;
			&lt;/tr&gt;
		&lt;?php endwhile; ?&gt;
	&lt;/tbody&gt;
&lt;/table&gt;</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-17" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-17'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-17">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$res</span> = <a href="http://www.php.net/mysql_query"><span style="color:#000066;">mysql_query</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; &nbsp; &nbsp; SELECT *</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; &nbsp; &nbsp; FROM users</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; "</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">?&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;table cellspacing=<span style="color:#FF0000;">"1"</span> cellpadding=<span style="color:#FF0000;">"0"</span> width=<span style="color:#FF0000;">"100%"</span>&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &lt;thead&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;th&gt;ID&lt;/th&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;th&gt;First Name&lt;/th&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;th&gt;Last Name&lt;/th&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;th&gt;Email&lt;/th&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &lt;/thead&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &lt;tbody&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#000000; font-weight:bold;">&lt;?php</span> <span style="color:#616100;">while</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$user</span> = <a href="http://www.php.net/mysql_fetch_assoc"><span style="color:#000066;">mysql_fetch_assoc</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$res</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>: <span style="color:#000000; font-weight:bold;">?&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;tr&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt;&lt;?php <a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$user</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'id'</span><span style="color:#006600; font-weight:bold;">&#93;</span>; ?&gt;&lt;/td&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt;&lt;?php <a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$user</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'first'</span><span style="color:#006600; font-weight:bold;">&#93;</span>; ?&gt;&lt;/td&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt;&lt;?php <a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$user</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'last'</span><span style="color:#006600; font-weight:bold;">&#93;</span>; ?&gt;&lt;/td&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt;&lt;?php <a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$user</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'email'</span><span style="color:#006600; font-weight:bold;">&#93;</span>; ?&gt;&lt;/td&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/tr&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#000000; font-weight:bold;">&lt;?php</span> <span style="color:#616100;">endwhile</span>; <span style="color:#000000; font-weight:bold;">?&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &lt;/tbody&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;/table&gt; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p><a href='http://devlog.info/wp-content/uploads/2007/06/pagination-no-limit.gif' title='Screenshot a table listing'><img src='http://devlog.info/wp-content/uploads/2007/06/pagination-no-limit.thumbnail.gif' alt='Screenshot a table listing' align="left" class="img_border img_m_left" /></a> This is a pretty simple piece of code. We run a MySQL query to fetch all the users in the system -- we've all done that before, right? Of course the problem is when there are just too many users to list all at once. In the case of my example database, there are 200 records.</p>
<h3>Introducing: LIMIT</h3>
<p>A feature of any SQL database (that follows standards, anyway) is the ability to tell the server where to start returning rows from, and how many rows to return. Let's first modify the query a bit so it looks like this:</p>
<pre id="raw-php-18" style="display:none; width: 1px; height: 1px; overflow: hidden;">$res = mysql_query(&quot;
	SELECT *
	FROM users
	LIMIT 5
&quot;);</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-18" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-18'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-18">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$res</span> = <a href="http://www.php.net/mysql_query"><span style="color:#000066;">mysql_query</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; SELECT *</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; FROM users</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; LIMIT 5</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">"</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>The <em>LIMIT 5</em> makes the database return a maximum of 5 rows. So instead of returning all 200 of the rows in my example database, only the first 5 are returned -- that would be users with ID's 1-5.</p>
<p>In addition to just limiting the number of rows to return, you can also provide an offset. The offset is how many rows to skip before returning the result set. For example, let's modify the query one more time:</p>
<pre id="raw-php-19" style="display:none; width: 1px; height: 1px; overflow: hidden;">$res = mysql_query(&quot;
	SELECT *
	FROM users
	LIMIT 10, 5
&quot;);</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-19" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-19'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-19">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$res</span> = <a href="http://www.php.net/mysql_query"><span style="color:#000066;">mysql_query</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; SELECT *</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; FROM users</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; LIMIT 10, 5</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">"</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>The first number is the offset, and the second number is the row count. <em>LIMIT 10, 5</em> means "Get 5 rows starting after the 10th row". In other words, rows 11-15.</p>
<p>So the magic behind pagination is this <em>LIMIT</em> clause. The rest of the work is just some basic PHP to display a page selector, and a bit of math to get the offset and row count from the page number.</p>
<h2>The PHP Side Of Things...</h2>
<p>Before we start, let's outline what information we need available:</p>
<ul>
<li>The number of rows to display per page. This is usually just a configuration setting. We'll hard code this value directly into our script.</li>
<li>The current page the user is viewing. This is simple, it's just the users current page or '1' if they have no page. We'll pass this along in the query string.</li>
<li>The number of total rows the user can view. We need this number so we can calculate how many pages we will have to show in the page selector.</li>
<li>The total number of pages.</li>
<li>The offset to plug into the <em>LIMIT</em> clause, based on the values for per-page and the current page.</li>
</ul>
<p>The only "hard parts" are getting the number of total rows, calculating how many pages are required to show them all, and calculating the offset for use in the LIMIT clause. Here's how I did it:</p>
<pre id="raw-php-20" style="display:none; width: 1px; height: 1px; overflow: hidden;">$per_page = 10;
$cur_page = isset($_REQUEST['p']) ? (int)$_REQUEST['p'] : 1;

$res = mysql_query(&quot;
	SELECT COUNT(*)
	FROM users
&quot;);
$num_rows = mysql_result($res, 0, 0);

$total_pages = ceil($num_rows / $per_page);

if ($cur_page &lt;1 || $cur_page&gt; $total_pages) {
	$cur_page = 1;
}

$offset = (($cur_page - 1) * $per_page);</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-20" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-20'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-20">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$per_page</span> = <span style="color:#CC66CC;color:#800000;">10</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$cur_page</span> = <a href="http://www.php.net/isset"><span style="color:#000066;">isset</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$_REQUEST</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'p'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#006600; font-weight:bold;">&#40;</span>int<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#0000FF;">$_REQUEST</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'p'</span><span style="color:#006600; font-weight:bold;">&#93;</span> : <span style="color:#CC66CC;color:#800000;">1</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$res</span> = <a href="http://www.php.net/mysql_query"><span style="color:#000066;">mysql_query</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; SELECT COUNT(*)</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; FROM users</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$num_rows</span> = <a href="http://www.php.net/mysql_result"><span style="color:#000066;">mysql_result</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$res</span>, <span style="color:#CC66CC;color:#800000;">0</span>, <span style="color:#CC66CC;color:#800000;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$total_pages</span> = <a href="http://www.php.net/ceil"><span style="color:#000066;">ceil</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$num_rows</span> / <span style="color:#0000FF;">$per_page</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$cur_page</span> &lt;<span style="color:#CC66CC;color:#800000;">1</span> || <span style="color:#0000FF;">$cur_page</span>&gt; <span style="color:#0000FF;">$total_pages</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$cur_page</span> = <span style="color:#CC66CC;color:#800000;">1</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#006600; font-weight:bold;">&#125;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$offset</span> = <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$cur_page</span> - <span style="color:#CC66CC;color:#800000;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> * <span style="color:#0000FF;">$per_page</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Now that we have the code, let's go over it:</p>
<ul>
<li>First we set $per_page to a hard-coded value. In this case, it is 10. In the future you might want to make this user-configurable, but for now lets keep it simple.</li>
<li>Next is getting the current page by setting it to the 'p' incoming variable (for example, <em>index.php?p=<strong>10</strong></em>). If there is no 'p' variable, then default to the first page. Also note that I have casted the value to an integer, we don't want the user messing around with the query string and providing some string.</li>
<li>Then we get the total amount of rows in the database. A simple <em>COUNT(*)</em> gives us the number we're after. After running the query it's just a matter of sticking the count into the variable $num_rows. <strong>Note</strong> that if you introduce some kind of searching into your scripts, the same <em>WHERE</em> and <em>JOIN</em> clauses will need to be present in this query as well as your search query. $num_rows is meant to contain the number of total rows that the user will want to view, not just the total number of rows in the table.</li>
<li>To get the total number of pages, we use some simple math. The number of pages will be the total number of rows divided by the number of rows per page. Note the use of the ceil() function here. We want to round up the number to ensure that even a page with only 3 rows will still be viewable.</li>
<li>Then we do a check to make sure $cur_page is correct. It needs to be at least 1, and at most $total_pages. This check is here to ensure the user doesn't try something like 99999999999.</li>
<li>Finally, we calculate $offset that will be used in the LIMIT clause of our query. The offset is simply $cur_page minus 1, multiplied by the number of rows per page. We have to subtract 1 from the current page, otherwise it would always be a page ahead.</li>
</ul>
<p>Now that we have the numbers, we can alter our data-getting query and plug them into the LIMIT clause:</p>
<pre id="raw-php-21" style="display:none; width: 1px; height: 1px; overflow: hidden;">$res = mysql_query(&quot;
	SELECT *
	FROM users
	LIMIT $offset, $per_page
&quot;);</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-21" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-21'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-21">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#0000FF;">$res</span> = <a href="http://www.php.net/mysql_query"><span style="color:#000066;">mysql_query</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; SELECT *</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; FROM users</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">&nbsp; &nbsp; LIMIT $offset, $per_page</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#FF0000;">"</span><span style="color:#006600; font-weight:bold;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<p>Tada! We're all done! Well, that part at least. The only part left is to generate the links to the other pages.</p>
<h2>Generating The Page Links</h2>
<p>There are several different styles of page links. I prefer the kind that have a first/last and prev/next links to the side of the actual page links, and the current page should be surrounded by 5 pages to the left/right. For example, if I'm on page 15, there will be links to pages 9-14 on the left and pages 16-20 on the right. This is the style that I'm going to demonstrate here.</p>
<p>Undoubtedly there are numerous ways to generate such a navigation. Here's how I did it:</p>
<pre id="raw-php-22" style="display:none; width: 1px; height: 1px; overflow: hidden;">&lt;?php
	$page_pad = 5;

	$min_page = max(1, $cur_page - $page_pad);
	$max_page = min($total_pages, $cur_page + $page_pad);

	$show_prev = $cur_page&gt; 1 ? $cur_page - 1 : false;
	$show_next = $cur_page &lt;$total_pages ? $cur_page + 1 : false;
?&gt;
&lt;div class=&quot;page_nav&quot;&gt;
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;?p=1&quot;&gt;&amp;laquo; First&lt;/a&gt;&lt;/li&gt;
		&lt;?php if ($show_prev): ?&gt;&lt;li&gt;&lt;a href=&quot;?p=&lt;?php echo $show_prev; ?&gt;&quot;&gt;&amp;lt;Prev&lt;/a&gt;&lt;/li&gt;&lt;?php endif; ?&gt;

		&lt;?php for ($page = $min_page; $page &lt;= $max_page; $page++): ?&gt;
		&lt;li &lt;?php if ($page == $cur_page): ?&gt;class=&quot;cur_page&quot;&lt;?php endif; ?&gt;&gt;&lt;a href=&quot;?p=&lt;?php echo $page; ?&gt;&quot;&gt;&lt;?php echo $page; ?&gt;&lt;/a&gt;&lt;/li&gt;
		&lt;?php endfor; ?&gt;

		&lt;?php if ($show_next): ?&gt;&lt;li&gt;&lt;a href=&quot;?p=&lt;?php echo $show_next; ?&gt;&quot;&gt;Next&amp;gt;&lt;/a&gt;&lt;/li&gt;&lt;?php endif; ?&gt;
		&lt;li&gt;&lt;a href=&quot;?p=&lt;?php echo $total_pages; ?&gt;&quot;&gt;Last &amp;raquo;&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;
&lt;/div&gt;</pre>
<div class="igBar">
<div class="wrap"><span id="lphp-22" style="float:right"><a href="#" onclick="javascript:showCodeTxt('php-22'); return false;">Plain Text</a></span><span class="langName">PHP:</span>
</div>
</div>
<div class="syntax_hilite">
<div class="wrap">
<div id="php-22">
<div class="php">
<ol>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">&lt;?php</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$page_pad</span> = <span style="color:#CC66CC;color:#800000;">5</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$min_page</span> = <a href="http://www.php.net/max"><span style="color:#000066;">max</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC66CC;color:#800000;">1</span>, <span style="color:#0000FF;">$cur_page</span> - <span style="color:#0000FF;">$page_pad</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$max_page</span> = <a href="http://www.php.net/min"><span style="color:#000066;">min</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$total_pages</span>, <span style="color:#0000FF;">$cur_page</span> + <span style="color:#0000FF;">$page_pad</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$show_prev</span> = <span style="color:#0000FF;">$cur_page</span>&gt; <span style="color:#CC66CC;color:#800000;">1</span> ? <span style="color:#0000FF;">$cur_page</span> - <span style="color:#CC66CC;color:#800000;">1</span> : <span style="color:#000000; font-weight:bold;">false</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; <span style="color:#0000FF;">$show_next</span> = <span style="color:#0000FF;">$cur_page</span> &lt;<span style="color:#0000FF;">$total_pages</span> ? <span style="color:#0000FF;">$cur_page</span> + <span style="color:#CC66CC;color:#800000;">1</span> : <span style="color:#000000; font-weight:bold;">false</span>;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;"><span style="color:#000000; font-weight:bold;">?&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;div <span style="color:#000000; font-weight:bold;">class</span>=<span style="color:#FF0000;">"page_nav"</span>&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &lt;ul&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;li&gt;&lt;a href=<span style="color:#FF0000;">"?p=1"</span>&gt;&amp;laquo; First&lt;/a&gt;&lt;/li&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#000000; font-weight:bold;">&lt;?php</span> <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$show_prev</span><span style="color:#006600; font-weight:bold;">&#41;</span>: ?&gt;&lt;li&gt;&lt;a href=<span style="color:#FF0000;">"?p=&lt;?php echo $show_prev; ?&gt;"</span>&gt;&amp;lt;Prev&lt;/a&gt;&lt;/li&gt;&lt;?php <span style="color:#616100;">endif</span>; <span style="color:#000000; font-weight:bold;">?&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#000000; font-weight:bold;">&lt;?php</span> <span style="color:#616100;">for</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$page</span> = <span style="color:#0000FF;">$min_page</span>; <span style="color:#0000FF;">$page</span> &lt;= <span style="color:#0000FF;">$max_page</span>; <span style="color:#0000FF;">$page</span>++<span style="color:#006600; font-weight:bold;">&#41;</span>: <span style="color:#000000; font-weight:bold;">?&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;li <span style="color:#000000; font-weight:bold;">&lt;?php</span> <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$page</span> == <span style="color:#0000FF;">$cur_page</span><span style="color:#006600; font-weight:bold;">&#41;</span>: ?&gt;class=<span style="color:#FF0000;">"cur_page"</span><span style="color:#000000; font-weight:bold;">&lt;?php</span> <span style="color:#616100;">endif</span>; ?&gt;&gt;&lt;a href=<span style="color:#FF0000;">"?p=&lt;?php echo $page; ?&gt;"</span>&gt;&lt;?php <a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$page</span>; ?&gt;&lt;/a&gt;&lt;/li&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#000000; font-weight:bold;">&lt;?php</span> endfor; <span style="color:#000000; font-weight:bold;">?&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; </div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#000000; font-weight:bold;">&lt;?php</span> <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$show_next</span><span style="color:#006600; font-weight:bold;">&#41;</span>: ?&gt;&lt;li&gt;&lt;a href=<span style="color:#FF0000;">"?p=&lt;?php echo $show_next; ?&gt;"</span>&gt;Next&amp;gt;&lt;/a&gt;&lt;/li&gt;&lt;?php <span style="color:#616100;">endif</span>; <span style="color:#000000; font-weight:bold;">?&gt;</span></div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &nbsp; &nbsp; &lt;li&gt;&lt;a href=<span style="color:#FF0000;">"?p=&lt;?php echo $total_pages; ?&gt;"</span>&gt;Last &amp;raquo;&lt;/a&gt;&lt;/li&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&nbsp; &nbsp; &lt;/ul&gt;</div>
</li>
<li style="font-family: 'Courier New', Courier, monospace; color: black; font-weight: normal; font-style: normal;color:#3A6A8B; font-weight:bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal;">&lt;/div&gt; </div>
</li>
</ol>
</div>
</div>
</div>
</div>
<p></p>
<ul>
<li>First we set a $page_pad setting that is used to determine how many pages to either side of the current page should be shown. I think 5 is an appropriate number.</li>
<li>Next we need to determine the minimum and maximum page numbers that will be shown, based on the current page and how many pages to pad it with. We can't simply do the current page minus the padding for the minimum or the current page plus the padding for the maximum. This would make for the possibility of negative pages being displayed (for example, page 1 minus 5 padding) and pages that are over the total pages. To solve this issue we can use the min() and max() functions to make sure the $min_page and $max_page never go over the acceptable values.</li>
<li>Then we just need some simple logic to determine if the previous and next pages should be display, and if so, what their page numbers are.</li>
<li>The next bit is outputting the HTML for all the paged links</li>
</ul>
<p>There you have it! Pretty simple, isn't it?</p>
<h2>Conclusion</h2>
<p>I hope I've helped some new programmer out there with this post. I had just gotten tired of so many people asking me how to add pagination to their apps and not having any definitive source to point them to. Not exactly the most advanced stuff, but still something I though needed to be covered.</p>
<p><a href='http://devlog.info/wp-content/uploads/2007/06/pagination.zip' title='Pagination Script'>You can download the full source code here.</a> The package contains a PHP file, a CSS file and an SQL file that contains the test 'users' table and its data. The result looks like this:</p>
<div class="center"><a href='http://devlog.info/wp-content/uploads/2007/06/pagination-result.gif' title='Screenshot of pagination in action'><img src='http://devlog.info/wp-content/uploads/2007/06/pagination-result.thumbnail.gif' alt='Screenshot of pagination in action' class="img_border" /></a></div>
]]></content:encoded>
			<wfw:commentRss>http://devlog.info/2007/06/04/php-pagination/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
