Create a business object class for a blog post.
Here is the minimal code.
application/models/Post.php
class Post extends BusinessObject { private $_id; public function __construct($id = null) { $this->_id = $id; } public function load() { $sql = "select * from posts where post_id = ? limit 1"; $data = Zend_Registry::get('db')->getRows($sql, array($this->_id)); return $data[0]; } }
Instantiating a business object class does not query the database. All it really
does is assign an ID. The load() method is called if data is requested by code
that looks like $post→title.
Create a business object class for containing a list of blog posts.
Here is the minimal code.
application/models/Post/All.php
class Post_All extends BusinessObject { public function getPosts() { $sql = "select post_id from posts"; $this->_hint('Post'); return Zend_Registry::get('db')->getCol($sql); } }
Post_All class is in the file
All.php in the “Post” folder.
There is no load() method needed in this class. The getPosts() method is
called by code that looks like $posts→posts.
To create a list of business objects, only the ID's of the objects are needed.
Querying for an array of ID's (or otherwise suitable primary key) is all that's
needed for the framework to generate the rest of the objects. This keeps the
code pertaining to Post business object out of the class pertaining to the
container for Post business objects. There is no need to query for, for
example, the title or body or whatever. This also makes the query faster and
more query cache-able.
The _hint() method is required when generating a collection to tell the
framework what the collection is a collection of.
Create a controller to display the blog posts (model) in a page (view).
Here is the minimal code:
application/controllers/BlogController.php
class BlogController extends Controller { public function index() { $posts = Zend_Registry::get('factory')->get('Post_All'); $this->view->posts = $posts->posts; $this->view->title = 'My Blog'; $this->view->display('blog/posts.tpl'); } }
Controller class and have a classname matching
a pattern of *Controller.
The controller action name corresponds to the URL. So the index action can be
called by requesting the URL http://localhost/blog/index. Since index is the
default action, you can also request the URL http://localhost/blog.
All objects are instantiated using the framework factory, i.e. the new keyword should never be used to instantiate a business object.
The list of posts is generated by the statement $posts→posts. This calls the
getPosts() class method, unless the data is already cached.
$this→view represents the Smarty template. Template variables can be
assigned, and templates can be displayed like always.
Create the view (Smarty template).
Here is the minimal code:
application/views/blog/posts.tpl
<html> <body> <h1>{$title}</h1> <table border="1"> <tr><th>ID</th><th>Title</th><th>Created</th></tr> {foreach from=$posts item=post} <tr><td>{$post->post_id}</td><td><a href="/blog/view/{$post->post_id}">{$post->title}</a></td><td>{$post->create_dt_tm}</td></tr> {/foreach} </table> </body> </html>
$posts Smarty variable is assigned by the PHP line $this→view→posts =
$posts→posts.
The $post→post_id field must match the name of the table column.
Load the page by requesting the URL http://localhost/blog. Here is a screenshot of what I get. (Note that clicking on the title hyperlink will result in a 404. We'll get to that link in a bit.)
Let's make the date look a little nicer.
The best way to do this is to return a timestamp from the database, and then let the template writer format the date in any way he wants, using Smarty modifiers. First, we need to return a timestamp. Given a statement like “$post→time”, the framework will first look for the field as a table column, then look for a getter method for that field. So, for “$post→time” to work, we need to add a getter method for a time field, where we can return anything we need. Here is the method.
public function getTime() { return strtotime($this->_data['create_dt_tm']); }
1. looks in ''$this->data'', a hash of all the fields for this object. 2. looks at table columns, loaded by the ''_load()'' method. 3. looks for a special ''get*'' method matching the field name.
Since we called $post→time and time is not a table column, it will look for
and call the getTime() method, which will return our data, and set the value
for $this→_data['time'] for future requests to use.
Then, in our view, we can use this newly available time field.
application/views/blog/posts.tpl
<html> <body> <h1>{$title}</h1> <table border="1"> <tr><th>ID</th><th>Title</th><th>Created</th></tr> {foreach from=$posts item=post} <tr><td>{$post->post_id}</td><td><a href="/blog/view/{$post->post_id}">{$post->title}</a></td><td>{$post->time|date_format:"%A %b. %e %Y %l:%M %p"}</td></tr> {/foreach} </table> </body> </html>
And now my screenshot looks like this.
That's it. Now, let's implement that title link so that we can View a single blog post.

