I am very noob to this URL rewrite. just got a question in my head.
www.example.com/?page_name=home
The $_GET['page_name'] is actually home
after the URL rewrite the url become
www.example.com/home
can PHP still get the $_GET['page_name'] is 'home'??
Thanks
The URL rewriting is done by the web server, let's say in this case Apache. This is not the same as PHP.
Apache receives a request for the URL www.example.com/home. It now needs to figure out what to do with this request. It will check its configuration for something that matches www.example.com, which will point it to a document root, i.e. some folder on the hard disk. It checks that folder on the hard disk and encounters an .htaccess file. It evaluates the .htaccess file, which tells it to rewrite the URL from /home to ?page_name=home.
Apache now tries to figure out what to do with ?page_name=home. Since there's no filename given, it defaults to index.php (which hopefully exists). It now runs that index.php file in the document root, passing it ?page_name=home as the URL it has received. PHP takes it from there, oblivious of the rewriting that happened. To PHP, it appears that you have received the parameter page_name as query parameter and puts it in $_GET.
Try using rewriting like this (change it as per your need):
RewriteRule ^([A-Za-Z0-9-_]+)/?$ index.php?page_name=$1 [L]
Above rule redirects
http://www.domain.com/string_LiKe-this53/
on a real existing page
http://www.domain.com/index.php?page=string_LiKe-this53
on which you can use your $_GET['page'], which will have value string_LiKe-this53.
It depends on the rewrite rule, but yes, you can get it to work as intended.
The following rewrite rule:
RewriteRule /home /index.php?page_name=home
Will simply cause requests to /home to execute index.php with $_GET['page_name'] equal to "home".
Depending on the complexity of your site, however, it may be preferable to use a more generic rewrite rule, such as:
RewriteRule ^(.+)$ index.php/$1
Then you would query $_SERVER['PATH_INFO'] to see if it contained "home". This will play nicely with other $_GET parameters that may be passed in.
Related
I'm trying to create nice urls with .htaccess files and have come across a weird issue.
I want to change portfolio.php?id=2 to /portfolio/2/
seems pretty simple solution
RewriteRule ^portfolio/([0-9]+)/$ /portfolio.php?id=$1 [L]
this does redirect to the correct script but when i try and run <?=$_GET['id'];?> it is undefined. but if change the script to something that does not equal the fake directory it works.
RewriteRule ^portfolio/([0-9]+)/$ /portfolioitem.php?id=$1 [L]
and just to make sure that it wasn't being caught by any other rules I tested this
RewriteRule ^portfolioitem/([0-9]+)/$ /portfolioitem.php?id=$1 [L]
and again it failed to pick up the id paramater!
any ideas?!
Cheers
This sounds suspiciously like a Multiviews related problem coupled with some PATH_INFO. The Multiviews option is part of mod_negotiation and it will try to match a requested URL path to a file path. It sees:
/portfolio/2/
And sees that there's a /portfolio.php file in the filesystem and assumes that this is what you want (which it is, but not in the same way). I'm willing to bet that instead of looking at $_GET['id'], which is blank of course since there are no GET params, if you look at $_SERVER['PATH_INFO'], you'll see it set to /2/. This is equivalent to going to:
/portfolio.php/2/
where the /2/ part gets passed to portfolio.php as part of the PATH_INFO. And since mod_negotiation is further up in the processing pipeline than mod_rewrite, your rewrite rules never get applied.
Try turning off multiviews. You can do this in your htaccess file using the Options directive (assuming your host has allowed Options):
Options -Multiviews
I have a number of urls that are stored in a database, and thus instead of adding a rewrite rule in .htaccess for every url, I am using the following code in htaccess to give the control to PHP code through the following ReWrite rule in Apache:
RewriteRule ^.*$ ./index.php
A url mentioned in the database, has a corresponding original url. Though, the tricky situation comes when I have to serve the content of the url fetched from DB by the corresponding original url for which the ReWrite rules are written in .htaccess. One solution is to implement the same rewrite rules for the url fetched from DB in PHP as written in Apache for the original url, however, the number of such original urls is huge.
Thus would be glad to know about a solution if possible which can make execution flow through the ReWrite rules mentioned in Apache after the processing inside PHP is complete.
If you have access to the main httpd.conf you could use a RewriteMap written in PHP.
Other than that, there is no way you can give control from PHP back to Apache so Apache can process it further, not in the same request anyway. You could do a 30x rewrite from PHP to let Apache work on the next request.
Basic rewriting, rather create an apache rule to redirect all 404 errors to a php file, which will be your url handler, using the requested url do a lookup in your list of urls in your database, return the original url to your handler, from there either do a redirect or fetch the page contents server-side/ajax the page/iframe whichever you perfer, if the requested url is not in your list display your custom 404 page, this kills two birds.
Setting up a 404 page:
http://www.404-error-page.com/404-create-a-custom-404-error-page.shtml
I don't even know how this method is called, I just know the behavior I want to achieve.
My example for this is Facebook. If you go to facebook.com/[username or id] you get to the profile page, but I can't imagine that they're creating a directory in their root folder and putting a index file in there for every user.
So how's the following behavior accomplished; You go to somepage.com/foo/bar/hello but actually you're requesting somepage.com/foo?bar=hello ?
Is this even possible with Apache and PHP?
I don't even know how this method is called, I just know the behavior I want to achieve.
That thing is called URI/URL and the local part of it is passed to a webserver. The webserver then processes the request.
Is this even possible with Apache and PHP?
Yes. Not even even. This is what a webserver is for. What happens on the server is entirely shielded by the HTTP protocol which knows only the URI/URL specification which does not regulate if and how that needs to match to concrete processes or files on the webserver.
For example with the Apache HTTP Server there is a famous module called Mod_Rewrite that does URL-Rewriting. Often in a fashion that the user with her browser does not take any notice of it.
Example configuration with a PHP file (Apache HTTPD):
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>
In a PHP script you can obtain the URI/URL by making use of special variables like $_SERVER['REQUEST_URI'] and $_SERVER['QUERY_STRING'].
Commonly this is made with mod rewrite. There you can make a "path" to a variable of a script.
E.g. http://example.com/user/1/edit could be translated with mod rewrite to http://example.com/index.php?function=edit&userid=1
Such a rule would look like this:
RewriteEngine on
RewriteRule ^/user/([0-9]+)/([a-z]+)$ index.php=function=$2&userid=$1 [L]
The first line activated the rewrite module the second line has a regular expression which must match for rewrite the url internally. If you like you can also make that externally with an [R] modifier instad of the [L].
Have a look to the whole documentation to learn more.
The stuff in the breckets are so called flags which are also well documentated.
I hope that helps!
I just inherited a website built in PHP. The main page of www.mysite.com has a href to www.mysite.com/index/35.html somewhere in the page. In the site's root directory and its children there is no document 35.html.
The number 35 is actually an id found in a DB which also holds the html contents of the page.
If I load URL: www.mysite.com/index.php?id=35 the same page loads.
How does PHP know how to automatically convert
/index/35.html
to
/index.php?id=35
EDIT
Based on the answers, I have found a .htaccess file containing rewrite instructions that would explain the functionality.
However, IIS doesn't seem to (or is not configured) know how to use this. (probably because this is an Apache feature?)
So this begs the following question: Is there a way to configure IIS to work with this?
it will be done usign URL Rewriting using .htaccess - should be in the webroot.
It may look something like:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
May have other bits, but what this basically tells apache is to send anything that DOES NOT physically exist to index.php
It doesn't. There is a mod_rewrite rule that rewrites from /index/foo to /index.php?id=foo, either in a .htaccess file somewhere or in the httpd configuration itself.
RewriteEngine On
RewriteRule ^index/([\d]+)\.html /index.php?id=$1 [NC,L]
This is off the top of my head. Any browsers trying to load an address starting with index/ has any number ending in .html will be internally redirected to index.php?id= whatever the number is.
Edit: Just saw that your working on IIS. This probably won't work for you. Sorry.
I think you will be using .htaccess to redirect all requests to index.php. From there You can pass the query string a routing class, which will parse the url and identify the unique ids.
In this case we can say like, your routing class will parse the request /index/35.html to indexController, indexAction, id=35. now you can pass this id to the model to get corresponding page contents
NB : Here I a am assuming you are using mvc pattern. Anyway it can be treated in your own way, with the concept remaining the same. Hope this make sence.
I'm using Mod Rewrite to remove index.php. I do not want to use queries. I want foo.com/bar to be interpreted as foo.com/index.php/bar.
It does this fine, but gives me Not Found error. The requested URL /home/foo/www/index.php/bar was not found on this server.
Why!!
Update
I think I just figured out what you are wanting to do. You see, you can pass queries behind the scenes, but you cannot pass what you are suggesting behind the scenes. You have to do an actual redirect. Something like this (The important part is the R):
RewriteRule ^bar$ index.php/bar [NC,QSA,R]
This forces a redirect to your page using the new special path. Is that what you wanted?
Original Answer
You cannot pass a path to a PHP page like that as it will be interpreted as part of a path. Chances are, your file is on a Linux/Unix machine where a directory can be named with a . in it. Sorry, but you will have to use a query string:
RewriteBase /
RewriteRule ^bar$ index.php?page=bar [NC,QSA]
Or updated:
RewriteBase /
RewriteRule ^bar$ index.php?/bar [NC,QSA]
I also think the last few versions of windows support . in directories as well, but I am not sure.
index.php is almost certainly a file, not a directory, unless you (bizarrely) have a directory called index.php. Apache is correctly complaining that there is no such directory.
You probably meant to do something like index.php?page=bar. Adjust your .htaccess accordingly.