views:

182

answers:

1

Hello all, it's my first post here :)

I'm having some difficulties with dealing with urls and parameters. I've gone through the router class api documentation over and over again and found nothing useful.

First of all, I'd like to know if there is any 'universal' format in CakePHP(1.3) for handling urls. I'm currently handling all my urls as simple arrays(in the format that Router::url and $html->link accepts) and it's easy as long as I only need to pass them as arguments to cake's own methods. It usually gets tricky if I need something else.

Mainly I'm having problems with converting string urls to the basic array format. Let's say I want to convert $arrayUrl to string and than again into url:

$arrayUrl=array('controller'=>'SomeController','action'=>'someAction','someValue');
$url=Router::url($arrayUrl);       //$url is now '/path/to/site/someController/someAction/someValue'
$url=Router::normalize($url);      //remove '/path/to/site'
$parsed=Router::parse($url);       /*$parsed is now
Array(
    [controller] => someController
    [action] => someAction
    [named] => Array()
    [pass] => Array([0] => someValue)
    [plugin] => 
) */

That seems an awful lot of code to do something as simple as to convert between 2 core formats. Also, note that $parsed is still not in the same as $arrayUrl. Of course I could tweak $parsed manually and actually I've done that a few times as a quick patch but I'd like to get to the bottom of this.

I also noticed that when using prefix routing, $this->params in controller has the prefix embedded in the action(i.e. [action] => 'admin_edit') and the result of Router::parse() does not. Both of course have the prefix in it's own key.

To summarize, how do I convert an url between any of these 3(or 4, if you include the prefix thing) mentioned formats the right way? Of course it would be easy to hack my way through this, but I'd still like to believe that cake is being developed by a bunch of people who have a lot more experience and insight than me, so I'm guessing there's a good reason for this "perceived misbehavior".

I've tried to present my problem as good as I can, but due to my rusty english skills, I had to take a few detours :) I'll explain more if needed.

+1  A: 

The "official" format for Cake URLs should be the array notation array('controller' => 'foo', 'action' => 'bar', 'baz', 'admin' => true). Whenever you write URLs, you should use this format. The Router class will translate those to either strings (/admin/foo/bar/baz) or information needed for the Dispatcher (array('named' => array(), 'pass' => array(), …)), depending on where the URL is used.

You should think of it in terms of which controller action you want to invoke. URLs (as strings) are only a necessary evil to accomplish this in a web context. There shouldn't be any need for you to use the Dispatcher format. You should also not use the string notation when specifying URLs, since these can't be reverse-routed if you ever want to change your URL scheme.

Maybe you could explain with an example why you need to convert these three forms from one to the other?

deceze
Thanks for the quick answer.I asked this because not a sigle Cake function that I know of returns this(array) format. In lack of a real example, let's use $controller->referer(). The result of referer() is string, which I need to convert to array in order to modify it. The only way I know of is Router::parse(), which returns dispatcher parameters. If I wanted to compare the result to an array URL, I would also have to convert the array URL to dispatcher parameters, which is done through Router::parse(Router::normalize(Router::url($arrayUrl))). Not good.
Pichan
@Pichan The referrer is an interesting case in that it's both something you may want to parse, but at the same time something you shouldn't pay that much attention to in the first place. Since you're really in lack of an example it seems, my advise stands. :)
deceze
Let's say I need to save the current URL to session, so when after a certain task is completed, the visitor gets taken back to the page from where the task originated. Until now I've been using $this->params, which isn't the same as array URLs, so little tinkering is required to make them play nice.I just want to avoid having to hard-code URLs that already are available to the controller in some format. I'm starting to think Cake won't work with me on this one, but is it only Cake or is my thinking flawed? After all I'm rather green to the whole MVC thing so it wouldn't be a surprise :)
Pichan
Damn these comment boxes are small.To make my simple example above reflect the real world more, let's say that sometimes it's necessary to change the url parts, like controller or action which is kind of hard to manage if the URL is a string.I'm not really sure if array URLs and dispatcher params act the same with different routings, but if they are the same data in a different format, I could always write my own conversion functions.I'm getting the feeling though that it won't go how how I'd want it to go :) If you have some insight on this, please share your wisdom :)
Pichan
@Pichan I still think you will never really need this functionality, and there should always be another way to do it. In case of saving URLs to return the visitor to, you should be fine with just saving them as strings. I think saving that URL, but then changing parts of it is a rather contrived example. In that case you'd rather just save the part you're interested in, like `$this->params['action']`, and then cobble together a new URL in the standard array format. I think if there was a real need to convert the formats back and forth, somebody would have added that functionality by now. :)
deceze
Even though I'm still not 100% convinced, I'll try do things differently for the next project. At least I now have someone else's opinion besides my own on this :) Thanks for your time.
Pichan