wanted: consistent order for parameters in user-friendly URLs

I want to use user-friendly URLs (as described in the Yii Guide, in the

URL Management chapter), and I want to use patterns ending in "/*".

However, there is a problem with such patterns: when generating the

content that corresponds to "/*", Yii makes no guarantee about the

order of parameters.

As an example, consider the following 2 blocks of code: which differ

only in the order of the parameters.




$this->widget(

  'zii.widgets.CMenu',

  array(

    'items'=>array(

        array(

          'label'=>'random label here...',

          'url'=>array('a/b', 'c' => 1, 'd' => 2),

        ),

      )

    )

  );






$this->widget(

  'zii.widgets.CMenu',

  array(

    'items'=>array(

        array(

          'label'=>'random label here...',

          'url'=>array('a/b', 'd' => 2, 'c' => 1),

        ),

      )

    )

  );



Yii will produce different URLs in the two cases, even though both

URLs produce the same page.

What I would like is some way to tell the urlManager component that it

should sort the parameters by name before generating the URL.

If you’re just going to be sorting the querystring parameters alphabetically then why not just write them in the correct order? If the position of them is important then you can use parametised hostnames that will hide the actual variable name as well. Otherwise it seems like unnecessary bloat to the framework.

Several reasons. First of all, I’m not aware that Yii makes any guarantees about the order. So while the current release appears to use the array order, a future release might do something different.

Secondly, suppose that I decide to list all the parameters alphabetically. Then, some of the time, the parameters will be in an "unnatural" order and things which should be grouped together will be separated.

So why not use the "natural" order? Because "natural" is not a well-defined term here, so my ideas about the natural order may change over time, possibly leading to different orders in different parts of the codebase.

I hadn’t thought of that. But it looks like that would force me to change the urlManager rule every time I add a new parameter to the controller action, which is not good.

If you have an url witch will contain known params and you want a certain order, why not make a route for such url?

Like this:


'<controller>/<action>/<c:\d+>/<d:\d+>' => '<controller>/<action>'

And the signature of the action can be like this:


public function actionAct($c, $d)

{

    // Code here

}

In this case there will be no difference in what order you will pass the arguments - their place in the resulting url is predefined.

Psih,

thanks for your suggestion (which is similar to an idea of Say_Ten’s, above).

The idea is workable, but it means I have to edit the rule every time I change the signature of the controller method.