0

In config.php I have

'urlManager'=>array(
    'class'=>'UrlManager',
...

In UrlManager.php I have

class UrlManager extends CUrlManager
{
    public function parseUrl($request)
    {
        ...
        setcookie(microtime(true),date('H:i:s'),strtotime('+10 minutes'));
        return parent::parseUrl($request);
    }
}

When I try open page I see two cookies was produced by setcookie(microtime(true),date('H:i:s'),strtotime('+10 minutes')); I expect there is would be just one cookie.

492786392.9662  17%3A53%3A12  // first cookie
1492786392.9704 17%3A53%3A12  // second cookie

It means method parseUrl runs twice. But why? Is it normal behavior or can I avoid it?

I found just this topic http://www.yiiframework.com/forum/index.php/topic/3558-url-manager-causes-page-to-load-twice/ but without desicion.


Update 1.

I added var_dump('_',Yii::app()->request); and noticed that first output has

private '_cookies' (CHttpRequest) => null

as second output has

object(HttpRequest)[2982]
...
object(CCookieCollection)[3044]
  private '_request' => 
    &object(HttpRequest)[2982]
  private '_initialized' => boolean true
  private '_d' (CMap) => 
    array (size=1)
      'YII_CSRF_TOKEN' => 
        object(CHttpCookie)[3043]
          public 'name' => string 'YII_CSRF_TOKEN' (length=14)
          public 'value' => string 'b78823914a0bb40b65093636b55687e683cf289f' (length=40)
          public 'domain' => string '' (length=0)
          public 'expire' => int 0
          public 'path' => string '/' (length=1)
          public 'secure' => boolean false
          public 'httpOnly' => boolean false
          private '_e' (CComponent) => null
          private '_m' (CComponent) => null
  private '_r' (CMap) => boolean false
  private '_e' (CComponent) => null
  private '_m' (CComponent) => null
venoel
  • 463
  • 3
  • 13
  • Well if it has run twice, it was called twice. You should log $_SERVER on the two requests and compare it. What's the difference? Could be JS / CSS / iframe, etc. call which led to URL parsing. – szako Apr 22 '17 at 19:28
  • I have added to function parseUrl setcookie(microtime(true),date('H:i:s'),strtotime('+10 minutes')); var_dump('_',$_SERVER); return parent::parseUrl($request); But did not make it clear. $_SERVER is outputing twice. Sometime there is difference, sometime there is not. In my local nginx differnece 'HTTP_PRAGMA' => string 'no-cache' 'HTTP_CACHE_CONTROL' => string 'no-cache' In my local apache 'HTTP_CACHE_CONTROL' => string 'max-age=0' There is not difference in my remote developer environment with nginx. So issue is still open. – venoel Apr 24 '17 at 08:52
  • You mean it gets outputted twice in one request? And if there's a a difference, what it is? Does the problem exists both in local and remote? Try to check [backtrace](http://php.net/manual/en/function.debug-backtrace.php) differences. Debugging would be better if you can. – szako Apr 24 '17 at 09:36
  • Yes, it get output twice per one request. There are differences in previous comment. Problem exists local and remote. Apache and nginx. – venoel Apr 24 '17 at 11:54
  • Well, then it's not relevant. Check calling hierarchy with backtrace command, mentioned in prev. comment. Is it the same? – szako Apr 24 '17 at 12:21
  • @szako, I update question with "Update 1" – venoel Apr 24 '17 at 15:38
  • You using the last Yii version in the 1.1 line, right? You can try skip rendering the layout, just call the pure controller method and check what's happening. Try exiting from index.php and check if it's called twice and you can rule out the browser / os calling multiple times. You mentioned 3 enviroments (local apache, local nginx, remote nginx, in all three the parseUrl is called twice? Did you try to debug the code in local enviroment? – szako Apr 25 '17 at 06:02
  • There is Yii 1.1.15, it is not last. Skip rendering (exit before $this->render) gives same result, now I even see triple calls. All three environment gives twice or triple calls. I've used debug. Important notice I did not mentioned. I have additional behavior class for runEnd function. So it is seems reason why HttpRequest object is created twice and respectively parseUrl is called twice. – venoel Apr 25 '17 at 08:13
  • Well, that was an important information... The trace should have showed the diff in call stack. – szako Apr 25 '17 at 09:40
  • As I understand I can't avoid double calls. – venoel Apr 25 '17 at 10:36
  • You cannot avoid multiple calls, but you can avoid setting multiple cookies. See my answer. – szako Apr 25 '17 at 11:44

1 Answers1

0

Via comments the cause was examined. The parseUrl is called multiple times because you have an additional parseUrl calling later in the program flow.

Use a user parameter for controlling the cookie setting, for example name it 'cookieSet' or anything else that suits your need. Once the parseUrl() ran, you can set it to '1' or true and the in the second run you can skip it checking the parameter. In this way cookie setting runs only once in one call.

szako
  • 1,271
  • 1
  • 9
  • 12