OK, during the last two days, I have built my first mini-application using Zend Framework. Now, I am beginning to understand how this PHP framework functions. I tried to uploaded the application onto Bluehost for the initial testing. But, it did not go as smooth as I had hoped. It took me two full days before getting all the issues worked out.
1st, Bluehost does not support Zend Framework by default. This means that I had to upload the ZF library into my home directory and edit the php.ini file. My test subdomain is test.are4.us. So, in that directory, I have my php.ini file, set up in the following manner.
# For PDO stuff, Bluehost has already gotten that configured. For my Mac, I had to recompile the PHP binary from the source. Apple does not enable PDO support out of the box.
extension=pdo.so
extension=pdo_sqlite.so
extension=sqlite.so
extension=pdo_mysql.sozend_extension=/usr/local/Zend/lib/ZendExtensionManager.so
zend_extension_ts=/usr/local/Zend/lib/ZendExtensionManager_TS.so# This addes the ZF framework library to my PHP lib path. It may require “apachectl restart”
include_path = “.:/home/arefouus/public_html/test/ZendFramework-1.5.2/library”
2nd, here the .htaccess file in the public_html/test/zft/html directory. This will be generated by the Zend IDE; but, requires minor tuning. Its purpose is to turn on redirection the index.php file and enable the Front-Controller pattern.
#Turn Rewrite Rule on.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* index.php
Options -Indexes
Lastly, here is my .htaccess file in the root directory – public_html to enable the PHP handling.
# Use PHP5 as default
AddHandler application/x-httpd-php5 .php
AddHandler server-parsed .html
AddHandler server-parsed .htm
AddHandler application/x-httpd-php5 .phtml
My index.php file is shown below.
<?php
define('APP_DIR', dirname(__FILE__) . "/application/");
define('ROOT_DIR', dirname(__FILE__));
define("WEB_DIR", dirname(__FILE__));
date_default_timezone_set('Europe/London');
set_include_path('.:/library/:/Library/WebServer/Documents/zft/:' . get_include_path());
require_once 'Zend/Loader.php'; // Main Zend loader class
//include("Loader.php"); // Custom loader class //need to investigate
Zend_Loader::registerAutoload();
//echo 'Path is'.get_include_path(); // # important - this echo statement should not be here, or it will cause header sent error.
/* not needed, already loaded by the auto-loading function.
require_once 'Zend/Layout.php';
require_once 'Zend/Config/Ini.php';
require_once 'Zend/Registry.php';
require_once 'Zend/Db.php';
require_once 'Zend/Db/Table.php';
*/
include_once 'application/default/models/Albums.php';
include_once 'application/default/models/AlbumForum.php';
$config = new Zend_Config_Ini('../application/config/config.ini', 'database');
$registry = Zend_Registry::getInstance();
$registry->set('config', $config);
$db = Zend_Db::factory($config->db);
Zend_Db_Table::setDefaultAdapter($db);
// Setup controller
$controller = Zend_Controller_Front::getInstance();
$controller->setControllerDirectory('../application/default/controllers');
$controller->throwExceptions(true); // should be turned on in development time
// bootstrap layouts
Zend_Layout::startMvc(array(
'layoutPath' => '../application/default/layouts',
'layout' => 'main'
));
// run!
$controller->dispatch();
// it is corrected, that the closing ?> is not needed here.
My IndexController.php file.
<?php
require_once 'Zend/Controller/Action.php';
require_once 'Zend/Db/Table.php';
class IndexController extends Zend_Controller_Action
{
/**
* The default action - show the home page
*/
public function indexAction()
{
$this->view->title = "My Albums";
$albums = new Albums();
$this->view->albums = $albums->fetchAll();
}
public function addAction()
{
$this->view->title = "Add New Album";
$form = new AlbumForm();
$form->submit->setLabel('Add');
$this->view->form = $form;
if ($this->_request->isPost()) {
$formData = $this->_request->getPost();
if ($form->isValid($formData)) {
$albums = new Albums();
$row = $albums->createRow();
$row->artist = $form->getValue('artist');
$row->title = $form->getValue('title');
$row->save();
$this->_redirect('/');
} else {
$form->populate($formData);
}
}
}
public function editAction()
{
$this->view->title = "Edit Album";
$form = new AlbumForm();
$form->submit->setLabel('Save');
$this->view->form = $form;
if ($this->_request->isPost()) {
$formData = $this->_request->getPost();
if ($form->isValid($formData)) {
$albums = new Albums();
$id = (int)$form->getValue('id');
$row = $albums->fetchRow('id='.$id);
$row->artist = $form->getValue('artist');
$row->title = $form->getValue('title');
$row->save();
$this->_redirect('/');
} else {
$form->populate($formData);
}
} else {
// album id is expected in $params['id']
$id = (int)$this->_request->getParam('id', 0);
if ($id > 0) {
$albums = new Albums();
$album = $albums->fetchRow('id='.$id);
$form->populate($album->toArray());
}
}
}
public function deleteAction()
{
$this->view->title = "Delete Album";
if ($this->_request->isPost()) {
$id = (int)$this->_request->getPost('id');
$del = $this->_request->getPost('del');
if ($del == 'Yes' && $id > 0) {
$albums = new Albums();
$where = 'id = ' . $id;
$albums->delete($where);
}
$this->_redirect('/');
} else {
$id = (int)$this->_request->getParam('id');
if ($id > 0) {
$albums = new Albums();
$this->view->album = $albums->fetchRow('id='.$id);
}
}
}
}
These code are from Rob Allen’s ZF tutorial. The link is http://akrabat.com/zend-framework-tutorial/
In conclusion, ZF framework is easy to use. The hard part is to manage the path of the library files and the directory structure. This problem is similar to Java’s Classpath issue. Once you get the Path issue resolved, the rest is pretty easy to maintain. The directory structure (auto generated by Zend IDE) is shown below.

