?
Solved

Mod_Rewrite on Product Substitutions

Posted on 2011-05-12
28
Medium Priority
?
338 Views
Last Modified: 2012-08-14
I have  to disable item numbers in the shopping cart and I need to have a way to handle these substitutions with mod_rewrite.  I have figured out how to do it one item at a time.  However, I need a more effecient means because there are lots of substitutions that need to take place.

Here is what I have now

RewriteCond %{REQUEST_URI} ^/?product\.php$ [NC]
RewriteCond %{QUERY_STRING} ^productid=275$ [NC]
RewriteRule ^.+$ /product.php?productid=855? [NC,R=301,L]

The syntax is http://www.domain.com/product.php?productid=275 the above rule changes the 275 to 855 and works great.  I just need many more substitutions and wanted to know if there is a cleaner way to accomplish this?

A PHP solution would be welcome too.

Thanks,

Randal
0
Comment
Question by:sharingsunshine
  • 14
  • 6
  • 4
  • +1
26 Comments
 
LVL 12

Expert Comment

by:mwochnick
ID: 35748130
any reason you can't do this in the product.php code? - it could have the mapping for all you products instead of trying to do it with a rule for every product

0
 

Author Comment

by:sharingsunshine
ID: 35748706
I am not a PHP programmer so that wasn't a consideration.  I would prefer mod_rewrite because I can manage that more effectively.
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35749103
Is it safe to assume that the products will not be remapped to the same target product id? In other words, if you have:

     http://www.domain.com/product.php?productid=275
     http://www.domain.com/product.php?productid=123
     http://www.domain.com/product.php?productid=456

then these will NOT become:

     http://www.domain.com/product.php?productid=855
     http://www.domain.com/product.php?productid=855
     http://www.domain.com/product.php?productid=855
0
Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

 

Author Comment

by:sharingsunshine
ID: 35749332
yes, that is a safe assumption.  they will each a unique target productid
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 35749579
Unfortunately then, I don't see how you can get around it (perhaps someone else can speak otherwise). In my estimation, the mapping is going to have to occur somewhere. If you are concerned about keystrokes, then I would say find a good text editor that you can copy/paste the entire rule block several times, and then perform the appropriate ID replacements. If you have sequential IDs, then some text editors can simplify that replacement. For instance, in TextPad, you can search for some string, and for each match, you can provide a sequential number (via a special replacement pattern).
0
 

Author Comment

by:sharingsunshine
ID: 35749772
no the biggest problem is the unwieldiness of a large cumbersome .htaccess with all the same rules coming in and only the productid's being different.

0
 
LVL 12

Expert Comment

by:mwochnick
ID: 35749930
maybe it would be simpler to use a simple redirect rule in .htaccess instead of mod_rewrite -
and just do it all of your products - you do need to maintain the mapping somewhere
redirect 301      /product.php?productid=275      /product.php?productid=855
0
 

Author Comment

by:sharingsunshine
ID: 35750174
that would be easy enough but using this string

redirect 301 /product.php?productid=275 /product.php?productid=855

it doesn't work.  Do I need something else?
0
 
LVL 12

Expert Comment

by:mwochnick
ID: 35750227
sorry my bad - that was for static pages - without parameters - sorry - what you have initially is what you have to do
0
 

Author Comment

by:sharingsunshine
ID: 35750318
how about giving me the php code and I'll see what the programmer can do with it.  Then we can mark this solved.
0
 

Author Comment

by:sharingsunshine
ID: 35761661
Hi Mwochnick,  I was just referring to what you said before:

any reason you can't do this in the product.php code? - it could have the mapping for all you products instead of trying to do it with a rule for every product

If I were to do it this way what would you suggest?
0
 
LVL 12

Expert Comment

by:mwochnick
ID: 35772100
sharingsundhine, I don't have a quick example for you but I know it can be done.  If you close this question and post another one under php you will get a quicker response than I will be able to give you.  I had started working on an example but then work swamped me. sorry
0
 
LVL 51

Expert Comment

by:Steve Bink
ID: 35791827
You can try RewriteMap, but that is still going to be cumbersome.

I agree with mwochnick - this is easier in PHP.  Create an array for the replacements, and check it at the beginning of the page.  If a replacement is available, use it, otherwise continue with the information provided.  For example:

$replacepid=array('275'=>'855','123'=>'456');
$productid=$_GET['productid'];
if (array_key_exists($productid,$replaceid)) { $productid=$replaceid[$productid]; }

Open in new window

0
 

Author Comment

by:sharingsunshine
ID: 35818299
Sorry it has taken so long to get back to you but we were swamped on Friday and not open on the weekend.

I am not an accomplished PHP programmer but it looks to me like  I need to use your code before this section is executed.

# Put all product info into $product array
#
$product_info = func_select_product($productid, @$user_account['membershipid']);
$is_product_cat = func_query_first_cell("SELECT productid FROM $sql_tbl[products_categories] WHERE productid='$productid' AND categoryid='$cat' LIMIT 1");
if (intval($cat) == 0 || empty($is_product_cat)) {
	$cat = $product_info["categoryid"];
}

Open in new window


This is what I came up with after looking at your example.

switch ($product_info["productid"]){
case "275":
$product_info["productid"] == 855;
break;
case "483":
$product_info["productid"] == 793;
break;
}

Open in new window


can you show me how using the array code to do the same more efficiently?
0
 

Author Comment

by:sharingsunshine
ID: 35818358
the switch isn't working after all.  I still had the rewrite rules in place.
0
 
LVL 12

Expert Comment

by:mwochnick
ID: 35818489
you need to put a conditional redirect at the very beginning of the page - you will need to combine your logic with this redirect

here's an article on doing redirects in php
http://php.about.com/od/learnphp/ht/phpredirection.htm
0
 

Author Comment

by:sharingsunshine
ID: 35818839
I looked at the page you suggested and altered the code in this manner:

switch ($product_info["productid"]){
case 275:
header( '/product.php?productid=855' ) ;
break;
case 483:
header( 'http://www.nnnnn.com/product.php?productid=794' ) ;
break;
case 80:
header( '/product.php?productid=784' ) ;
break;
}

but it doesn't work.  I even tried it with the complete url and it still didn't work.
0
 
LVL 12

Expert Comment

by:mwochnick
ID: 35823782
the php code above has to be before the page outputs anything so if there is any html tag before this code it won't work
0
 

Author Comment

by:sharingsunshine
ID: 35824368
I did a check and there is nothing above it or in the entire set of code using and html tag.
0
 

Author Comment

by:sharingsunshine
ID: 35824373
I need this answer so I am raising the points.
0
 
LVL 51

Expert Comment

by:Steve Bink
ID: 35828207
>>> I did a check and there is nothing above it or in the entire set of code using and html tag.

It does not need to be an HTML tag.  It can be anything outside of the PHP parser tags.  For example, a single space or a newline at the end of an include file can cause this issue.  This would be apparent if you if examine your PHP error log.  You will see a warning or error referencing "headers already sent".

You only need a redirect or rewrite if you want the client's browser URL to change.  If you do want the URL to change in the client's address bar, you should try to use RewriteMap.  The only other requirement is that you can edit the main server conf files.  

If you do not need the URL to change, or if you do not have access to the conf files for RewriteMap, you can still use the array method.  I would alter the $productid variable, and let that change cascade down into the $product_info array, instead of altering the array directly.  Again, the method is pretty simple:

<? 
// at some point prior to this line, you have $productid populated with the product id requested

// the array $replaceid should be formatted where the key is the old product id, and the value is the replacement id
$replaceid=array(
      '275'=>'855',  // change $productid from 275 to 855
      '123'=>'456'   // change $productid from 123 to 456
);
// if the current $productid exists as a key in the $replaceid array, set $productid equal to the value associated with that key
if (array_key_exists($productid,$replaceid)) { $productid=$replaceid[$productid]; }

// the rest of your code goes here
# Put all product info into $product array
#
$product_info = func_select_product($productid, @$user_account['membershipid']);

// ... etc ...
?>

Open in new window

0
 
LVL 51

Accepted Solution

by:
Steve Bink earned 2000 total points
ID: 35828221
P.S.  In the event you want to redirect if the product is changed, modify line 10 to read as shown below:

if (array_key_exists($productid,$replaceid)) { header("location: /product.php?productid=".$replaceid[$productid]); }

Open in new window

0
 

Author Comment

by:sharingsunshine
ID: 35835678
the first code works but this line doesn't

if (array_key_exists($productid,$replaceid)) { header("location: /product.php?productid=".$replaceid[$productid]); }

this is what I really need to have it change the url too.

Thanks,
0
 
LVL 51

Expert Comment

by:Steve Bink
ID: 35835755
Explain how it does not work.  What do you see in the PHP error log?
0
 

Author Closing Comment

by:sharingsunshine
ID: 35843284
thanks for sticking with it
0
 

Author Comment

by:sharingsunshine
ID: 35843292
I had to get a php error log set up.  Afterwards, there were no  php errors so found out that your routine where it is placed works only with enabled products.  The product I was testing was disabled.  Once I turned it on the routine worked.

Thanks,

Randal
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

These days socially coordinated efforts have turned into a critical requirement for enterprises.
We are witnesses that everyone is saying that our children shouldn't "play" with a technology because it is dangerous. This article is going to prove that they are wrong.
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…
This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.
Suggested Courses
Course of the Month14 days, 18 hours left to enroll

839 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question