Question

I'm a novice to php5 and Zend Framework and I'm using Zend Studio. I have gone through many documentations but I still can't understand the concept behind the controllers in Zend.

To explain in short, I'm trying to develop a small web application for accounts handling. I have not made any changes to the default index.php file. here it is:

<?php

// Define path to application directory
defined('APPLICATION_PATH')
|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application'));

// Define application environment
defined('APPLICATION_ENV')
||define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv ('APPLICATION_ENV'):    'production'));

// Ensure library/ is on include_path
set_include_path(implode(PATH_SEPARATOR, array(
       realpath(APPLICATION_PATH . '/../library'),
       get_include_path(),
)));

/* function _initView()
{
   $view = new Zend_View();
   $view->addScriptPath(APPLICATION_PATH . '/views/scripts/');
} */



/** Zend_Application */
require_once 'Zend/Application.php';

// Create application, bootstrap, and run
$application = new Zend_Application(
       APPLICATION_ENV,
       APPLICATION_PATH . '/configs/application.ini'
);
$application->bootstrap()
->run(); 

here is my IndexController.php

<?php

class IndexController extends Zend_Controller_Action
{

public function init()
{
    /* Initialize action controller here */
}

 public function indexAction()
 {

 }

}

I haven't done any changes there also, as I can't understand the concept.

my index.phtml :

<html>
<style>
</style>

<body>
<img alt="" src="http://localhost/Accounts/application/views/scripts/images/logo.png">
<div id="text" >
<h1>Welcome</h1><br><hr>
<h4>Please Log In To View The Main Page</h4></div><br><br><br>
<form action="main/main" method="post"><center><table>
<tr>
<td>User Name  :</td> <td><input type="text" name="uname"/></td>
</tr>
<tr>
<td>Passowrd   :</td> <td><input type="password" name="pwd"/></td>
</tr>
<tr>
<td><center><input type="submit" value="Log In"/></center></td> <td><center><input type="reset" value="Cancel"/></center></td>
</tr>
</table></center></form>
</body>
</html>

**please note that I have specified

<form action="main/main">

to go to the next page , which is "main.phtml". But this doesn't work.

here is my MainController.php:

<?php
require_once ('library/Zend/Controller/Action.php');

class MainController extends Zend_Controller_Action {

public function init()
{
    /* Initialize action controller here */
}

public function mainAction()
{
    include 'views/scripts/main/main.phtml';
}
}

in the above controller, if I specify,

include 'views/scripts/main/main.phtml';

or not, it works the same. On the browser, nothing is displayed when I tried to login.

As I have not specified any criteria to the log in, I think this should display the main.phtml.

here it is:

<html xmlns="http://www.w3.org/1999/xhtml" lang = "en">
<style>
</style>

<head>
    <meta name="keywords" content="" /></meta>
    <meta name="description" content="" /></meta>
    <link rel="shortcut icon" href="http://localhost/Accounts/application/views/scripts/images/favicon.ico" >
    <title>Accounts Handling</title>
</head>

<body>
    <div id="header"></div>
    <div id="main">
        <div id="menu">
        <?php include ('C:\wamp\www\Accounts\application\views\scripts\header\header.php');?>
        </div>
        <div id="content">  
            <center><img src="http://localhost/Accounts/application/views/scripts/images/accounts.jpg" alt="image" height=600px width=550px/></center>  
        </div>
        <div>
        <?php include ('C:\wamp\www\Accounts\application\views\scripts\footer\footer.php');?>
        </div>
    </div>
</body>
</html>

What's wrong in my code? Why doesn't this work? What I need to understand is how these controllers work. How do they link the views?

Was it helpful?

Solution

First does your application work at all? Do you get the index page when you navigate to http://localhost/accounts/public/index or do you get an error? If you get an error you need to fix your PHP/ZF environment.

Second, I recommend that you configure a virtual host for your application to make navigating easier. You'll have urls like http://accounts/main instead of http://localhost/accounts/public/main.

Your problem with displaying pages maybe that you are simply not navigating to the correct url's.

Now to your basic question.?

The controller concept...

Think of a controller in an MVC application (specifically Zend Framework) as a sort of traffic manager for data. The controller is what glues your web pages (views) to your models (data). The controller is most typically used to get data from the user (ie. forms), filter and validate that data and then pass it on to model for further processing or to be persisted in a database or other storage. It also works the other way. Get data from the model and prepare it for presentation to the user.

Here is an example of a simple controller action that just displays a list users:

//navigate to http://myapp/user/list where myapp is the base url, user is the controller
// and list is the action
class UserController extends Zend_Controller_Action{

    public function listAction() { //declare action in camel case
            $currentUsers = Application_Model_DbTable_User::getUsers();//get data from database via model
            if ($currentUsers->count() > 0) {
                $this->view->users = $currentUsers; //send list of users to the view
            } else {
                $this->view->users = NULL;
            }
        }
    }

and to display this list of users the view script might look like:

<!-- list.phmtl at application/views/scripts/user -->
h2>Current Users</h2>
<?php if ($this->users != null) : ?>
    <table class='spreadsheet' cellpadding='0' cellspacing='0'>
        <tr>
            <th>Links</th>
            <th>Last Name</th>
            <th>First Name</th>
            <th>Username</th>
            <th>Role</th>
            <th>
        </tr>
        <?php echo $this->partialLoop('_user-row.phtml', $this->users); ?>
    </table>
<?php else : ?>
    <p>You do not have any users yet.</p>
<?php endif ?>
<p><a href='/user/create'>Create a new user</a></p>

A partail in ZF is a bit of script that allows you to loop over the same code with a specified bit of data, in this case each user row will be displayed by these few lines of code. Tends to replace some instances of a foreach loop.

<!-- the patial _user_row.phtml -->
<tr>
    <td class="links">
        <a href='/page/edit/id/<?php echo $this->id ?>'>Update</a>
        <a href='/page/delete/id/<?php echo $this->id ?>'>Delete</a>
    </td>
    <td><?php echo $this->name ?></td>
</tr>

for completeness I'll include a portion of the model that provided the data:

class Application_Model_DbTable_User extends Zend_Db_Table_Abstract
{
    protected $_name = 'users';

 public static function getUsers() {
        $userModel = new self();
        $select = $userModel->select();
        $select->order(array('last_name', 'first_name'));
        return $userModel->fetchAll($select);
    }
}


I realize the answer here is a little simplistic as controllers can take on many roles depending on the application, their primary role in most applications is data management and view preparation.

I understand how hard this can be to wrap your head around, I went through this myself a short time back. A very good place to start would be Rob Allens's ZF 1.x tutorial.

Also you may want to be a little bit wary of Zend Studio while you get started, it seems to do some things during project creation that are different from what Zend_Tool does when it creates projects (I think this behavior can be changed in options) so the code that gets generated by Zend studio may not be exactly the same as in the tutorials.

Code snippets are from the Book Pro Zend Framework Techniques

I hope this provides some direction and help...

P.S. if you have ZF installed and configured correctly you'll almost never use an include statement. If you have to include anything from ZF you have a problem with your configuration (probably your php include path)

[EDIT]

To correct the 500 server error, there are few things you can check:

In your Apache config httpd.conf make sure this line LoadModule rewrite_module modules/mod_rewrite.so is un commented.

In the same .conf file make sure your directory entry for you localhost directory has these following settings:

<Directory "C:\Zend\Apache2/htdocs"><--- YOUR DIRECTORY
    ...truncated as the following is the important part
    Options Indexes FollowSymLinks <---IMPORTANT FOLLOWSYMLINKS IS REQUIRED FOR ZF
    #
    # AllowOverride controls what directives may be placed in .htaccess files.
    # It can be "All", "None", or any combination of the keywords:
    #   Options FileInfo AuthConfig Limit
    #
    AllowOverride All<---IMPORTANT, THIS ALLOWS .HTACCESS TO WORK
    #
    # Controls who can get stuff from this server.
    #
    Order allow,deny
    Allow from all
</Directory>

Hopefully this will fix your problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top