Basic Zend Tutorial

Created by:

SilverLine IT
B-118, Sector 64, Noida, UP, India.

Version V-1.0

Modification Date
14th Ju;ly

Description Creation


Silver Line IT

B-118, Sector 64, Noida, UP, India.

You must also ensure that Apache is configured to support . This is used to separate out the different parts of your application to make development and maintenance easier.ini | |-.index.public | |-. You will not be able to navigate to any page other than the home page in this tutorial if you have not configured mod_rewrite and .controllers | -.htacess usage correctly.css |---index. Directory Structure www/zf(localhost directory) |-. Create a database testing and a table student with 2 columns id and name to have working zend application working :) Or You can change the setting in config.delete. India.phtml |-. Requirements The Zend Framework has the following requirements: • PHP 5. Check with your distribution’s documentation for exact details.php |-views | -.conf file. UP. .library (zend library) |-. Silver Line IT B-118.1.php |-models | |-.edit.Short Summary This tutorial is intended to give a very basic introduction to using the Zend Framework to write a basic database driven application.scripts | --index -.ini file as per Your files.phtml -. Sector 64.phtml -.add.4 (or higher) • A web server supporting mod_rewrite functionality. Noida.Student.phtml -.application | |-. The Zend Framework uses the Model-View-Controller (MVC) architecture._form.styles | .php Create the above file/folder structure Or You can also use the attached files.phtml -.IndexController. This is usually done by changing the setting: AllowOverride None to AllowOverride All in your httpd.config.

Zend_Loader::loadClass('Zend_Db').htaccess files to ensure that our application and library directories are protected: zf-tutorial/application/.php php_flag magic_quotes_gpc off php_flag register_globals off You can also consider the following zf-tutorial/public/. include "Zend/Loader. Noida. To achieve this.htaccess deny from all zf-tutorial/library/.php file.php <?php //error_reporting(E_ALL|E_STRICT). PATH_SEPARATOR .htaccess deny from all The Bootstrap File: index. all requests need to go through a single index. get_include_path()). Zend_Loader::loadClass('Zend_Controller_Front'). '. UP. Zend_Controller is designed to support websites with clean urls.php". PATH_SEPARATOR . Zend_Loader::loadClass('Zend_Config_Ini')./application/models/' .htaccess RewriteEngine off Whilst not strictly necessary with out current rewrite rules. Zend_Loader::loadClass('Zend_Db_Table'). PATH_SEPARATOR .Folders/Files Explanation The Zend Framework’s controller. Sector 64.htaccess RewriteEngine on RewriteRule . India. Zend_Loader::loadClass('Zend_Registry'). This provides us with a central point for all pages of the application and ensures that the environment is set up correctly for running the application./library' . we can add a couple more . . set_include_path('. // load configuration Silver Line IT B-118. '. We achieve this using an .htaccess file in the zf-tutorial root directory: zf/.* index. known as the bootstrapper.' .

/application/config.' . The Zend Framework is designed such that its files must be on the include path. Zend_Db_Table::setDefaultAdapter($db). $frontController->setControllerDirectory('.php". '. $config). error_reporting(E_ALL|E_STRICT). 'general'). Obviously. $registry = Zend_Registry::getInstance(). $frontController->throwExceptions(true)./application/controllers').php to gives us access to the Zend_Loader class which has the required static functions to enable us to load any other Zend Framework class Zend_Loader::loadClass('Zend_Controller_Front'). Let’s go through this file. set_include_path('./library' . Sector 64. Zend_Loader::loadClass loads the named class. PATH_SEPARATOR .ini'.php. We also set up our current time zone as required by PHP 5.ini setting display_errors set to on). // setup database $db = Zend_Db::factory($config->db->adapter. If Silver Line IT B-118.1+. PATH_SEPARATOR .php to the end. $config->db->config->toArray()). date_default_timezone_set('Europe/London'). India. // setup controller $frontController = Zend_Controller_Front::getInstance(). '. // run! $frontController->dispatch(). PATH_SEPARATOR . $registry->set('config'. To kick off we have to include the file Zend/Loader. These lines ensure that we will see any errors that we make (assuming you have the php. you should choose your own time zone. Note that we do not put in the ?> at the end of the file as it is not needed and leaving it out can prevent some hard-to-debug errors when redirecting via the header() function if additional whitespace occurs after the ?>. Thus the class Zend_Controller_Front will be loaded from the file Zend/Controller/Front. ./application/models/' . UP. include "Zend/Loader. This is achieved by converting the underscores in the class name to path separators and then adding . We also place our models directory on the include path so that we can easily load our model classes later.$config = new Zend_Config_Ini('. get_include_path()). Noida.

In order for the router to operate.php so that it can look at the URI elements after that point. Sector 64. the controller is news and the action is view. Of course. it needs to work out which part of the URL is the path to our index. but if it doesn’t work for your set up. $frontController = Zend_Controller_Front::getInstance(). As this is a tutorial and we are running on a test system. page content and exceptions. It does a pretty good job of auto-detecting the correct base URL. This is telling us that we haven’t set up our application yet. If you go to http://localhost/zf/ to test. for a URL of the format http://localhost/zf/news/view. $frontController->throwExceptions(true). we had better discuss what we are going to build.. Each page of the application is known as an “action” and actions are grouped into “controllers”. By default. so let’s do that next. The first class we need. Before we can do so. you shouldn’t be displaying errors to the user anyway! Finally we get to the heart of the matter and we run our application: // run! $frontController->dispatch().you follow the same naming convention for your own library classes. This includes HTTP header. it’s important to understand how the framework expects the pages to be organised. you should see a fatal error similar to: Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (index)' in. is the front controller. but this application isn’t big enough to bother with them! Silver Line IT B-118.g. Noida. E. archived and view. $frontController->setControllerDirectory('. then you can override it using the function $frontController->setBaseUrl(). The front controller uses a router class to map the requested URL to the correct PHP function to be used for displaying the page. so it is easier to just rethrow so that the exceptions are easily visible./application/controllers'). This is to allow for grouping of related actions. the front controller will catch them for us and store them in the _exceptions property of the “Response” object that it creates. on a production server. The response object holds all information about the response to the requested URL. The Zend Framework’s MVC system also supports modules for grouping controllers together. I’ve decided to instruct the front controller to throw all exceptions that occur. The front controller will automatically send the headers and display the page content just before it completes its work This can be quite confusing for people new to the Zend Framework. UP.. We need to configure the front controller so that it knows which directory to find our controllers. For instance. a news controller might have actions of current. India. This is done by the Request object. then you can utilise Zend_Loader::loadClass() to load them too. . Organising the Pages Before we set up our files.

php within the specified controllers directory.phtml to show that it is a template file. UP. . Setting up the View To integrate the view into our application all we need to do is create some view files with test display code and add some action specific content into the controller actions. They won’t work yet until we set up the views. It should come as no surprise that this is also called index. Note that {Controller name} must start with a capital letter.php: zf/application/controllers/IndexController.. In this case {action name} should start with a lower case letter. we are not going to be bothered with “complicated” things like logging in! That can wait for a separate tutorial. Setting up the Controller We are now ready to set up our controller. That is. Thus our controller class is called IndexController which is defined in zf/application/controllers/IndexController. The Zend Framework’s controller also reserves a default controller name should none be supplied.The Zend Framework’s controller reserves a special action called index as a default action. As this is a simple tutorial. Each action is a public function within the controller class that must be named {action name}Action. These files are known as templates and the render() method expects that each template file is named after its action and has the extension .php <?php class IndexController extends Zend_Controller_Action { function indexAction(){ } function addAction(){ } function editAction(){ } function deleteAction(){ } } We have now set up the four actions that we want to use. Noida. the controller is a class that must be called {Controller name}Controller. This class must live in a file called {Controller name}Controller. for a url such as http://localhost/zf/news/ the index action within the news controller will be executed.phtml We now need to add four view files to our application. Thus the url http://localhost/zf/ will cause the index action in the index controller to be executed.. Sector 64. India. In the Zend Framework. zf-tutorial/application/views/scripts/index/index. Again {Controller name} must start with a capital letter and every other letter must be lowercase. The file must be in a subdirectory that is Silver Line IT B-118.

org/TR/xhtml1/DTD/xhtml1-transitional. .phtml zf/application/views/scripts/index/add. We can then use them to hold the “common” HTML and just reference from the view templates. The new files are: zfapplication/views/scripts/header.phtml zf/application/views/scripts/index/edit.phtml and footer. Noida. India. We will factor out the html code that is common to two files: header. Sector 64.phtml zf/application/views/scripts/index/delete. ?></title> </head> <body> <div id="content"> zf-tutorial/application/views/scripts/footer.phtml'). ?> Short Summary Silver Line IT B-118.named after the controller.phtml zf/application/views/scripts/index/delete. so the four files are: zf/application/views/scripts/index/index. our views need changing: zf/application/views/scripts/index/index.w3. ?> <h1><?php echo $this->escape($this->title). UP.phtml zf/application/views/scripts/index/add.phtml within the scripts directory.phtml </div> </body> </html> Again.phtml zf/application/views/scripts/index/edit. ?></h1> </body> </html> Common HTML code It very quickly becomes obvious that there is a lot of common HTML code in our views. ?></h1> <?php echo $this->render('footer. ?></title> </head> <body> <h1><?php echo $this->escape($this->title).org/1999/xhtml" xml:lang="en" lang="en"> <head> <meta http-equiv="Content-Type" content="text/html.w3.0 Transitional//EN" "http://www.charset=utf-8" /> <title><?php echo $this->escape($this->title).phtml').phtml <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.dtd"> Page 8 of 18 <html xmlns="http://www.phtml <?php echo $this->render('header.phtml <html> <head> <title><?php echo $this->escape($this->title).

phtml . To solve this.ini [general] db.charset=utf-8" /> <title><?php echo $this->escape($this->title). we need to tell it which database to use along with a username and password. we’ll need a CSS file to make our application look a little bit presentable! This causes a minor problem in that we don’t actually know how to reference the CSS file because the URL doesn’t point to the correct root directory.. class IndexController extends Zend_Controller_Action { function init() { $this->view->baseUrl = $this->_request->getBaseUrl(). ?></title> <link rel="stylesheet" type="text/css" media="screen" href="<?php echo $this->baseUrl.. We will use an INI file: zf-tutorial/application/config. we use the getBaseUrl() function that is part of the request and pass it to the view. India. . Noida. We need to add the CSS file to the <head> section of the header. The Zend Framework provides Zend_Config to provide flexible object oriented access to configuration files.css" /> </head> .. The DatabaseConfiguration To use Zend_Db_Table.. } function indexAction() { .. As we would prefer not to hard-code this information into our application we will use a configuration file to hold this information.php . Sector 64.?>/public/styles/site.Styling Even though this is just a tutorial. UP. This provides us with the bit of the URL that we don’t know.. <head> <meta http-equiv="Content-Type" content="text/html.adapter = PDO_MYSQL Silver Line IT B-118.phtml: zf-tutorial/application/views/scripts/header. We use the IndexController::init() function for this code as init() is called by the constructor and so the property will be available in all actions.. The configuration file can either an INI file or an XML file. zf/application/controllers/IndexController..

It supports a notation in the section name to allow loading of additional = localhost db. password and dbname parameters will be grouped under $config->db->config. username.password = yourdbpassowrd db. . $registry->set('config'. Note in this case. Zend_Config_Ini loads one section from the INI file. // setup database $db = Zend_Db::factory($config->db->adapter. we do this within the bootstrapper (additions in bold): Relevant part of zf-tutorial/index. UP. India.ini'.config. not every section (though every section can be loaded if you wanted to). the host../application/config.. Create the Table I’m going to be using MySQL and so the SQL statement to create the table is: CREATE TABLE student ( id int(11) NOT NULL auto_increment.db.dbname = testing bviously you should use your username. $config->db->config->toArray()). // setup controller .php . Again. Zend_Db_Table::setDefaultAdapter($db). Silver Line IT B-118. To do this we need to create an instance of Zend_Db and then register this with the static function Zend_Db_Table:: setDefaultAdapter(). // load configuration $config = new Zend_Config_Ini('.php Setting up Zend_Db_Table To use Zend_Db_Table.config. Zend_Config_Ini also treats the “dot” in the parameter as hierarchical separators to allow for grouping of related configuration parameters. $config). See relevant part of zf-tutorial/index. 'general'). we need to tell it the database configuration information that we have just loaded..config.ini'. 'section'). Zend_Loader::loadClass('Zend_Db_Table').ini. In our config.config.username = root db. PRIMARY KEY (id) ).. $registry = Zend_Registry::getInstance(). not mine! To use Zend_Config is very easy: $config = new Zend_Config_Ini('config. Sector 64. name varchar(100) NOT NULL. Noida. password and database name. Zend_Loader::loadClass('Zend_Db').

. . India. we have to set the protected property $_name to the name of the table. Zend_Loader::loadClass('Student ')..php. This is done in the IndexController class. UP. Noida. It doesn’t matter what we call our class. } Silver Line IT B-118. $student = new Student()..php . This is done in the init() function: zf-tutorial/application/controllers /IndexController.The Model Zend_Db_Table is an abstract class. so we have to derive our class that is specific to managing albums. To tell Zend_Db_Table the name of the table that it will manage. function indexAction() { $this->view->title = "Students". Thus. The name of this field can be changed too if required. so it makes sense to load the student class when the controller is instantiated. our class will be called Album as our table name is album. Sector 64. Also.. } You can also tell Zend_Db_Table about related tables and it can fetch related data too. Clearly every action within IndexController will be manipulating the album table using the Student class. We will store our Album class in the models directory: zf/application/models/Student... Listing Students Now that we have set up configuration and database information. function init() { $this->view->baseUrl = $this->_request->getBaseUrl(). $this->view->students = $student ->fetchAll(). but it makes sense to call it the same as the database table. We are going to list the albums in a table within the indexAction(): zf/application/controllers/IndexController. we can get onto the meat of the application and display some students. Zend_Db_Table assumes that your table has a primary key called id which is auto-incremented by the database.php . } . Note: This is an example of using Zend_Loader::loadClass() to load our own classes and works because we have put the models directory onto the php include path in index.php <?php class Student extends Zend_Db_Table { protected $_name = 'student'.

. ?> </table> <?php echo $this->render('footer. UP.phtml'). India. ?> <h1><?php echo $this->escape($this->title). Sector 64. if ($this->_request->isPost()) { Zend_Loader::loadClass('Zend_Filter_StripTags'). Noida. ?> Adding New Students We can now code up the functionality to add new albums. There are two bits to this part: • Display a form for user to provide details • Process the form submission and store to database This is done within addAction(): zf-tutorial/application/controllers/IndexController.?>">Edit</a> <a href="<?php echo $this->baseUrl. ?>/index/add">Add new album</a></p> <table border="1" cellpadding="5" cellspacing="5" width="65%"> <tr> <th>ID</th> <th>Label</th> <th>&nbsp.</th> </tr> <?php foreach($this->students as $student) : ?> <tr> <td><?php echo $this->escape($student->id). ?>/index/edit/id/<?php echo $student->id.. The function Zend_Db_Table::fetchAll() returns a Zend_Db_Table_Rowset which will allow us to iterate over the returned rows in the view template file: zf-tutorial/application/views/scripts/index/index.?>">Delete</a> </td> </tr> <?php endforeach.phtml <?php echo $this->render('header.phtml'). .?></td> <td><?php echo $this->escape($student->name). ?>/index/delete/id/<?php echo $student->id. $filter = new Zend_Filter_StripTags(). ?></h1> <p><a href="<?php echo $this->baseUrl.?></td> <td> <a href="<?php echo $this->baseUrl.. Silver Line IT B-118.php function addAction() { $this->view->title = "Add New Student".

?>" method="post"> <div> <label for="artist">Student</label> <input type="text" name="name" Silver Line IT B-118.phtml').phtml and edit. Then. if ($name != '') { $data = array( 'name' => $name. Album(). $this->view->buttonText = 'Add'. ?> <?php echo $this->render('footer.phtml'). $student = new Student(). to insert the information into a new row in the database table. // additional view fields required by form $this->view->action = 'add'. . ?> <h1><?php echo $this->escape($this->title). ?></h1> <?php echo $this->render('index/_form. $this->_redirect('/').phtml: The templates for adding an student are: zf/application/views/scripts/index/add. return. ?> zf/application/views/scripts/index/_form. Finally.phtml) that is called from both add. India.phtml'). Looking ahead. $this->view->student = $student->createRow().$name = $filter->filter($this->_request->getPost('name')). If it has. we can see that the edit action’s form will be very similar to this one.phtml <?php echo $this->render('header. so we will use a common template file (_form. } Notice how we check the request object’s isPost()method to see if the form has been submitted. Noida. we utilise our model class. $student->insert($data). we set up the view ready for the form we will use in the template. Sector 64. assuming that they have been filled in. $name = trim($name). } } // set up an "empty" album $student = new Student(). we redirect using the controller’s _redirect() method to go back to the root of our application. After we have added the album. ). UP. we retrieve the artist and title from the post array using the Zend_Filter_StripTags class to ensure that no html is allowed.phtml <form action="<?php echo $this->baseUrl ?>/index/<?php echo $this->action.

if ($this->_request->isPost()) { Zend_Loader::loadClass('Zend_Filter_StripTags'). we use a variable for the text to be displayed on the submit button. $this->_redirect('/'). Similarly. 0).php function editAction() { $this->view->title = "Edit Student". Editing Student Editing an album is almost identical to adding one. $where). } else { $this->view->student = $student->fetchRow('id='. Noida. Sector 64.phtml for the edit action as well. $where = 'id = ' . we have used a variable to $this->action rather than hard coding the action attribute. ?>" /> </div> </form> This is fairly simple code. Silver Line IT B-118. As we intend to use _form. so the code is very similar: zf/application/controllers/IndexController. $student->update($data. ?>" /> <input type="submit" name="add" value="<?php echo $this->escape($this->buttonText).?>"/> </div> <div id="formbutton"> <input type="hidden" name="id" value="<?php echo $this->student->id.value="<?php echo $this->escape(trim($this->student->name)). $id = (int)$this->_request->getPost('id'). } } } else { // album id should be $params['id'] $id = (int)$this->_request->getParam('id'. India. if ($id !== false) { if ($name != '') { $data = array( 'name' => $name. $name = $filter->filter($this->_request->getPost('name')). $name = trim($name). $student = new Student(). ). $filter = new Zend_Filter_StripTags().$id). . $id. return. UP.

UP.$id). $del = $filter->filter($this->_request->getPost('del')). if ($del == 'Yes' && $id > 0) { $where = 'id = ' . $filter = new Zend_Filter_Alpha(). India. ?> <h1><?php echo $this->escape($this->title).if ($id > 0) { $this->view->student = $student->fetchRow('id='. $student = new Student(). } } // additional view fields required by form $this->view->action = 'edit'.phtml'). we retrieve the id parameter from the request’s params property using getParam(). Sector 64. if ($id > 0) { // only render if we have an id and can find the album. ?> Deleting Student The code looks somewhat similar to the add and edit actions: function deleteAction() { $this->view->title = "Delete Student". if ($this->_request->isPost()) { Zend_Loader::loadClass('Zend_Filter_Alpha'). The template is: zf/application/views/scripts/index/edit. } } else { $id = (int)$this->_request->getParam('id'). $this->view->student = $student->fetchRow('id='. ?> <?php echo $this->render('footer. ?></h1> <?php echo $this->render('index/_form.phtml'). $rows_affected = $student->delete($where).phtml'). . $id = (int)$this->_request->getPost('id').phtml <?php echo $this->render('header. $id. $this->view->buttonText = 'Update'. } Note that when we are not in “post” mode. } } } // redirect back to the album list unless we have rendered the view Silver Line IT B-118. if ($this->view->student->id > 0) { // render template automatically return.$id). Noida.

just create a db and table student as mentioned above and copy/paste all the files in Your www directory on localhost to see all working :) Silver Line IT B-118.?> <?php echo $this->render('footer. India. } The template is a simple form: zf/application/views/scripts/index/delete. UP. ?> All the codes have been attached.phtml'). ?></h1> <?php if ($this->student) :?> <form action="<?php echo $this->baseUrl ?>/index/delete" method="post"> <p>Are you sure that you want to delete '<?php echo $this->escape($this->student->name).phtml'). .$this->_redirect('/'). ?> <h1><?php echo $this->escape($this->title). ?>" /> <input type="submit" name="del" value="Yes" /> <input type="submit" name="del" value="No" /> </div> </form> <?php else: ?> <p>Cannot find student. Sector 64. Noida.</p> <?php endif.phtml <?php echo $this->render('header. ?>' ? </p> <div> <input type="hidden" name="id" value="<?php echo $this->student->id.

End Of Document Silver Line IT B-118. India. Sector 64. Noida. . UP.

Sign up to vote on this title
UsefulNot useful