mod_rewrite query strings returning 404 - php

I have a custom URL like this:
website.com/show/?id=9999&n=page-name
I'm trying to come up with a rewrite rule to convert it to:
website.com/show/9999/page-name/
Note that this is a WordPress site and /show/ is WP page name.
Here's the rules I'm using in .htaccess:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^show/(.*)$ /show/?id=$1 [R=301,NC,QSA]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
This is working; it rewrites website.com/show/?id=9999 to website.com/show/9999/.
Then I modified the rule for the second query string:
RewriteRule ^show/(.*)/(.*)$ /show/?id=$1&n=$2 [R=301,NC,QSA]
But now website.com/show/9999/page-name/ returns a 404 error. It works if I go to: website.com/show/9999/?n=page-name.
What am I doing wrong?
Update
The 404 problem is now solved.
However, now I need to redirect the old query string URL:
website.com/show/?id=9999&n=page-name
to the new SEO friendly URL:
website.com/show/9999/page-name
How do I setup that redirect?

Try this:
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteRule ^show/(\d+)/?([^/]*)/?$ /show/?id=$1&n=$2 [L,NC,QSA]
# Wordpress defaults:
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
## Results
# show/9999 => show/?id=9999&n=
# show/9999/ => show/?id=9999&n=
# show/9999/page-name => show/?id=9999&n=page-name
# show/9999/page-name/ => show/?id=9999&n=page-name
As you see, when page-name is not available, there will be an empty n query string parameter. In your PHP script, instead of checking for the parameter presence using isset(), try using empty().
One last note; The above rules do not redirect the request, it maps the request under the hood, so that the URL stays clean. If you need a redirect, just add a R flag.
404
Even if you remove your custom rewrite rules, you'll get a 404 from WordPress. That's because, as you said, the rewrite target (/show) is a WordPress page and ultimately get mapped to the index.php file. Then, WordPress checks its database to see if it can find a page with that path or throws a 404 if it can't. Obviously, the latter is your case.
Update
Regarding your recent update; To redirect the old URL to the new one, you need some rewrite rules along the lines of:
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} ^id=(\d+)(&n=)?(.*)$
RewriteRule ^show/?$ /show/%1/%3 [R=301,QSD,L]
# Wordpress default rules:
# ...
</IfModule>
## Results
# show?id=9999 => show/9999
# show?id=9999&n=page-name => show/9999/page-name
# show/?id=9999&n=page-name => show/9999/page-name
Don't use [R=301] until you're 100% sure that everything's working fine, as it's aggressively get cached by the browser.

I think I figured it out... almost.
#sepehr is correct that WordPress is checking, not finding the page, and throwing a 404. So I needed to use WordPress' own rewrite engine to define the rewrite rules so it recognizes what I'm doing.
So I added this to my WordPress theme's functions.php file:
add_action( 'init', 'init_custom_rewrite' );
function init_custom_rewrite() {
add_rewrite_rule(
'^show/([^/]*)/([^/]*)/?',
'index.php?page_id=2382&id=$matches[1]&n=$matches[2]',
'top'
);
}
add_filter('query_vars', 'my_query_vars', 10, 1);
function my_query_vars($vars) {
$vars[] = 'id';
$vars[] = 'n';
return $vars;
}
Now the URL website.com/show/9999/page-name works correctly, not throwing a 404.
However, now I need to redirect the old query string URL to this new one. See my updated question.
Update
Here's the rewrite rule to redirect the old query string URLs to the new SEO friendly URLs:
RewriteCond %{QUERY_STRING} ^id=([^/]*)&n=([^/]*)$
RewriteRule ^show/?$ /show\/%1\/%2\/? [R=301,L]

Please check below rule in to your .htaccess.
RewriteRule ^show/(.+)/(.+)$ show/?id=$1&n=$2 [L,QSA]

Related

Removing $id from url with .htaccess

I am using an .htaccess file to redirect "http://www.domain.com/cars/cars.php?cars_item=231" to "http://www.domain.com/cars/231/porsche"
So basically I'm redirecting 'cars.php?cars_item=231' to '$id/$title'
The .htaccess file consists of:
#Start
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
# Redirect cars.php?cars_item=231 to cars/231/
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+cars/cars\.php\?cars_item=([^&\s]+) [NC]
RewriteRule ^ /cars/%1 [R=302,L]
# Internally forward cars/231/ to cars.php?cars_item=231
RewriteRule ^cars/([0-9]+) /cars/cars.php?cars_item=$1 [NC,L,QSA]
#end
Then i'm using the following hrefs:
"http://domain.com/index.php" = echo porsche;
and in "http://www.domain.com/cars/cars.php" i'm using a $_GET['cars_item'];
My question is: How could I remove the $id from the url please? I want to have the following url as a result - "http://www.domain.com/cars/porsche" ... so basically I want to update the .htaccess and redirect "http://www.domain.com/cars/cars.php?cars_item=231" to "http://www.domain.com/cars/porsche"
This is because the $id in the url is creating some problems for indexing especially. Google keeps crawling "http://www.domain.com/cars/$id/" where as the $id is not a folder but is a db row hence I'd like to remove the $id from the url.
I would appreciate your help as always.

Wordpress after migration doesn't work

I had problems with WordPress migration from one server to another, and generally now it works but I have many smaller problems..
Before I use domain oldexample.com and now i use domain newexample.com/something . Generally everything on the page works but changing language isn't work (qTranslate plugin).
I think that I found the reason of this - in admin menu I found in some places situation that href links start from "/" for example: "/wp-admin/..." and in result it change the URL from newexample.com/something/wp-admin to newexample.com/wp-admin. I see this problem in qTranslate settings links and when I want delete some plugins. I get the error message "404 Not Found - nginx/1.4.5" in results...
Did you see this problem before? Maybe I should change something in WordPress core files? .htaccess? Now it looks like this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?newexample\.com\/something$ [NC]
</IfModule>
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
After long time I find the solution! All "href" are generated by using $_SERVER['REQUEST_URI'], and this variable show only the rest part of the path (without /something/. I add to wp-settings.php this part of code: $_SERVER['REQUEST_URI'] = '/something'.$_SERVER['REQUEST_URI']; (on the very beggining) all forms generate good path.

How to mask the URL with htaccess in zend framework 1.10

Hi I Have to create the URL something like "http://www.contract.com/user/profileview/index/MQ==" to "http://www.contract.com/profile/india/MQ==". We have tried the masking with codeignitor and succeeded. But coming to the Zend it is throwing the error "Invalid controller specified (india)".
We have rewrite the htaccess rules to Mask the URL in codeignitor. Same is applied here, but it is not working here. My htaccess code is
#php_value magic_quotes_gpc off
RewriteEngine on
Options -Indexes
Options FollowSymlinks
RewriteEngine On
RewriteBase /
#Admin
RewriteRule ^admin(.*)$ public_mvc/admin.php [L]
#RewriteRule ^profile/(.*)/(.*)/(.*)(/|)$ user/profileview/index/$2 [L,NC]
RewriteRule ^profile/(.*)/(.*)/(.*)(/|)$ user/profileview/index/$2 [L,NC]
#RewriteRule ^profile/(.*)/(.*)/(.*)/?$ user/profileview/index/$2 [L,NC,QSA]
# Also Tried Ones. Start
#RewriteRule ^profile/(.*)/(.*)/(.*)/$ /user/profileview/index/$1 [NC,L]
#RewriteRule ^profile/(.*)/(.*)/(.*)/?$ /user/profileview/index/$2 [NC,L]
#RewriteRule ^profile/(.*)/(.*)/(.*) /user/profileview/index/$2 [NC]
#RewriteRule ^/profile/(.*)/(.*)/(.*)/?$ /user/profileview/index/$2 [QSA]
# Also Tried Ones. End
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ public_mvc/index.php
Rewriterule ^$ /home [r=301,nc]
What is the wrong with this? We have tried so many types options. But all went in vain. You can see all those different tries in the code. Please help me this.
Thanks in advance.
"http://www.contract.com/profile/india/MQ=="
above url can be rewriter in htaccess
method 1;
RewriteRule ^profile/(.*)$ redirectedUrl.php [NC,L]
redirectedUrl.php as page, it should be placed in the root directory, it cant shows an error, regards changing the url in htaccess!!!
method 2;
handling on bootstapper.php for redirect into some controller with another action for using
Zend_Controller_Router_Route_Regex
Thanks for the Support. I have achieved the goal in some other way. We have changed the ZEND routing according to our needs. So we have Auth file(which is called in every request). This file is called in all the requests. So what I did is I checked the URL and if the URL contains the module name as 'Profile' then I have set the Module, Controller and Action name using the "setModuleName", "setControllerName", "setActionName", etc..
$ModuleName = $request->getModuleName();
$ControllderName = $request->getControllerName();
$ActionName = $request->getActionName();
/*
This condition is added to mask the URL. This is added by Ghanta Kiran on 27-Dec-2013. Start
Example : (From) http://www.contractskills.com/profile/india/username/id ==> (To) http://www.contractskills.com/user/profileview/index/id
*/
if($ModuleName == 'profile')
{
$paramId = $request->getParam('id'); // This is to get the User Id from the URL, to fetch the user profile details.
$request->setModuleName('user');
$request->setControllerName('profileview');
$request->setActionName('index');
$request->setParam('id',$paramId);
}
So what it will do is, If the URL Contains the 'Profile' in it, it will set the Module, Controller, Actions explicitly. I have done so many changes to the .htaccess, but ultimately all those efforts went wild.

Can't get mod_rewrite to work

I am trying to get url from:
192.168.0.1/movie-page.php?id=123
to:
192.168.0.1/movie/movie-name
or even (for now):
192.168.0.1/movie/123
I've simplified it by using this url (to get something working):
192.168.0.1/pet_care_info_07_07_2008.php TO 192.168.0.1/pet-care/
my .htaccess file:
RewriteEngine On
RewriteRule ^pet-care/?$ pet_care_info_07_07_2008.php [NC,L]
What am I doing wrong? I've tried many combinations but no luck and my patience is running out...
I am running this on my local NAS which should have mod_rewrite enabled by default. I have tested .htaccess by entering random string in .htaccess file and opening the page, I got 404 error. I assume this means that .htaccess is being used since the page stops functioning if the file is malformed.
If you want to rewrite:
192.168.0.1/movie-page.php?id=123 too
192.168.0.1/movie/movie-name or 192.168.0.1/movie/123
Then you would do something like, but will require you manually add a rewrite for any new route (fancy url) you want, and eventually you may want your script to create routes dynamically or have a single entry point to sanitize:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^movie/([a-zA-Z0-9-]+)$ movie-page.php?id=$1 [L]
So a better method is to route everything through the rewrite:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?route=$1 [L,QSA]
Then handle the route by splitting the $_GET['route'] with explode()
<?php
//192.168.0.1/movie/movie-name
$route = (isset($_GET['route'])?explode('/',$_GET['route']):null);
if(!empty($route)){
//example
$route[0]; //movie
$route[1]; //movie-name
}
?>
You want something like this:
RewriteRule ^movie/([0-9]*)$ /movie-page.php?id=$1 [L,R=301]
That will give the movie ID version with a numeric ID.

Clean URL from custom $_GET variables in wordpress

I'm using wordpress pretty permalinks, my .htaccess file looks like this:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /nafham/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /nafham/index.php [L]
</IfModule>
# END WordPress
I'm using a form that displays the index page with url variables, like this:
http://www.nafham.com/?edu_year_selectionreal=79&semester_selectionreal=15&subject_selectionreal=80
I'd like to have the url to be displayed like this:
http://www.nafham.com/79/15/80
Is it possible to do so? and what's the best way of doing this in order not to make things go wrong with the rewrite conditions wordpress is Already applying?
as you have the rewrite already setup all you need to do is parse the url in your index.php
if (preg_match("#(\d+)/(\d+)/(\d+)#", $_SERVER['REQUEST_URI'], $regs)) {
$edu_year_selection_real = $regs[1]
$semester_selectionreal = $regs[2];
$subject_selectionreal = $regs[3];
}
add smth. like this to .htaccess:
RewriteRule ^/([0-9-]+)/([0-9-]+)/([0-9-]+)$ index.php?var1=$1&var2=($2)&var3=($3) [L]
At you need to set custom rewrite rules in the Wordpress otherwise Wordpress throw you to error page.
Here's example to set custom rewrite rules:
<?php
add_filter('rewrite_rules_array', 'insert_custom_rules');
function insert_custom_rules($rules)
{
$newrules = array();
$newrules['(.+?)/(.+?)/(.+?)/?$'] =
'index.php?edu_year_selectionreal=$matches[1]&semester_selectionreal=$matches[2]&subject_selectionreal=$matches[3]';
return $newrules + $rules;
}
?>
Hope this will help.

Categories