Rewrite URL to only show value of $_GET argument

Andrew Martin andrew.s.martin at gmail.com
Mon Sep 16 05:32:57 UTC 2013


Francis,

I ended up coming up with this solution:
map $request_uri $request_basename {
    ~/(?<captured_request_basename>[^/?]*)(?:\?|$)
$captured_request_basename;
}
server [
....
        try_files $uri $uri/ @rewrite;

        location ~ [^/]\.php(/|$) {
                fastcgi_split_path_info ^(.+?\.php)(/.*)$;

                if (!-f $document_root$fastcgi_script_name) {
                        return 404;
                }

                fastcgi_pass 127.0.0.1:9004;
                fastcgi_index index.php;
                include fastcgi_params;
        }

        location @rewrite {
                if (!-e $request_filename) {
                        rewrite ^/article/[^/]+$
/index.php?title=$request_basename last;
                }
        }
....
}

This allows me to visit this URL in the browser:
http://mysite.com/article/my_test_page

and have nginx internally load this page:
http://mysite.com/index.php?title=my_test_page

Thanks again for all of your help,

Andrew


On Wed, Sep 11, 2013 at 9:31 AM, Francis Daly <francis at daoine.org> wrote:

> On Wed, Sep 11, 2013 at 08:32:09AM -0500, Andrew Martin wrote:
>
> Hi there,
>
> > Using the similar statement "try_files $uri $uri/ /index.php;", if I
> visit
> > this URL:
> > http://mysite.com/index.php?title=my_test_page
> > then the URL is rewritten to this, but it just loads the contents of
> > index.php (without the title variable):
>
> When you say "the contents of", you mean "the unprocessed php", yes?
>
> In nginx, one request is handled in one location.
>
> You must put all of the configuration that you wish to apply to a request,
> in the one location that handles that request.
>
> This means that if you have a "location = /index.php", then if the
> request is for /index.php, your "location ~ php" will not be used.
>
> In this case, can I suggest that you use a slightly different approach,
> to keep separate things separate?
>
> Something like (untested):
>
>   try_files $uri $uri/ @fallback;
>
>   location = /index.php {
>     # the browser requested /index.php
>     if ($arg_title != "") {
>       return 302 http://mysite.com/$arg_title;
>     }
>     fastcgi_pass 127.0.0.1:9000;
>     include fastcgi_params;
>   }
>
>   location @fallback {
>     # the browser requested something that is not on the nginx filesystem
>     fastcgi_pass 127.0.0.1:9000;
>     fastcgi_param SCRIPT_FILENAME $document_root/index.php;
>     fastcgi_param QUERY_STRING title=$uri;
>     include fastcgi_params;
>   }
>
> but there will be rough edges there -- you may want the "include" line at
> the start of the @fallback stanza rather than the end, and you probably
> will need to tweak the QUERY_STRING param passed (to remove the leading /
> on $uri, most likely).
>
> You can test to find what exactly is needed.
>
> Probably enabling the debug log until you are certain that you understand
> what nginx is doing, will be helpful.
>
> > The php code is a custom page, not a pre-built CMS. It is doing an ajax
> > call to load the content, but should be functionally-equivalent to this:
> > <html>
> > <head></head>
> > <body>
> > <!-- header code here -->
> > <?php
> > if (isset($_GET['title'])) {
> >      include($_GET['title'] . ".html");
> > } else {
> >      include("home.html");
> > }
> > ?>
> > <!-- footer code here -->
> > </body>
> > </html>
>
> Can I suggest that you test initially with that exact code, rather
> than something that should be functionally equivalent? Keep it simple,
> so that you can see at what point in the sequence things first fail.
>
> (Even better: just do something like "print $_GET['title']", so you can
> see exactly what you received. After that works right, add the complexity.)
>
> If "ajax" means "makes further http requests of nginx", then you'll need
> to make sure that the first one works before trying the subsequent ones.
>
> > If I go to this page:
> > http://mysite.com/index.php?title=my_test_page
> > I would like the client's browser to instead show this URL:
> > http://mysite.com/my_test_page
>
> The "return" should do that.
>
> What you now also want is for, when you go to
> http://mysite.com/my_test_page, that nginx knows to tell the fastcgi
> server to process the index.php page with certain arguments. For that,
> you must configure nginx correctly.
>
> Keep a very clear picture of how the browser, nginx, and the fastcgi/php
> server communicate, and you'll be able to work out where things are not
> doing what you expect them to do; and then you may be able to see what
> to change, to get the to do what you want.
>
> > Does this help clarify what I am looking for?
>
> Building your own php framework, and making it work with nginx.
>
> If you search for how every other framework does this, you may find
> useful hints as to how your one will work.
>
> Good luck with it,
>
>         f
> --
> Francis Daly        francis at daoine.org
>
> _______________________________________________
> nginx mailing list
> nginx at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx/attachments/20130916/f9ba7432/attachment.html>


More information about the nginx mailing list