How to do MVC form url formatting?

2019-04-11 11:11发布

I am using PHP. I want to create an MVC setup from scratch to learn more about how MVC works. I want to use clean urls with slashes as delimiters for the arguments. How do people do this when it comes to GET method forms? Or do people avoid GET method forms all together?

As of right now the ways I can imagine are:

  1. Don't use GET method forms (although this makes it harder to let users bookmark/link in some cases).
  2. Use AJAX instead of form submission (although what do you do for SEO and JS disablers?).
  3. Have page submit to itself with post method, then reform the post vars into an url, then rerout to that url using headers (seems like wasted resources).

Any suggestions or suggested reading welcome.

10条回答
欢心
2楼-- · 2019-04-11 11:14

What you're referring to with the URLs really has little to do with MVC. It is an implementation of REST architecture. ( Wiki Article )

Basically instead of using sessions, each URL should contain all of the information the server needs in order to create a request.

There are a couple of ways of doing this:

You can use Apache's mod_rewrite to rewrite a PATH to the proper GET parameters. For example say you have a user management module that is normally accessed with:

http://your.domain/users.php?request=edit&id=<some id>

You could put in Apache:

RewriteRule ^users\/edit\/(\d+) /users.php?request=edit&id=$1

Which would then allow you to address the same request with:

http://your.domain/users/edit/<some id>

(this is assuming ID is a number)

This is pretty easy to if all of the requests you expect to issue are pretty simple. If they are more dynamic then it gets harder to set it all up. The other drawback, if you were wanting to release your new framework, would be that it requires your user to have at least the ability to modify the Apache config through .htaccess files. That may not always be the case.

The alternative is write logic in the code that can parse the URL. In this case you usually need a controlling script for your entire site. The URL would be something like:

http://your.domain/users.php/edit/<some_id>

<?php

// get the part that appears after the script name
$parts = explode("/", $_SERVER['PATH_INFO'] );

$request = $parts[1];
$id = $parts[2];

// do somethign with the $request and the $id 

?>

As you can see, my example is simplistic but with option 2, it's easier to put much more complex logic to do all sorts of things.

Hope that helps.

查看更多
Viruses.
3楼-- · 2019-04-11 11:16

The answer to this depends on what kind of page the resulting page will be. If you are going to give the user a page with a single item on it, I would redirect them to that page, with a pretty URL. That's not a huge demand on the system.

If I was going to show a list of results for a search query, I might well go for an unformatted GET query. This, after all, could be a useful URL, which people might pass around:

http://www.example.com/search?name=lonesomeday&site=stackoverflow

On the other hand, if there was only one field, I might well redirect to a more simple form:

http://www.example.com/search/lonesomeday

YMMV, of course.

查看更多
戒情不戒烟
4楼-- · 2019-04-11 11:16

Hey dqhendricks, I am doing somewhat what you are doing -- learning MVC by studying other frameworks and creating one from scratch.

First of all, you shouldn't use GET to handle any form data. Use POST or PUT instead. POST is used only for retrieving information from web service. You can use actions in GET pretty much to manipulate what information to retrieve (e.g. sort order, page, etc).

Regarding your points:

1) Don't use GET method forms

Correct. It sounds incorrect in the first place that in order to get a certain view you have to use a form.

2) Use AJAX instead of form submission

Exactly. Your forms and URL's should work both with and without JS.

3) Have page submit to itself with post method, then reform the post vars into an url, then rerout to that url using headers (seems like wasted resources).

I would not say this is wasted resources. It will take only milliseconds for your app. In fact this is exactly what I end up doing. When front controller detects use of POST, it dispatches it to the Controller which performs necessary actions on submitted data. Based on result, app either redirects client, or renders requested page (no redirect). And yes, it works the same way for ANY URL.

At the same time, if a certain param was found in the URL, Front controller dispatches to respective controller. But this is never used to process data in any way. For example, this is used to remember preferred domain (www or mobile) when you want to use www when you browse in mobile browser.

Also, IMO you could say that wasted resources would be APP deciding where to redirect (or passing redirect URL in HTTP query or PHP session). In any case, it takes both development time and server resources to implement alternative methods.

So #3 is the way to go, in my opinion.

查看更多
趁早两清
5楼-- · 2019-04-11 11:20

As what i understand and my personal experience, none of your 3 points apply to how to handle a MVC Pattern:

  1. thats a good and classy one about the subject http://www.w3.org/2001/tag/doc/whenToUseGet.html , basically, get is the way to go if the resulting URL coresponds with content, for an Example, don't use GET to pass information you want to save, don't use POST do transmit a ID of content you want to show the User. Its all about Url Patterns, and rewrites, you can probably draw some inspiration from the zend framework router http://framework.zend.com/manual/en/zend.controller.router.html basically isn't /?id=123 the same as /weird-article-slug-123 when you know your URL Pattern is ^[\w\d-]+([\d]+)$?

  2. Nope, sorry, AJAX is at the very most, a way to use JS,so your AJAX Functions can only take advantage of your MVC Backend Application, the same way ... well, your "normal" HTML Interaction does.

  3. That would be "wasted resources" indeed

查看更多
兄弟一词,经得起流年.
6楼-- · 2019-04-11 11:20

Forget about second approach - it's an horrible idea.

  1. Usually you can use standard QueryString (...?a=b&c=d) in "GET forms" as their URLs aren't important.
  2. However, if you really want to have nice URLs all the time you'll have to send a form (GET/POST - doesn't matter) and redirect user:

    if (/* form has been submitted */) {
        $data = array_map("urlencode", $_GET);
        $url = sprintf('/%s/%s/%s', $data['a'], $data['b'], $data['c']);
    
        header("Location: $url");
        echo "Redirection: <a href='$url'>$url</a>";
        exit;
    }
    
  3. Eventually if you're worried about server resources you could use JavaScript to do that:

    formReference.addEventListener("submit", function() {
        /* do exactly the same as above PHP code */
    
        return false;
    }, false);
    

    Of course server-side redirection should be left in case somebody has disabled JS.

查看更多
叛逆
7楼-- · 2019-04-11 11:21

Get variables and clean URLs don't contradict each other. You can always have URLs like

http://example.com/controller/action?value1=foo&value2=bar

An alternative URL style could also look like

http://example.com/controller/action/value1/foo/value2/bar or http://example.com/controller/action/foo/bar

In these 2 cases if you want to create these URLs via a form GET submit you will have to use JavaScript to assemble the correct URL therefore the very first solution might be easier to implement.

Another question is the decision between POST and GET form submission. POST is more secure but as you said, users can't bookmark it.

查看更多
登录 后发表回答