Optional Parameter in mod_rewrite (pretty url) - php

I am trying to do the following:
Access user.php?lang=$1&id=$2&title=$3
via
en/user/1/tyler (for English language)
and
user/1/tyler (without language parameter)
My rules are:
RewriteRule ^(en)(?:/(user)/([0-9]+)/([a-zA-Z0-9-]*))?/?$ user.php?lang=$1&id=$2&title=$3 [L,QSA]
RewriteRule ^(user)/([0-9]+)/([a-zA-Z0-9-]*)?$ user.php?lang=&id=$1&title=$2 [L,QSA]
It works when I put the language (en) on the front and I can retrieve all the parameters via $_GET but it doesn't work without it.
How could I achieve this?
Thank you

You may try these rules:
Options -MultiViews
RewriteEngine On
RewriteRule ^(en)/user/(\d+)/([\w-]+)/?$ user.php?lang=$1&id=$2&title=$3 [L,NC,QSA]
RewriteRule ^user/(\d+)/([\w-]+)/?$ user.php?lang=&id=$1&title=$1 [L,NC,QSA]
It is important to turn off MultiViews to avoid using content negotiation service in Apache that may override mod_rewrite rules.

Related

Mod_rewrite handling extra get variables (QSA not working)

I have a mod rewrite rule for settings page: (localhost/settings/index.php)
RewriteRule settings/([a-zA-Z0-9_]+)/?$ settings/?path=$1 [QSA,L]
And I am handling menu references within the URL which will be similar to:
http://localhost/settings/xyz/?ref=menu1&abc=2&de=3..
However, with my current rewrite rule, the variable does not get passed along and I didn't get the values of ref,abc..
I read here about QSA flag but that doesn't seem to be working.
What am I doing wrong?
Try turning off MultiViews option:
Options -MultiViews
RewriteEngine On
RewriteRule ^settings/([\w-]+)/?$ settings/?path=$1 [QSA,L,NC]
In place of QSA, you can use this trick to captured query string:
RewriteRule ^settings/([\w-]+)/?$ settings/?path=$1&%{QUERY_STRING} [L,NC]

How to automatically make pretty urls

I have a site that I'm working on, but I'm annoyed that I have to work with ugly URLS. So, I have a URL of http://example.com/user.php?id=54 and another of http://example.com/foobar.php?name=Test.
How could I convert both of them to pretty URLS without adding it to .htaccess for every URL I want to make pretty?
example.com/user.php?id=54 => example.com/user/54
example.com/foobar.php?name=Test => example.com/foobar/Test
I have this in my .htaccess file:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^([^/]+)/?$ $1.php [L]
RewriteRule ^$1/$3/? /$1.php?$2=$3 [NC]
Thanks,
Lucy
My full .htaccess file:
# include classes on every page
php_value auto_prepend_file Resources/Classes.php
# add custom Directory Indexes
DirectoryIndex index.php Default.php Down.php
# begin routing to pretty URLs
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^/(?!Resources)([0-9a-zA-Z-]+)/([0-9]+) /$1.php?id=$2 [NC]
RewriteRule ^/(?!Resources)([0-9a-zA-Z-]+)/([a-zA-Z-]+) /$1.php?name=$2 [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [L]
Try this
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^user/([0-9]+) /user.php?id=$1 [QSA,L]
RewriteRule ^foobar/([0-9a-zA-Z-]+) /foobar.php?name=$1 [QSA,L]
if you want global rule you can make
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([0-9a-zA-Z-]+)/([0-9a-zA-Z-]+) /$1.php?parameter=$2 [NC]
or more specifically
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([0-9a-zA-Z-]+)/([0-9]+) /$1.php?id=$2 [NC]
RewriteRule ^([0-9a-zA-Z-]+)/([a-zA-Z-]+) /$1.php?name=$2 [NC]
when argument will be a string it will pas name parameter and when argument will be integer there will be id parameter passed.
I may delete this answer in the future as it might be specific to my setup.
I recently discovered, using Apache, that anything after the URL was populating the PATH_INFO environment variable. This means that given your example, example.com/user/54, if user was a script the server could process, anything after it would be populated into PATH_INFO; in this case it would look like /54. This is a great find because with proper structure, you could make your own router similar to Rails.
I would create some landing page (e.g., index) which is going to be your application router: example.com/index/<model>/<id>/. Inside index would be your routing code. I'll use Perl to demonstrate, since it's better than PHP :) Note that index could be called anything that Apache can process (e.g., router.php, index.pl, application.rb); though, removing the extension adds to the beauty of the URL.
index:
#!/usr/bin/perl
use 5.012;
# Retrieve what you're looking for; obviously not production-ready
my ($model,$id) = $ENV{PATH_INFO} =~ m{^/([^/]+?)/([^/]+)};
# route the request
given($model){
when('user'){ callUser($id); } # callUser defined elsewhere, perhaps another script
when('foobar'){ callFoobar($id); } # callFoobar defined elsewher, perhaps another script
default { makePageDefault(); }
}
http://example.com/index/user/1: passes 1 to callUser()
http://example.com/index/foobar/5: passes 5 to callFoodbar()
http://example.com/index/user: calls makePageDefault() because regex was not smart enough to handle anything without an ID
http://example.com/index/diffmodel/1: also calls makePageDefault(), since we don't handle diffmodel didn't exist
The script above is not production ready because it doesn't perform any sanitation and doesn't handle all the use cases you will need. My guess is you want something similar to Rails (e.g., example.com/movie/1/edit). While Apache is designed to handle the routing for you, there is some convenience in being able to manage this close to where your application code lives.
I have not implemented this method, so I'm curious to hear if this is something used and if there's any reason not to trust it.

.htaccess with multiple rules

I want to create an htaccess file with the following rules:
I want to redirect:
http://computingessentials.tk/episodes/6
To:
http://computingessentials.tk/episodes.php?id=6
Same applies with the remaining episode.php ids
Next, I want to redirect:
http://computingessentials.tk/episode.php?id=56
To:
http://computingessentials.tk/episode/56
Same applies with the remaining episode.php ids
And last but not the least, I want to remove all the .php extensions of the files.
Since I am farlynew to htaccess i don't really know how to get all of these in an htaccess.
Help would be very much appreciated.
Make sure your mod rewrite of apache is on and put these rules in .htaccess
RewriteEngine on
RewriteRule ^episodes/([0-9]+)$ episodes.php?id=$1 [L]
You can use these 2 rules in your root .htaccess:
Options +FollowSymLinks -MultiViews
RewriteEngine on
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+episodes\.php\?id=([^\s&]+) [NC]
RewriteRule ^ /episodes/%1? [R=301,L]
# internal forward from pretty URL to actual one
RewriteRule ^episodes/([^/.]+)/?$ /episodes.php?id=$1 [L,QSA,NC]

How do urls without get parameters work

Hi i have come across some urls of the type "http://localhost/jsfweb/cat/query/" where query is a string that will return some results from a mysql database. I am familiar with urls of the type "http://localhost/jsfweb/cat.php?query=query" how can i use those urls with php?
You can do this by rewriting url in htaccess file by this :
RewriteRule ^cat/(.*)$ cat.php?query=$1
Use modrewrite
You do something like this:
Inside a file named '.htaccess'
Options +FollowSymlinks
Options -MultiViews
RewriteEngine on
RewriteBase /php/eclipse/ShiftPlus2/
#forbidden area
#RewriteCond %{THE_REQUEST} index\.php
#RewriteRule ^index\.php$ http://localhost/php/eclipse/ShiftPlus2/? [R=301]
#unique case
RewriteRule ^email$ email.html [L]
#general case
RewriteRule ^([a-zA-Z_]*)/?$ index.php?query=$1 [L]
RewriteRule ^([a-zA-Z_]+)/([a-z]+)/?$ index.php?query=$1&action=$2 [L]
RewriteRule ^([a-zA-Z_]+)/(-?\d+)/?$ index.php?query=$1&id=$2 [L]
RewriteRule ^([a-zA-Z_]+)/([a-z]+)/(-?\d+)/?$ index.php?query=$1&action=$2$id=$3 [L]
RewriteRule ^([a-zA-Z_]+)/(\w+)/?$ index.php?query=$1&special=$2 [L]
#RewriteRule ^index.php$ login [R]
Where on the left side, there is a Rewrite rule with a regular expression and on the right, this is the real link like you know.
Take a look at Apache's mod_rewrite. For most of the websites it is done through that module. If you don't want to get your hands dirty with it, you can employ some sort of MVC framework that incorporates it.
Apache mod_rewrite is what you want. This is an excellent read for beginners:
10 Mod Rewrite Rules You Should Know
CodeIgniter (MVC framework) works by accepting a single entry point to the application, then routing according to what follows. So say you declare index.php as the default document, then /index.php/controller/view is the same as /controller/view. The parameters controller and view are used to instantiate and run the appropriate classes.

Create a Catch-All Handler in PHP?

I want to have a PHP file catch and manage what's going to happen when users visit:
http://profiles.mywebsite.com/sometext
sometext is varying.
E.g. It can be someuser it can be john, etc. then I want a PHP file to handle requests from that structure.
My main goal is to have that certain PHP file to redirect my site users to their corresponding profiles but their profiles are different from that URL structure. I'm aiming for giving my users a sort of easy-to-remember profile URLs.
Thanks to those who'd answer!
Either in Apache configuration files [VirtualHost or Directory directives], or in .htaccess file put following line:
Options -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L,NC,QSA]
</IfModule>
It will silently redirect all incoming requests that do not correspond to valid filename or directory (RewriteCond's in the code above make sure of that), to index.php file. Additionally, as you see, MultiViews option also needs to be disabled for redirection to work - it generally conflicts with these two RewriteCond's I put there.
Inside index.php you can access the REQUEST_URI data via $_SERVER['REQUEST_URI'] variable. You shouldn't pass any URIs via GET, as it may pollute your Query-String data in an undesired way, since [QSA] parameter in our RewriteRule is active.
You should use a rewrite rule..
In apache (.htaccess), something like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php?url=$1 [QSA,L]
</IfModule>
Then in your index.php you can read $_GET['url'] in your php code.
You can use a .htaccess file (http://httpd.apache.org/docs/1.3/howto/htaccess.html) to rewrite your url to something like profiles.websites.com/index.php?page=sometext . Then you can do what you want with sometext in index.php.
An obvious way to do this would be via the 404 errorDocument - saves all that messing about with mod_rewrite.
If you have not heard about MVC, its time you hear it, start with CodeIgniter, its simplest and is quite fast, use default controller and you can have URLs like
domain.com/usernam/profiledomain.com/usernam/profile/editdomain.com/usernam/inboxdomain.com/usernam/inbox/read/messageid Or use .htaccess wisely

Categories