Architecture
A nice (mercifully short) explanation of how/when to use ZF components is here:http://usingzendframework.blogspot.com/2007/01/zend-framework-overview.html
Configuration/Installation
XAMPP doesn’t enable Apache mod_rewrite by default in C:\xampp\apache\conf\httpd.conf.MVC tutorial
http://framework.zend.com/wiki/display/ZFDEV/2.+Introduction+to+Model-View-Controller+Architectural+Pattern- A Zend Controller instantiates, configures and assigns variables to a Zend View.
- Business logic (model data manipulation) gets implemented in the Controller.
- In the Zend_Controller implementation, controllers are classes and actions are class methods. For instance, http://domain/controller/action … gets implemented as:
class/class-method
- Routing is parsing a URI into a Controller (class) and action (class-method). Zend_Controller_Router_Rewrite parses a URL i nto a controller, action and parameters, using one of two Apache mod_rewrite rules (see “Controller Setup”, below).
Security
- PHP logic files should not be located under the webRoot tree; this may not be possible with web hosting. To deny browser access to a directory, put Deny from All in an .htaccess file within the directory to be protected.
- View template output should be ‘escaped’ via this->escape() method.
- View template content variables should be specified/configured in the controller.
- Zend_Filter provides static filtering methods. Zend_Input_Filter should be used to access all $_Post input.
Zend_Config class
Zend_Config provides a Property-based interface for reading text, hierarchical, configuration files ... in array, .ini or xml text file formats.For example, http://www.johndwells.com/journal/phrappe_controller_front-part-1-using-zend_config-to-describe-routing
Zend_Controller class
Modules can utilize different controller directories.Controller nomenclature and paths
Controller class file names must be suffixed with the word Controller e.g. a ‘go’ controller must be named goController.A Zend-framework site must have a default controller, named IndexController, located within the /controllers directory.
Zend recommends that the only two files in the web root directory be:
- .htaccess – to specify the Apache mod_rewrite ‘bootstrap’ file rule and
- Index.php, the Zend_Controller_Front site‘bootstrap’ file.
.htaccess
Enable Apache mod_rewrite and configure it via .htaccess in the VirtualHost document root (or in the httpd.conf VirtualHost section) with either of the following rules:RewriteEngine on RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php… which tells Apache mod_rewrite to re-direct all URI requests to the index.php file. This process is referred to as ‘bootstrapping’ i.e. the cornerstone file from which the site ‘pulls itself up by its bootstraps’ … or …
RewriteEngine on
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1
… which tells Apache mod_rewrite to, first, look for the SCRIPT_FILENAME and only re-direct to index.php, if it can’t find the SCRIPT_FILENAME.
Zend Controller errors
Error 500 Server error
Although Zend plans to not require Apache mod_rewrite in the future, the current version of the Zend_Controller_Router_Rewrite requires the Apache mod_rewrite module. So, if, after creating .htaccess, you see the following error, mod_rewrite is, probably, not enabled.Server error! The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there was an error in a CGI script. Error 500I suspect that the clue, here, is “Server error!” i.e. if nothing renders (i.e. nothing is interpreted), it’s an Apache server, rather than PHP script, error. In this case, the .htaccess mod_rewrite rule causes a server error, since mod_rewrite was not enabled. So, set AllowOverride All in the httpd.conf VirtualHost <Directory /> section.
Invalid controller specified()
exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (DbS)' in ...This turned out to be a controllerNameController.php file where in the file code controllerName was IndexController instead of classNameController. In other words, Zend_Controller_Router_Rewrite wanted to see:
class ControllerNameController extends Zend_Controller_Action {
rather than:
class IndexController extends Zend_Controller_Action {
in the file, ControllerNameController.php. You might say, “of course”; but, this was a bit more subtle because the ControllerName (DbS) was a virtual host under the web-root. I had thought that under http://localhost/DbS that it would be looking for IndexController.php; instead, it was looking for DbSController.php !
Zend_Controller_Router_Rewrite
addRoute syntax
The addRoute syntax is as confusing as syntax comes; so, follow it carefully. From Ruby-on-Rails parlance, the parameters are:$routerVariableName->addRoute(name, map, [parameters], [requirements]);
Parameter |
Definition |
optional |
|---|---|---|
name |
route label |
required |
map |
controllerName/:actionName |
required |
parameters |
Array(‘action’ => value) |
optional |
requirements |
Test expression |
optional |
The above translates to:
$routerVariableName->addRoute(
‘routeNameLabel’,
‘controllerName/:actionName’,
array(
‘action’ => defaultValue,
‘controller’ => ‘controllerName’,
‘action’ => ‘actionName’),
array(‘action’ => ‘someTest’
);
Note that in the array parameter the terms ‘controller’ and ‘action’ must be used literally i.e. they are not changeable variable names.The new Router_Rewrite has built-in root-URL and Index defaults; so, you need not add them. Note: the blank mapping; the controller and actions default to ‘index’.
$this->addRoute('default', '', array('controller' => 'index', 'action' => 'index'));
Zend_HTTPclient class
Zend_HTTPClient class may be used to retrieve and store entire articles (e.g. feed entries) in a database.$http = new Zend_Http_Client($channelLink); $response = $http->get(); $fullText = $response->getBody();
Zend_InputFilter class
Zend_InputFilter class checks input for safe use e.g. from the arrays, $_GET, $_POST and $_SESSION. To assign an array to a Zend object and, then, store the object instance in the Registry:
Zend::loadClass($class);
$filterGet = new Zend_InputFilter($_GET);
$filterPost = new Zend_InputFilter($_POST);
$filterSession = new Zend_InputFilter($_SESSION);
Zend::register('fGet', $filterGet);
Zend::register('fPost', $filterPost);
ZF JSON class
JSON (JavaScript Object Notation) can be used for data interchange (e.g via AJAX) between JavaScript and other languages. Since JSON can be directly evaluated by JavaScript, it is more efficient and lightweight than XML for exchanging data with JavaScript clients.
Zend_Loader class
Zend_Loader::loadFile() is a PHP include() function wrapper to load a class, contained in a PHP file. Require is faster than Zend_Loader::LoadClass; so, prefer Require, except where variables contain class names to Load.ZF Registry class
The Registry offers an alternative to using (and checking) session variables. Session variables may be stored in the Registry. The Zend class includes a registry, which can store (only) objects. The Registry persists only for the current script duration. The register() method stores (SET’s values); the registry() method retrieves (GET’s values).Zend::register(‘objectLabel’, ‘objectName’);To close the session:
session_destroy();
Zend_View class
There’s a nice, short Zend_View tutorial here: http://www.ingredients.com.au/nick/2006/06/10/getting-to-know-zend_view/Instantiating ZF View object is unnecessary
I’ve seen a lot of tutorials suggesting the following line to instantiate a ZF View object; for example: $view = new Zend_View(); Per http://benramsey.com/archives/ny-thoughts-and-zend_view_helper-notes/ Ben Ramsey says that a Controller will instantiate a View object when a Controller Action calls $this->render(). The controller configures the View and calls $this->render() (not the PHP View file); for example:
<?php
class CustomerController extends Zend_Controller_Action
{
public function init()
{
$this->initView();
}
public function indexAction()
{
$this->render();
}
public function addressAction()
{
$this->render();
}
}
?>
Zend_Controller_Action::initView() determines the views directory location i.e. you don’t have to specify the Zend_Views directory location … and, as stated above, the Controller will instantiate the View when $this->render() is called.
FrontController and View
Use
$frontController->setParam('view', $view);
… if there’s only a single view.
The front controller dispatches the $view request object to the correct ‘view’ action controller, which populates the $view request object with data.
$this->_response->appendBody
($this->_view->render('indexIndex.phtml'));
_view is the FrontController protected variable, used to receive the $view request object, containing the model data resultset.
Finally, the bootstrap Index.php sends the consolidated results for the browser to render.
$response->sendResponse();The default Zend_View script file extension is: .phtml. The ZF MVC project leader, Matthew Weier O’Phinney, writes that the .phtml template extension reinforces the idea that templates are .html files, containing PHP code. $this refers to the Zend_View object instance ($view).
Single vs. multiple Zend_Views
If the application has only one view object, one can use the Registry as in: Zend_Registry::set('viewName', $view);
If the application uses multiple views, use: $frontController->setParam('viewName', $view);
Zend_View Helper classes
Zend_View includes HTML “helper” classes, prefixed by a categorization word (e.g. formButton, formCheckbox etc.) and called as: $this->formHelperName().Naming Zend_View Helper methods
Prefix the name with Zend_View_Helper and camel-case the name e.g.Zend_View_Helper_HelperNameFor a Zend_View Helper to work, the HelperName must correspond to (be the same as) a Helper Class method name.
Back Home