I have a web page that generates QR code.
I want the link to look like "website.name/qr/data_to_convert"
So I used the following in .htaccess file.
RewriteRule ^([\s\S]+)/?$ create.php?data=$1
This is so that I can convert any character set to QR code.
But I get an error.
So I tried to make it:
RewriteRule ^([A-Za-z0-9\!\#\#\$\%\^\&\*\(\)\_\-\+\=\{\}\[\]\;\:\'\"\<\,\>\.\?\|\~\`\s\/\\]+)/?$ create.php?data=$1
And now the data that is passed is "create.php"
I have just one rewrite rule in this htaccess file apart from the
RewriteEngine On
command.
What should the regexr be so that I can include any text after "qr/" to convert it to QR code.
Thanks.
Update: I get the data passed as create.php even for the first regex
Related
I've been trying to redirect this URL (and all its substructures):
http://example.com/archive/
to (and its corresponding substructures):
http://archive.example.com/
For example: http://example.com/archive/signature/logo.png ==> http://archive.example.com/signature/logo.png
I tried to generate an .htaccess rule using a generator and evaluating it by looking at the regex, which I can understand (I think).
The result was the following rule:
RewriteEngine On
RewriteRule http://example.com/archive/(.*) http://archive.example.com/$1 [R=301,L]
The way I see it, the server will proccess any URL that starts with http://example.com/archive/ , will capture the string that comes next and will change the whole initial portion with the subdomain structure and append the captured string.
Unfortunately, this doesn't seem to work neither on my server, nor on online testing tools such as: http://htaccess.madewithlove.be/
Is there anything I'm missing there?
Thank you!
You should be able to try it this way.
RewriteEngine On
RewriteRule ^archive/(.*)$ http://archive.example.com/$1 [R=301,L]
Note that I did not make it dynamic as you didn't specific if you will have more URL's that need to work this way as well or not.
I currently have rewrites in an htaccess file of mine and need to account for a jumplink.
The issue I beleive I am having is the '#' keeps getting recognized as a comment.
I've seen questions on here suggesting the use of the [NE] or [R] flags, but either I am not using them correctly or they do not do what I need.
My current working rewrite is:
RewriteRule ^news/([^/]*)/([^/]*)/*$ display_news.php?yid=$1&mid=$2 [L]
My idea was to append another segment to the end of the url with something like this:
RewriteRule ^news/([^/]*)/([^/]*)/1/*$ display_news.php?yid=$1&mid=$2#jumplink [L]
With my use of the [NE] and [R] flags I replaced ? with 3F and $ with 24 for hexcodes given by http://www.asciitable.com/. Do I have to enclose these codes with special brackets or something? How would Apache know I don't literally mean 3F or 24.
The current behavior when I try to place these hexcodes in my file I get the internal server error.
If there is a more elegant method to account for jumplinks in an htaccess file I am all ears.
EDIT:
As suggested here are example URLs of what I am expecting.
http://website.com/news/2013/11 would map to display_news.php?yid=2013&mid=11
and
http://website.com/news/2013/11/1 would map to display_news.php?yid=2013&mid=11#jumplink
But I would want the address to remain in the format http://website.com/news/2013/11/1 and just map to the page.
This should work:
RewriteRule ^news/([^/]*)/([^/]*)/1/?$ /display_news.php?yid=$1&mid=$2#jumplink [L,NC,QSA,NE,R=302]
I suggest you to provide example of URIs that you want to match and what what is your target URI.
The #jumplink part of the URI that you've rewritten to is completely meaningless to the server. The URL fragment (the #jumplink part) is used by browsers and javascript running on browsers. It's not even passed to php.
You can try adding an R flag to externally redirect the browser but I'm guessing that's not what you want.
Recently, I'm experimenting with PHP's mod_rewrite engine. A bunch of tutorials I've read gave me a pretty good picture how to use its most basic and useful possibilities. But there is still that question I didn't find the answer for. I guess it should be the very first question to be explained but no tutorial gave me the answer yet.
I'm wondering which very part of URL is being considered when trying to match the regex.
Let's say I have a directory my_project on my server and a .htaccess file inside that directory. The browser should see the directory like this:
http://my_website.com/my_project
If I add a rule in .htaccess then which part of the above URL will be considered when trying to match the regex of this rule? I'm pretty good in understanding regular expressions themselves but I can't figure out which chunk of URL does mod_rewrite pick to do the regex.
If my question isn't clear enough let me also put it this way: which exact place of the above URL is matched by the following regex in .htaccess?
^
Yet another question, if I go to
http://my_website.com/my_project/subfolder
will the considered part of the URL will be different or it will always depend on the place where .htaccess is placed?
I figured it out.
To explain the problem and how I got to the answer I'll try to explain it step by step.
Let's assume the following:
.htaccess is placed in a folder my_project in the root path of www.my_website.com. .htaccess consists the following rule:
RewriteRule ^.*$ index.php?matched=$0
To avoid endless loop let's "fire" the rule only if we provide a test parameter in query string, so the complete .htaccess should look like this:
RewriteEngine On
RewriteCond %{QUERY_STRING} test=1
RewriteRule ^.*$ index.php?matched=$0
Now, if everything goes as I thought we should end up in the index.php script placed in my_project folder. To see the whole match let's add the following line to the script:
var_dump($_GET["matched"]);
In the browser we go to http://my_website.com/my_project?test=1 and we expect the output to be:
string(32) "http://my_website.com/my_project"
But it is not! It is instead
string(0) ""
We're almost there. Now let's go to http://my_website.com/my_project/subfolder/?test=1. The output is
string(10) "subfolder/"
That proves one thing - when mod_rewrite starts to compare the URL with regular expressions it doesn't see the PROTOCOL part of the URL as well as the HTTP_HOST part. As my further research reveal, it also ommits every folder above the .htaccess location as well as the query string and hash part of the URL. For the mod_rewrite the URL begins where the .htaccess location begins.
I hope this self-answered question will be helpful for someone in the future.
Enjoy!
Let me give you a practical example
Suppose Your website is www.example.com and it's located in a folder/Directory named 'ex'
You'll place the .htaccess file in your ex folder to make it work for your website www.example.com
Now let's say you want to make this url clean www.example.com/ex/index.php?page=welcome
open your.htaccess file that you have placed in your ex folder and add this following code to it
RewriteEngine On
RewriteRule ^([A-Za-z0-9-+_%*?]+)/?$ index.php?page=$1 [L]
It'll chagle the URL from www.example.com/ex/index.php?page=welcome to www.example.com/ex/welcome
Now let's say you moved your website to a subfolder ex/subfolder OR www.example.com/ex to www.example.com/ex/subfolder
Simply move the .htaccess file with all of your site to that subfolder no need to change the code it'll work the same
([A-Za-z0-9-+_%*?]+) <-- this part with in the brackets is used as regular expression
means you are looking for any Character from A to z and from a to z and any number from 0 to 9 and symbol - , +,_,%,*,? and the + sign after the closing square bracket means more than one .
In short You are asking to for which is ([in here]+) and it's more than one ,if however you remove the + symbol after the bracket it'll return only the first character
I'm trying to understand why this regular expression isn't working in my .htaccess file. I want it so whenever a user goes to the job_wanted.php?jid=ID, they will be taken to job/ID.
What's wrong with this?
RewriteEngine On
RewriteCond %{QUERY_STRING} jid=([0-9]+)
RewriteRule ^job_wanted\.php?$ job/%1? [R]
I want it so when a user clicks on http://localhost/jobwehave.co.za/jobs/ID they are shown the same results as what below would show http://localhost/jobwehave.co.za/jobs?id=ID.
Sorry for the mix up. I still very confused to how this works.
The primary problem is that you can't match the query string as part of RewriteRule. You need to move that part into a RewriteCond statement.
RewriteEngine On
RewriteCond %{QUERY_STRING} jid=([0-9]+)
RewriteRule ^job_wanted\.php$ /job/%1?
Editing to reflect your updated question, which is the opposite of what I've shown here. For the reverse, to convert /job/123 into something your PHP script can consume, you'll want:
RewriteEngine On
RewriteRule ^/job/([0-9]+)$ /path/to/job_wanted.php?jid=$1
But you're probably going to have trouble putting this in an .htaccess file anywhere except the root, and maybe even there. If it works at the root, you'll likely need to strip the leading / from the RewriteRule I show here.
Second edit to reflect your comment: I think what you want is complicated, but this might work:
RewriteEngine On
RewriteRule ^/job/([0-9]+)$ /path/to/job_wanted.php?jid=$1 [L]
RewriteCond %{QUERY_STRING} jid=([0-9]+)
RewriteRule ^job_wanted\.php$ http://host.name/job/%1? [R]
Your fundamental problem is that you want to "fix" existing links, presumably out of your control. In order to change the URL in the browser address bar, you must redirect the browser. There is no other way to do it.
That's what the second cond+rule does: it matches incoming old URLs and redirects to your pretty URL format. This either needs to go in a VirtualHost configuration block or in the .htaccess file in the same directory as your PHP script.
The first rule does the opposite: it converts the pretty URL back into something that Apache can use, but it does so using an internal sub-request that hopefully will not trigger another round of rewriting. If it does, you have an infinite loop. If it works, this will invoke your PHP script with a query string parameter for the job ID and your page will work as it has all along. Note that because this rule assumes a different, probably non-existent file system path, it must go in a VirtualHost block or in the .htaccess file at your site root, i.e. a different location.
Spreading the configuration around different places sounds like a recipe for future problems to me and I don't recommend it. I think you'll be better off to change the links under your control to the pretty versions and not worry about other links.
The ^ anchors the regex at the beginning of the string.
RewriteRule matches the URI beginning with a / (unless it's in some per-directory configuration area).
Either prefix the / or remove the anchor ^ (depending on what you want to achieve)
You haven't captured the job ID in the regex, so you can't reference it in the rewritten URL. Something like this (not tested, caveat emptor, may cause gastric distress, etc.):
RewriteRule ^job/([0-9]+) job_wanted.php?jid=$1
See Start Rewriting for a tutorial on this.
You need to escape the ? and . marks if you want those to be literals.
^job_wanted\.php\?jid=9\?$
But although that explains why your pattern isn't matching, it doesn't address the issue of your URL rewriting. I'm also not sure why you want the ^ and $ are there, since that will prevent it from matching most URLs (e.g. http://www.yoursite.com/job_wanted.php?jid=9 won't work because it doesn't start with job_wanted.php).
I don't know htaccess well, so I can only address the regex portion of your question. In traditional regex syntax, you'd be looking for something like this:
s/job_wanted\.php\?jid=(\d*)/job\/$1/i
Hope that helps.
Did you try to escape special characters (like ?)?
The ? and . characters have a special meaning in regular expressions. You probably just need to escape them.
Also, you need to capture the jid value and use it in the rule.
Try to change your rules to this:
RewriteEngine On
RewriteRule ^job_wanted\.php\?jid=([0-9]+)$ /job/$1
Something like
ReWriteRule ^job\_wanted\.php\?jid\=([0-9-]+)$ /job/$1
should do the trick.
Right now I'm doing something like this:
RewriteRule ^/?logout(/)?$ logout.php
RewriteRule ^/?config(/)?$ config.php
I would much rather have one rules that would do the same thing for each url, so I don't have to keep adding them every time I add a new file.
Also, I like to match things like '/config/new' to 'config_new.php' if that is possible. I am guessing some regexp would let me accomplish this?
Try:
RewriteRule ^/?(\w+)/?$ $1.php
the $1 is the content of the first captured string in brackets. The brackets around the 2nd slash are not needed.
edit: For the other match, try this:
RewriteRule ^/?(\w+)/(\w+)/?$ $1_$2.php
I would do something like this:
RewriteRule ^/?(logout|config|foo)/?$ $1.php
RewriteRule ^/?(logout|config|foo)/(new|edit|delete)$ $1_$2.php
I prefer to explicitly list the url's I want to match, so that I don't have to worry about static content or adding new things later that don't need to be rewritten to php files.
The above is ok if all sub url's are valid for all root url's (book/new, movie/new, user/new), but not so good if you want to have different sub url's depending on root action (logout/new doesn't make much sense). You can handle that either with a more complex regex, or by routing everything to a single php file which will determine what files to include and display based on the url.
Mod rewrite can't do (potentially) boundless replaces like you want to do in the second part of your question. But check out the External Rewriting Engine at the bottom of the Apache URL Rewriting Guide:
External Rewriting Engine
Description:
A FAQ: How can we solve the FOO/BAR/QUUX/etc. problem? There seems no solution by the use of mod_rewrite...
Solution:
Use an external RewriteMap, i.e. a program which acts like a RewriteMap. It is run once on startup of Apache receives the requested URLs on STDIN and has to put the resulting (usually rewritten) URL on STDOUT (same order!).
RewriteEngine on
RewriteMap quux-map prg:/path/to/map.quux.pl
RewriteRule ^/~quux/(.*)$ /~quux/${quux-map:$1}
#!/path/to/perl
# disable buffered I/O which would lead
# to deadloops for the Apache server
$| = 1;
# read URLs one per line from stdin and
# generate substitution URL on stdout
while (<>) {
s|^foo/|bar/|;
print $_;
}
This is a demonstration-only example and just rewrites all URLs /~quux/foo/... to /~quux/bar/.... Actually you can program whatever you like. But notice that while such maps can be used also by an average user, only the system administrator can define it.