passing parameters to rewrited urls - php

My project have data about different websites so I have rewritten urls using .htaccess so that when ever someone passes a name containing a dot(.) to my website, it shows the site.php page. here is my code for that:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9\_\-]+(\.)[a-zA-Z0-9\_\.\-]+)/?$ site.php?url=$1
RewriteRule contact$ contact.php
This sends site name as parameter to site.php. Now I want one more parameter to be passed to is like it could have been passed in general, for ex. I want the site to get real time updated data, i want to pass ?update=true so that it updates the data from internet rather then taking it from database. But passing parameter like this
http://www.mysite.com/anysite.com?update=true
isn't working, how can I pass additional parameters to my existing rewritten url?

The [QSA] flag ("query string append") will append any received query string onto the rewritten URL. I have also added the [L] flag as a best practice to prevent a match to your first rule also matching an additional rule later on in your chain, should one ever be added.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([a-zA-Z0-9\_\-]+(\.)[a-zA-Z0-9\_\.\-]+)/?$ site.php?url=$1 [QSA,L]
RewriteRule contact$ contact.php [QSA,L]
However, if I have misunderstood the problem and you don't need for the browser to be sending update=true but rather just want to force it on all requests, simply add it to the rewrite rule:
RewriteRule ^([a-zA-Z0-9\_\-]+(\.)[a-zA-Z0-9\_\.\-]+)/?$ site.php?update=true&url=$1 [QSA,L]

Related

Why the url in which index.php is prefix with first segment in codeigniter works | Codeigniter | RewriteCond

I am working on a CodeIgniter project and today I found a very strange issue.
When I open the URL that is prefixed with index.php in the first segment it is still working even though I expect the URL to return a 404 Not Found page.
For example, the URL of my website is http://localhost/project and when I open the URL http://localhost/project/jobs it works fine, but when I open http://localhost/project/index.phpjobs it also works.
I don't know what is going on over here!
Please note that the URL doesn't include slash but is still working and that is not a typo.
Please check in your project and let me know if someone have the same problem because I think this problem may also exist in your current project but not noticed.
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^admin(.*)$ admin/index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L]
RewriteRule ^.well-known/ - [L,NC]
Your first rewrite rule
RewriteRule ^admin(.*)$ admin/index.php?/$1 [L]
will be honored only if the previous two conditions
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
have been met.
Now, the trick lies in these conditions which basically say that the rewrite will be performed only if the requested resource (REQUEST_FILENAME here) does not exist as either a file or a folder.
Since index.php obviously exists the rewrite rule is skipped and the server actually receives the original (non-rewritten) request.
That is the reason why you see the same result for requests that both do and do not contain /index.php/ as prefix.
The same applies for both sets of rewrite, the one you are using for your admin page and the regular one.

Keep question mark on $_GET with rewrite rule

So I've found this interesting question on making the question mark symbol appear on $_GET variable after using rewrite rules.
However, as much as I've tried to accomplish this myself, I didn't quite understand how it works to have the same result on my website.
Here's my rewrite rule:
RewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]
This basically allows me to route users to specific places without hard coding each page on my htaccess file, so if a user goes to /about/contact page, he's actually going to index.php?uri=/about/contact.
The problem is that sometimes I WANT the question mark to be kept in $_GET. Let's say a topic title of "What's up?" then my url would search for a topic like /topic/what-s-up? and would match with what-s-up? in the database. But, right now, my $_GET variable stores just "what-s-up" (without the "?") and my database still stores "what-s-up?" (with the "?"), which would say that there's no topic with that title when there actually is.
How can I keep the question mark so /topic/what-s-up? still translates to /topic/what-s-up? in the query string?
EDIT: FULL .HTACCESS FILE FOR TEST PURPOSES
Options -Indexes
DirectoryIndex index.html index.php
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]
You can change your rule to this to capture optional ? in uri parameter:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} \s/+([^?]*\??\S*)\sHTTP [NC]
RewriteRule ^(.+)$ index.php?uri=%1 [QSA,L]
Since we want ? also to be captured we are using RewriteCond %{THE_REQUEST} since pattern in RewriteRule only matches REQUEST_URI. Since we are capturing value from RewriteCond hence we are using %1 instead of $1 as back-reference.
THE_REQUEST variable represents complete original request received by Apache from your browser and it doesn't get overwritten after execution of some rewrite rules. Example value of this variable is GET /index.php?id=123 HTTP/1.1
I know its late, but i used php urlencode() to pass the question mark, as it converts ? to %3F

Pagination and htaccess

I am looking for some help in my htaccess to better handle my urls when using a pagination function.
Currently my htaccess looks like this:
RewriteEngine On RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9-]+)/?$ index.php?alias=$1 [QSA,NC,L]
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ index.php?alias=$1/$2 [QSA,NC,L]
basically, I have two rules. At first I only had the second one, to direct all requests to my index page, where I then parse out some details of the url in order to show the correct content. I found that it didnt work for urls with only one sub directory, like example.com/bars, but only two directories like, example.com/bars/bar-name, so I added the rule before it.
This has been working great for me. All of my urls look great and the ?alias=bars/bars-name has been completlely hidden and now looks like /bars/bars-name
Recently though I have integrated a pagination php function. This function creates urls that looks like this:
example.com/bars?alias=bars&info=mysql_table_bars&page=2
Basically, 'info' is the table name that the pagination function queries, and 'page' is the current page. It seems 'alias' also started showing in the url once I started using this function.
What I would like is for my pagination to look like these examples:
example.com/bars/page/2
example.com/hotels/page/5
etc...
What do I need to add to my htaccess to handle this situation? Also, is there a way to simplify my existing two rules?
Regarding your original rules. The conditions that you have only get applied to the immediately following RewriteRule, so you need to duplicate them:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9-]+)/?$ index.php?alias=$1 [QSA,NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ index.php?alias=$1/$2 [QSA,NC,L]
For the new pagination stuff, firstly, it is really bad to be pulling database table names from the query string, unless they've been validated somehow (which may be what's happening). But even then, it's still an information disclosure problem. So you can use these rules to always remove them:
# This matches the actual request when there's pagination in the query string
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/\?]+)\?alias=([^&\ ]+)&info=.*&page=([0-9]+)
# an optional sanity check, does the request URI match the "alias" param?
RewriteCond %1:%2:%3 ^(.*):\1:(.*)$
# redirect the browser to the URL with the table name removed
RewriteRule ^ /%1/page/%2? [L,R=301]
Then you need rules to internally rewrite them back to the request with the query string:
# rewrite it back to the query string
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?([^/]+)/page/([0-9]+) /$1?alias=$1&info=mysql_table_$1&page=$2 [L]

.htaccess issue when creating users profile?

I am using .htaccess code in order to pass pages titles to the url and then retrieve them with php from mysql tables when the page loads.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
I am using this php code to explode the url and get the title:
$passed_url = $_SERVER['REQUEST_URI'];
$passed_url = explode("/", $passed_url);
$passed_url = end($passed_url);
Now I want to create a user profile page like so www.website.com/users/User_name_in_here
how do I check with php if this is a users page or it is just a regular page which can be writer like so: www.webiste.com/Page_title_in_here
is there a better way to do this ?(I am just a starter in php)
One way is to check $passed_url[1]. If it's 'users' then you know you're on the users page.
A better way would be to use index.php as a front controller and pass the request to a controller based on the request uri. there are a number of ways to do this.
Some frameworks map the uri to a class::method. So your url would be changed to /users/view/username and the users::view would be called.
I prefer to write regular expressions and which ever regular expression is matched controls which controller is loaded.
You can actually change your Rewrite Engine .htaccess file this way:
RewriteEngine On
RewriteRule (.*)-(.*)\.ptf$ ./?page=$1&id=$2&%{QUERY_STRING}
RewriteRule ^([^/]*)\.ptf$ ./?page=$1&%{QUERY_STRING} [L]
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ ./?page=$1&id=$2&%{QUERY_STRING}
So, this rule, what it exactly does is:
when the URL is www.website.com/Page_title_in_here,
it goes to www.website.com/?page=Page_title_in_here
and when you put this way, www.website.com/users-User_name_in_here,
it redirects to www.website.com/?page=users&id=User_name_in_here
So you can manipulate with the $_GET["page"] and $_GET["page"] variables!
What say? I do this way. Hope this helps you!

.htaccess losing URL parameters/$_GET and $_POST after redirect

I have a php file like: http://www.domain.com/?mod=test&act=view
And I want to create a redirection from that address to something like: http://www.domain.com/view-test
so that everytime a user accesses the first uri it gets redirected to http://www.domain.com/view-test viewing the content of the first uri.
I have the following rules:
RewriteCond %{QUERY_STRING} mod=test&act=view
RewriteRule ^$ view-test? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^view-test.html amas/index.php?mod=test&act=view [L]
This works fine for pages without parameters or forms submissions but If I have any of those nothing works.
Meaning that if I have a form that is submitting to the same file it won't work. If i have something like http://domain.com/?mod=test&act=view&order_by=id i'm left with the redirected to uri and the order_by parameter is ignored!
Is it even possible to do what I'm trying? I don't really know much about this and to be honest I'm lost between all the info I find... :/
Use Query String Append:
RewriteRule ^view-test.html amas/index.php?mod=test&act=view [L,QSA]

Categories