3

Title may be confusing, but here's explanation with code.

Based on some conditions, I may call actionContact even if user has called actionIndex.

Solution:1

 public function actionIndex()
    { 
        $a = 5;
        if($a == 5){


$this->actionContact();
        }
        else{
            $this->render('index');
        }
    }

    public function actionContact()
    {
        // Some codes
        $this->render('contact');
    }

Solution:2

public function actionIndex()
        { 
            $a = 5;
            if($a == 5){


// Repeat code from actionContact method
            $this->render('contact');
        }
        else{
            $this->render('index');
        }
    }

Solution:3 I can redirect to contact url.

I think, solution 1 works fine for me and I would prefer that. But since I am new to yii, I would like to know, if its the way to go ?

tereško
  • 58,060
  • 25
  • 98
  • 150
Jashwant
  • 28,410
  • 16
  • 70
  • 105

3 Answers3

9

If its not problem, you could use forward

http://www.yiiframework.com/doc/api/1.1/CController#forward-detail

public function actionIndex()
{ 
    $a = 5;
    if($a == 5){
        // Forward user to action "contact"
        $this->forward('contact'); 
    }
    else{
        $this->render('index');
    }
}

public function actionContact()
{
    // Some codes
    $this->render('contact');
}
briiC
  • 2,134
  • 17
  • 28
  • I guess, this is the standard way. If I am right, I can forward request to action method of another controller too. Am I right ?. I have already mark other question as answer, so +1. – Jashwant Apr 10 '12 at 08:04
  • Yes, its yii-way :) but i found hard to give it custom params, but for your problem it's ok. – briiC Apr 10 '12 at 16:41
  • sorry, didn't answer your question. Yes, you can forward it to another controller action :) – briiC Apr 10 '12 at 16:42
  • i am trying very same, but i cant forward it to a controller which works on PUT verb – Himanshu97 Aug 26 '14 at 12:11
  • I'm not sure but I think `forward` can't change original request. So you need to send `PUT` at the begining OR instead of forward make `curl` call that sends `PUT` request http://stackoverflow.com/questions/19257295/send-put-request-with-php-curl – briiC Aug 27 '14 at 06:57
3

"Repeat code" is very rarely the correct answer. Redirects involve additional overhead, and in my opinion they should mostly be used in response to POST actions, not like this. In this case I would go with solution 1.

DCoder
  • 12,962
  • 4
  • 40
  • 62
3

You could use a fourth option, which is refactoring the part that is common to index and contact actions into a third method:

public function common() {
    // ...
}

public function actionIndex() {
    // ... call $this->common()
}

public function actionContact() {
    // ... call $this->common()
}

The best option depends on your particular case, though. For example, when you decide you have to call a different action, do you want to render its view, too?

Joni
  • 108,737
  • 14
  • 143
  • 193
  • So, methods inside controller are not 'special'. They are just methods with specific names based on user action ? – Jashwant Apr 10 '12 at 07:24
  • 1
    if they start with 'action' they are special. in that you can call them via a url. otherwise you can have any old method name, and you can't call it from a url – Neil McGuigan Apr 10 '12 at 07:32
  • @NeilMcGuigan, No, I am thinking whether any variable is available in scope of those special methods (and only to those) whose name starts with 'action' – Jashwant Apr 10 '12 at 07:34
  • 1
    The "action" prefix is just a marker; from the PHP perspective they are just normal instance methods with standard scoping rules. – Joni Apr 10 '12 at 07:36