LogoPhly, boy, phly
the weblog and site of Matthew Weier O'Phinney

Friday, March 28. 2008

Login and Authentication with Zend Framework

I've fielded a number of questions from people wanting to know how to handle authentication and identity persistence in Zend Framework. The typical issue is that they're unsure how to combine:

  • An authentication adapter
  • A login form
  • A controller for login/logout actions
  • Checking for an authenticated user in subsequent requests

It's not terribly difficult, but it does require knowing how the various pieces of the MVC fit together, and how to use Zend_Auth. Let's take a look.

Authentication Adapter

For all this to work, you'll need an authentication adapter. I'm not going to go into specifics on this, as the documentation covers them, and your needs will vary based on your site. I will make the assumption, however, that your authentication adapter requires a username and password for authentication credentials.

Our login controller will make use of the adapter, but simply have a placeholder for retrieving it.

Login Form

The login form itself is pretty simple. You can setup some basic validation rules so that you can prevent a database or other service hit, but otherwise keep things relatively simple. For purposes of this tutorial, we'll define the following criteria:

  • Username must be alphabetic characters only, and must contain between 3 and 20 characters
  • Password must consist of alphanumeric characters only, and must be between 6 and 20 characters

The form would look like this:


class LoginForm extends Zend_Form
{
    public function init()
    {
        $username = $this->addElement('text', 'username', array(
            'filters'    => array('StringTrim', 'StringToLower'),
            'validators' => array(
                'Alpha',
                array('StringLength', false, array(3, 20)),
            ),
            'required'   => true,
            'label'      => 'Your username:',
        ));

        $password = $this->addElement('password', 'password', array(
            'filters'    => array('StringTrim'),
            'validators' => array(
                'Alnum',
                array('StringLength', false, array(6, 20)),
            ),
            'required'   => true,
            'label'      => 'Password:',
        ));

        $login = $this->addElement('submit', 'login', array(
            'required' => false,
            'ignore'   => true,
            'label'    => 'Login',
        ));

        // We want to display a 'failed authentication' message if necessary;
        // we'll do that with the form 'description', so we need to add that
        // decorator.
        $this->setDecorators(array(
            'FormElements',
            array('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form')),
            array('Description', array('placement' => 'prepend')),
            'Form'
        ));
    }
}
 

Login Controller

Now, let's create a controller for handling login and logout actions. The typical flow would be:

  • User hits login form
  • User submits form
  • Controller processes form
    • Validation errors redisplay the form with error messages
    • Successful validation redirects to home page
  • Logged-in user gets redirected to home page
  • Logout action logs out user and redirects to login form

The LoginController will make use of your chosen authentication adapter, as well as the login form. We will pass to the login form constructor the form action and method (since we now know what they will be for this usage of the form). When we have valid values, we'll pass them to our authentication adapter.

So, let's create the controller. First off, we'll create accessors for the form and authentication adapter.


class LoginController extends Zend_Controller_Action
{
    public function getForm()
    {
        return new LoginForm(array(
            'action' => '/login/process',
            'method' => 'post',
        ));
    }

    public function getAuthAdapter(array $params)
    {
        // Leaving this to the developer...
        // Makes the assumption that the constructor takes an array of
        // parameters which it then uses as credentials to verify identity.
        // Our form, of course, will just pass the parameters 'username'
        // and 'password'.
    }
}
 

Next, we need to do some checking before we dispatch any actions to ensure the following:

  • If the user is already authenticated, but has not requested to logout, we should redirect to the home page
  • If the user is not authenticated, but has requested to logout, we should redirect to the login page

The following preDispatch() routine will do this for us:


class LoginController extends Zend_Controller_Action
{
    // ...

    public function preDispatch()
    {
        if (Zend_Auth::getInstance()->hasIdentity()) {
            // If the user is logged in, we don't want to show the login form;
            // however, the logout action should still be available
            if ('logout' != $this->getRequest()->getActionName()) {
                $this->_helper->redirector('index', 'index');
            }
        } else {
            // If they aren't, they can't logout, so that action should
            // redirect to the login form
            if ('logout' == $this->getRequest()->getActionName()) {
                $this->_helper->redirector('index');
            }
        }
    }
}
 

Now, we need to do our login form. This is our simplest method -- we simply retrieve the form and assign it to the view:


class LoginController extends Zend_Controller_Action
{
    // ...

    public function indexAction()
    {
        $this->view->form = $this->getForm();
    }
}
 

Processing the form involves slightly more logic. We need to verify that we have a post request, then that the form is valid, and finally that the credentials are valid.


class LoginController extends Zend_Controller_Action
{
    // ...
   
    public function processAction()
    {
        $request = $this->getRequest();

        // Check if we have a POST request
        if (!$request->isPost()) {
            return $this->_helper->redirector('index');
        }

        // Get our form and validate it
        $form = $this->getForm();
        if (!$form->isValid($request->getPost())) {
            // Invalid entries
            $this->view->form = $form;
            return $this->render('index'); // re-render the login form
        }

        // Get our authentication adapter and check credentials
        $adapter = $this->getAuthAdapter($form->getValues());
        $auth    = Zend_Auth::getInstance();
        $result  = $auth->authenticate($adapter);
        if (!$result->isValid()) {
            // Invalid credentials
            $form->setDescription('Invalid credentials provided');
            $this->view->form = $form;
            return $this->render('index'); // re-render the login form
        }

        // We're authenticated! Redirect to the home page
        $this->_helper->redirector('index', 'index');
    }
}
 

Finally, we can tackle the logout action. This is almost as simple as displaying the login form; we simply clear the identity from the authentication object, and redirect:


class LoginController extends Zend_Controller_Action
{
    // ...

    public function logoutAction()
    {
        Zend_Auth::getInstance()->clearIdentity();
        $this->_helper->redirector('index'); // back to login page
    }
}
 

Okay, that's it for our login/logout routines. Let's look at the one associated view we have, the form:


<? // login/index.phtml ?>
<h2>Please Login</h2>
<?= $this->form ?>
 

And that's it. Really. Zend_Form makes view scripts simple. :-)

Checking for Authenticated Users

The last part of the question area is: how do I determine if a user is authenticated, and restrict access if not?

If you look carefully at the preDispatch() method above, you can see already how this can be done. Zend_Auth persists the identity in the session, allowing you to query it directly using this construct:


Zend_Auth::getInstance()->hasIdentity()
 

You can use this to determine if the user is logged in, and then use the redirector to redirect to the login page if not. You can pull the identity from the auth object as well:


$identity = Zend_Auth::getInstance()->getIdentity();
 

This could be sprinkled into a helper to show login status in your layout, for instance:


/**
 * ProfileLink helper
 *
 * Call as $this->profileLink() in your layout script
 */

class My_View_Helper_ProfileLink
{
    public $view;

    public function setView(Zend_View_Interface $view)
    {
        $this->view = $view;
    }

    public function profileLink()
    {
        $auth = Zend_Auth::getInstance();
        if ($auth->hasIdentity()) {
            $username = $auth->getIdentity()->username;
            return '<a href="/profile' . $username . '">Welcome, ' . $username .  '</a>';
        }

        return '<a href="/login">Login</a>';
    }
}
 

Conclusion

Zend_Auth does a lot of behind the scenes work to make persisting an identity in the session trivial. Combine it with Zend_Form, and you have a very easy to implement solution for retrieving and validating credentials; add standard hooks in the Zend_Controller component for filtering actions prior to dispatch, and you can restrict access to applications easily based on authentication status.

Posted by Matthew Weier O'Phinney in PHP at 11:14 | Comments (52) | Trackbacks (2)
Defined tags for this entry: mvc, php, zend framework
Related entries by tags:
Form Decorators Tutorial posted
Zend Framework Q&A Session
View Helpers Tutorial on DevZone
ZF Plugins Tutorial on DevZone
Action Helpers in ZF

Trackbacks
Trackback specific URI for this entry

Logowanie z u?yciem Zend_Auth i Zend_Form
Matthew Weier O?Phinney w swoim blogu zaprezentowa? bardzo ciekawy przyk?ad wykorzystania Zend_Auth i Zend_Form w celu autoryzacji i autentyfikacji u?ytkownik
Weblog: dominik bu?aj
Tracked: Mar 29, 07:53
Login and Authentication with Zend Framework - phly, boy, phly
Login and Authentication with Zend Framework - phly, boy, phly
Weblog: roScripts - Webmaster resources and websites
Tracked: Mar 29, 10:15

Comments
Display comments as (Linear | Threaded)

Hey Matthew,
this seems to be a very helpful tutorial.
I think I will try this today and have some fun with ZF.

Thank you for your great work for ZF and your nice character within mailing list.
#1 Wolfgang Forstmeier (Link) on 2008-03-28 12:32 (Reply)
First of all I'd like to say thanks for your contributions to the ZF, I'm loving it so far.

I'm currently in the process of building a prototype using several pieces of the ZF, although it's not currently using Zend_Auth. I'm authenticating against SOAP web service, which I suppose could be implemented with an Auth_Adapter, but I haven't gone down that road yet.

What I did do is create a Controller_Plugin which listens for a login (by checking the POST data) and handles it appropriately; or if no login is provided checks if the user is authenticated and handles that response properly.

This makes it so the user can get linked to http://example.com/wherever/they/want and if they are not logged in I set the route to the login page, where the form simply posts back to itself so the user will login and automatically be where they tried to get in the first place.

This is my first whack at the ZF... but I'm very much looking forward into getting to know it more intimately. The MVC+Layout, OpenID, and Translate pieces are phenomenal. Thanks again, and keep up the good work! If I'm able to push my prototype into production hopefully I can provide a case study for you guys or something.... I'll be going to battle with a home-baked Java framework, so wish me luck :-)
#2 Brian Holub on 2008-03-28 14:37 (Reply)
couple of syntax errors

array('StringLength', false, array(3, 20),
array('StringLength', false, array(6, 20),

missing extra )

should be
array('StringLength', false, array(3, 20)),
array('StringLength', false, array(6, 20)),
#3 Adrian (Link) on 2008-03-28 16:33 (Reply)
Thanks -- I've corrected those now.
#3.1 Matthew Weier O'Phinney (Link) on 2008-03-28 17:46 (Reply)
Excellent article! I appreciate all the hard work you have put into ZF.
#4 Justin Woods on 2008-03-28 17:51 (Reply)
Matthew Hello, thank you for this tutorial.
I have taken the liberty of translating it into Spanish, I hope not to create any problems.

feedback: http://cuatroxl.wordpress.com/2008/03/29/login-y-autentificacion-con-zend-framework/
#5 acido69 (Link) on 2008-03-28 22:20 (Reply)
To the contrary -- I'm honored!
#5.1 Matthew Weier O'Phinney (Link) on 2008-03-28 22:30 (Reply)
Hello Matthew,
Thanks for taking the time to write this, I've been itching to dive into Zend_Auth and I can see a lot of value with this sample. Also, I like how Zend_Form lends itself to encapsulating forms outside of the view, giving them a lot more portability.
#6 Jon Lebensold (Link) on 2008-03-29 00:45 (Reply)
Great article Matt, looking forward to more.

Just a quick note. I think the LoginForm init() function needs to be called. Perhaps

__construct() { parent::__construct(); $this->init(); }

Or am I just missing something?
#7 Huey Hu (Link) on 2008-03-29 04:56 (Reply)
init() was added in 1.5.1, and is called in __construct() prior to loading the default decorators. :-)
#7.1 Matthew Weier O'Phinney (Link) on 2008-03-29 10:30 (Reply)
Excellent post. There's just one thing here that I must point out... at least in the past, when I've authenticated users with $auth->authenticate($adapter), it seems zend_auth sticks the user's name in the identity *even if the auth fails*

This meant using hasIdentity does not work like expected and you'd have to clearIdentity after the failed auth attempt. Not sure if this happens in the latest version of ZF, though.
#8 Jani Hartikainen (Link) on 2008-03-29 10:25 (Reply)
Erm I mean isValid, not authenticate... :-P
#8.1 Jani on 2008-03-29 10:26 (Reply)
Jani -- thanks for the tip. I haven't experienced that behavior yet, but I'll keep my eye out for it (and hopefully fix it, if it rears its head).
#8.2 Matthew Weier O'Phinney (Link) on 2008-03-29 10:31 (Reply)
Hello Matthew,
The problem I currently have, is to implement authentication via a form that is just a part of a layout.
I think i'm stuck there. It is not a problem to display a form via a controller action like you did in your example above
but to integrate it into a layout and always display it if not authenticated. if the user then submits the form instead of the form a menu like Profile,.... etc should appear.

The problem especially is that i need to render everything to a layout key to place it to the right place. Maybe you can advice something?

How can i ensure that the appropiate layout keys get set on every page?
#9 Martin Thommas on 2008-03-29 18:49 (Reply)
Thanks for the post, Matthew.

The simple data persistence has it's disadvantages as the persisted data does not necessarily reflect the actual database row in it's current state (in case of database authentication of course).

I know that there is the possibility of calling write() when there are changes, but this won't work when row data is externally updated by maintenance scripts etc.

I have not yet found a way to force Zend_Auth to always update the persisted data on each request by fetching the current row. Any help/advice where to implement such functionality would be greatly appreciated.
#10 Chris on 2008-03-30 10:21 (Reply)
Nice walk through!

Maybe I'm missing something, but how could: if(!$auth->isValid($adapter)) work?

Shouldn't that be $auth->authenticate($adapter); ??

I can see the comment above regarding the problems of using authenticate(), but is isValid() really the solution?

Best,

//Anders
#11 Anders Fredriksson (Link) on 2008-03-31 07:12 (Reply)
Or maybe it should be:

$result = $adapter->authenticate();
if($result->isValid())

?

//Anders
#12 Anders Fredriksson (Link) on 2008-03-31 07:18 (Reply)
Yes, you're right -- and that's how I have it in my code, but I had a bad copy and paste; I've fixed it now.
#12.1 Matthew Weier O'Phinney (Link) on 2008-03-31 07:55 (Reply)
You forgot a semi column and it I think it should be

$result = $auth->authenticate($adapter);

if ($result->isValid() === false) {
}
#12.1.1 Arnaud on 2008-03-31 16:59 (Reply)
Fixed -- thanks. (where did my test first mantra go...?)
#12.1.1.1 Matthew Weier O'Phinney (Link) on 2008-03-31 17:11 (Reply)
The code in public function processAction() still shows the uncorrected way, I think you forgot to update something :-)
#12.1.1.1.1 Arnaud on 2008-04-01 03:06 (Reply)
Check now -- I believe it's fixed once and for all.
#12.1.1.1.1.1 Matthew Weier O'Phinney (Link) on 2008-04-01 06:29 (Reply)
what about checking user-login on the Plugin?
in most applications, you would want to restrict pages instead of just showing the "profile link" of the currently logged in user.

i would have a plugin that looks something like this:
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
try {
$controllerName = $this->getRequest()->getControllerName();
$frontController = Zend_Controller_Front::getInstance();
$user = Zend_Auth::getInstance()->getIdentity();

if ($controllerName=='index' OR $controllerName=='auth') {
return true;
}
if(!isset($user)) {
throw new Exception();
}
} catch (Exception $e) {
$this->getResponse()->setHttpResponseCode(403);
$request->setControllerName('error');
$request->setActionName('noaccess');
}
}
}

one could do additional ACL checking within the plugin. the great thing about using a plugin is that whenever you need to make changes with your ACL (or something), all you have to do is to edit the plugin. this is really helpful for me because i used to put a function in the preDispatch() of every Controller to check user-login. if i need to make changes, i would have to edit all of the controllers...

thanks again for the post Matthew! :-)
#13 wenbert (Link) on 2008-04-01 06:05 (Reply)
I specifically chose not to address ACLs in this tutorial to keep it simple and to the point: how do you authenticate a user and persist their identity afterwards. I then show techniques on how to retrieve the identity later -- which could be used from within a plugin to check ACLs for the user.

Yes, ACLs *are* typically best done from a plugin, but that's a topic for another day.
#13.1 Matthew Weier O'Phinney (Link) on 2008-04-01 06:33 (Reply)
Thanks! :-) Can't wait for the next post regarding Zend_Acl ;-)
#13.1.1 wenbert (Link) on 2008-04-01 06:41 (Reply)
Hi all,

I'm new to Zend Framework and I'm wondering what the difference is between the redirector calls in the following code:

if ('logout' != $this->getRequest()->getActionName()) {
$this->_helper->redirector('index', 'index');
}
} else {
// If they aren't, they can't logout, so that action should
// redirect to the login form
if ('logout' == $this->getRequest()->getActionName()) {
$this->_helper->redirector('index');
}

One redirector points to 'index', 'index' and one to 'index'. Can someone explain me what the result will be and how this works? I've checked the manual (http://framework.zend.com/manual/en/zend.controller.actionhelpers.html) but I can't find any information about the constructor and the arguments.
#14 Rob on 2008-04-02 12:52 (Reply)
The Redirector helper, when called as a method of the helper broker, proxies to its own goto() method. That method mimics the signature of Zend_Controller_Action::_forward(), which accepts the params: $action, $controller, $module, array $params. If no $controller is provided, the current controller is assumed; if no module is provided, the current module is assumed.

So, in the case where I call ('index', 'index'), I'm directing to the home page (this will actually be rewritten as '/' during redirection); in the case of ('index'), I'm redirecting to the index action of the current controller -- LoginController (internally, this will be rewritten to '/login').

The Redirector also has a way for you to specify a named route and pass parameters, in case you need the URL to follow a specific, custom schema.
#14.1 Matthew Weier O'Phinney (Link) on 2008-04-02 13:39 (Reply)
Thanks for your explanation Matthew! It's no totally clear to me how it works.
#14.1.1 Rob on 2008-04-02 14:20 (Reply)
Hello Matthew,

First I like to thank you very much for posting this.

I am very new to Zend Framework moving over from CodeIgnitor.

I have two requests
1) Can you provide us with the file and folder structure?
2) It seams the only thing missing to make this a working example is the db. Could you use an array with key username and value password?

Something like
$users = array('matthew'=>'1234',
'tanya'=>'4321',
'john'=>'5678',
'troy'=>'8765');

Best would be a working example of this in a zip file or google svn using sqlile as the db. :-)
You know what if you do get me going by providing the above I will create the svn for you, which ever you prefer. How is that?
#15 Troy (Link) on 2008-04-03 21:31 (Reply)
I use a standard ZF directory structure, which is outlined in our MVC docs as well as in the new Quick Start guide. As for the database, I've typically used Zend_Auth_Adapter_DbTable, and there is excellent documentation in the manual showing how to setup and utilize a database table for use with that adapter.
#15.1 Matthew Weier O'Phinney (Link) on 2008-04-04 09:04 (Reply)
Hi Matthew,

thanks for an other great tutorial !

While trying it out for my own application I noticed a problem with the code for the view helper.

In the method profileLink() you are using

$username = $auth->getIdentity()->username;

this gives a "Trying to get property of non-object" error.

I looked at the code and $auth->getIdentity() returns an array.
So, unless I missed something, shouldn't it be something like:

$identity = $auth->getIdentity();
$username = $identity['username'];
#16 Martin Carpentier on 2008-04-04 05:45 (Reply)
$auth->getIdentity() in most cases should be returning a stdClass object -- but this may vary based on the authentication adapter you utilize. The Zend_Auth_Adapter_DbTable adapter definitely returns a stdClass, and that's the adapter I'm most familiar with.
#16.1 Matthew Weier O'Phinney (Link) on 2008-04-04 09:02 (Reply)
Thanks for the clarifications. I'm using Zend_Auth_Adapter_Digest so it must be why. Although, I'm digging through the code but can't find where the stdClass Object is set up when using Zend_Auth_Adapter_DbTable.
#16.1.1 Martin Carpentier on 2008-04-08 05:36 (Reply)
Excellent tutorial. A great starting point for new adopters like me.

A question: How would you display a message to the user that their login failed due to bad credentials?
#17 Christopher on 2008-04-04 12:49 (Reply)
You'll notice that I add an additional decorator to the form, 'Description'. That decorator displays an HTML div with the contents provided by setDescription()... if any contents have been provided.

In processAction(), if the form is invalid, I call setDescription() indicating that the credentials are invalid. Thus, when the form is re-displayed, this message will be provided to the user.
#17.1 Matthew Weier O'Phinney (Link) on 2008-04-04 13:11 (Reply)
Took me while but after searching for Zend Framework and authentication etc I landed on this perfect cut'n'paste page :-)
Also, NEW to ZF and just need the last missing piece to start reviewing the code and understand the structure of this.
So, above there is a gap when calling the getAuthAdapter.
What should this return ?
My plan is to (within a year or so :-) ) use MySql for storage of the credentials but I would really appreciate just an example.

Thank you,
Bjorn
#18 Bjorn Cronqvist on 2008-04-18 06:17 (Reply)
I appreciate this tutorial but am have problems getting this working. Being new to ZF, I started off with the "Hello World" example in the manual using the IndexController, with a few Auth and ACL examples thrown in. So far so good - I was now ready to try the Forms part with your example.

My directory structure is according to the manual I think, so I put the code you listed above in
../application/views/scripts/login/login.phtml
../application/controllers/LoginController.php
and in /html is index.php and LoginForm.php.

Would that be be correct?

URL rewriting seems ok, since the URLs ending in /index and /index/index do call call the IndexController via
Zend_Controller_Front::run('../application/controllers');

The URLS /login though, gives no ZF error, just an error about not finding /index.php in the browser.

The .htaccess has the usual:
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

Thx in advance.
#19 sean on 2008-04-25 13:48 (Reply)
LoginForm.php should be somewhere in your include_path; it would have been better for me to name it something like 'My/Form/Login.php', and indicate that this would be found in your include_path.

Also, please notice that the view script should be in application/views/scripts/login/index.phtml -- not login.phtml. This is actually the cause of your error.

Finally, a better place to receive help on ZF related questions is on the mailing lists; fw-general for general questions, fw-mvc for MVC and forms related questions. You can find archives and links to signup instructions at http://framework.zend.com/archives.
#19.1 Matthew Weier O'Phinney (Link) on 2008-04-25 14:30 (Reply)
Yes, I think my key problems are re-writing though, I'm debugging with Apaches's RewriteLog and echo's in preDispatch(). I'll follow up in the forums though, Thx for the tips.
#20 Sean Boran on 2008-04-25 17:06 (Reply)
Hello all!
I see that there is a lot of compliments about this Tutorial, and i would like to say that all efforts mathew does are very appreciated.
There is a simple point of view i would like to add. Lets say, that i am noob at ZF, and that i have not fully clear picture of what ZF does. Official documetation is so confusing. I am not native speaker and hardly can understand what that documentation is used for anyway. So the only way to really learn and to really use ZF is to learn thru tutorial here and there.
Mathew i am sure that you have spent a few hours writing this tutorial but i simply cant make it work.
1. class LoginForm extends Zend_Form - whats that? how to name that file and where to save it?
I cant continue cause i am stucked on the first point :-)
Also there is a feeling that i just jumped in the middle of something and that there is no beggining(i mean on application structure and bootstrap file..) and no end of this tutorial. Tbh, i am not able to learn nothing from this tutorial, and as i sadi, or i did not, i am noob in use of ZF :-)
#21 Vladimir on 2008-05-01 10:53 (Reply)
The answer as to where to put the LoginForm class has been answered in another comment.

I'm sorry that you are having difficulty understanding the tutorial and other ZF documentation. You may want to start with the Quick Start guide offered on the ZF site, or one of the tutorials on Zend Framework offerred by Rob Allen (http://akrabat.com/). This tutorial assumes you already know a fair bit about how ZF's MVC works, and that you're also somewhat familiar with how Zend_Form and Zend_Auth work. If this is not the case, a more basic tutorial will help you gain the knowledge you need to understand this one.

Also, you may want to sign up for one of the ZF mailing lists (http://framework.zend.com/archives), or, if you like IRC, join the #zftalk channel; both of these sources will put you in touch with good developers who are willing to help you out.
#21.1 Matthew Weier O'Phinney (Link) on 2008-05-01 11:25 (Reply)
Thank you for your swift reply.. You are absoultely in right, i was just miss somehow include path explained in previous post and want to apologize for bad i made :-)
I make it works now.
Thank you Matt!
#21.1.1 Vladimir on 2008-05-02 13:53 (Reply)
First off let me say, as many others have, Thank You. I'm a noob to the Zend Framework, though not so much to PHP, and am finding that I really like it. Resources like this make it much more enjoyable to learn.

Of course I do have a question :-)

In the LoginController, in the getForm function you specify the action to take when submitting the form, the problem is that I'm not running a Virtual Server for this app, nor am I running in the server's document root, so the action of course cannot be completed (404). My question is, how do I change this to something relative to the app?

I've tried using $this->baseUrl().'/login/process', but it returns an error saying: "Fatal error: Uncaught exception 'Zend_Controller_Action_Exception' with message 'Method "baseUrl" does not exist and was not trapped in __call()' in...."

Changing the action to just 'process' results in: "Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (process)' in...."

So I'm at a tad bit of a loss here. Your help is greatly appreciated.
#22 Michael (Link) on 2008-05-01 16:49 (Reply)
Michael -- change that to $this->getRequest()->getBaseUrl(), and you should be good to go.
#22.1 Matthew Weier O'Phinney (Link) on 2008-05-01 16:58 (Reply)
Thanks! That did it. Now I'm off to figure out Zend_Auth_Adapter_DbTable :-)
#23 Michael (Link) on 2008-05-01 17:24 (Reply)
Just a small thing:

href="/profile' should be href="/profile/'
#24 Jason (Link) on 2008-05-01 19:47 (Reply)
Actually, to the contrary: in ZF routes, you don't need the trailing slash.
#24.1 Matthew Weier O'Phinney (Link) on 2008-05-01 19:59 (Reply)
Here is the whole file:
------------------------------------------------------------------------
class My_View_Helper_ProfileLink
{
public $view;

public function setView(Zend_View_Interface $view)
{
$this->view = $view;
}

public function profileLink()
{
$auth = Zend_Auth::getInstance();
if ($auth->hasIdentity()) {
$username = $auth->getIdentity()->username;
return 'Welcome, ' . $username . '';
}

return 'Login';
}
}
----------------------------------------------------------------------------

IF

return 'Welcome, ' . $username . '';

AND assume username is jason.

it will return

"/profilejason" instead of "/profile/jason"

Because here ZF does not involve.
#24.1.1 Jason (Link) on 2008-05-02 01:33 (Reply)
oops, something missed

In

return 'Welcome, ' . $username . '';

IF I assume username is jason

it will return

"/profilejason" instead of "/profile/jason"
#24.1.1.1 Jason (Link) on 2008-05-02 10:32 (Reply)
Your blog system ate the HTML a tag. But I am sure, you know what I meant.
#24.1.1.1.1 Jason (Link) on 2008-05-02 11:59 (Reply)
Great tutorial! But I have one question - why everytime we want to use Zend_Auth we're getting instance of it? Can't we just use Zend_Auth as fully static class, eg: Zend_Auth::getIdentity(); instead of Zend_Auth::getInstance()->getIdentity();?
I understand it can be a pretty lame question... ;-)
(and sorry for my poor english...)
#25 Mikoskay (Link) on 2008-05-08 01:53 (Reply)
Honestly? I have no idea. I haven't really looked into the design of the component. But it's a good question; I'll ask Darby.
#25.1 Matthew Weier O'Phinney (Link) on 2008-05-08 07:56 (Reply)

Add Comment

Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

 
 
  • Home
  • Resume
  • Blog
  • Phly PEAR Channel
  • Contact Me
  • About this site

ZCE

Zend Education Advisory Board Member

Add to Technorati Favorites

Calendar

Back May '08 Forward
Mon Tue Wed Thu Fri Sat Sun
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Quicksearch

Links

  • PHLY - PHp LibrarY
  • Paul M. Jones
  • Mike Naberezny
  • Shahar Evron
  • Planet PHP
  • Zend Where I now work
  • Garden.org Where I once worked

Archives

May 2008
April 2008
March 2008
Recent...
Older...

Categories

XML Linux
XML Personal
XML Aikido
XML Family
XML Programming
XML Perl
XML PHP

All categories

Syndicate This Blog

XML RSS 0.91 feed
XML RSS 1.0 feed
XML RSS 2.0 feed
ATOM/XML ATOM 0.3 feed
ATOM/XML ATOM 1.0 feed
XML RSS 2.0 Comments

Show tagged entries

xml best practices
xml books
xml conferences
xml file_fortune
xml linux
xml mvc
xml pear
xml php
xml programming
xml zendcon
xml zend framework
© 2004 - present, Matthew Weier O'Phinney
matthew-web <at> weierophinney.net