Rewrite URL to only show value of $_GET argument

Francis Daly francis at daoine.org
Wed Sep 11 14:31:17 UTC 2013


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



More information about the nginx mailing list