I keep getting a 500 internal server error when trying to rewrite these one specific URLs/files (item.php & purchase.php), the rest works.
I have tried many ways to fix this but nothing seemed to work, which is weird because all other URLs do work, but these 2 just seem to not want to work for some reason.
.htaccess file
Options -Indexes
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php
ErrorDocument 500 "500"
ErrorDocument 404 "404"
ErrorDocument 403 "403"
RewriteRule ^users/([^/]*)$ /user/profile.php?username=$1
RewriteRule ^users/([^/]*)/inventory$ /user/GetUserInventory.php?username=$1
RewriteRule ^market/item/([^/]*)$ /market/item.php?id=$1
RewriteRule ^market/item/([^/]*)/purchase$ /market/purchase.php?id=$1
RewriteRule ^community/([^/]*)$ /communities/view.php?id=$1
RewriteRule ^community/([^/]*)/join$ /communities/join.php?id=$1
RewriteRule ^community/([^/]*)/manage$ /communities/manage.php?id=$1
RewriteRule ^game/([^/]*)$ /games/view.php?id=$1
item.php
<?php
include_once('../private/header.php');
$item = $handler->query("SELECT * FROM items WHERE id=" . $_GET['id']);
$gB = $item->fetch(PDO::FETCH_OBJ);
echo '
<div class="col s12 m9 l8">
<div class="container" style="width:100%;">
<div class="content-box" style="border-radius:0;">
<div class="left-align">
</div>
<div class="row">
<div class="col s12 m6 l3 center-align">
<img src="'.$cdnServer.'/items/thumbnails/'.$gB->image.'.png" class="responsive-img">
</div>
<div class="col s12 m6 l6">
<div style="padding-left:25px;overflow:hidden;">
<div style="font-size:26px;font-weight:300;">'.$gB->name.'
<b style="text-transform:uppercase;font-size:12px;">'.$gB->type.'</b>
</div>
<div style="color:#777;font-size:14px;">'.$gB->description.'</div>
</div>
</div>
<div class="col s12 m3 l3 center-align" style="padding-top:15px;">
<center>
';
if ($gB->onsale == 1){
echo '<a href="'.$serverUrl.'/market/item/'.$gB->id.'/purchase" class="modal-trigger waves-effect waves-light btn green">Purchase</a>';
} else {
echo '<a class="modal-trigger waves-effect waves-light btn grey darken-2">Offsale</a>';
}
echo '
</center>
<div style="height:15px;"></div>
<center><b style="text-transform:uppercase">Creator</b></center>
<center><a href="'.$serverUrl.'/users/'.$gB->creator.'" style="padding-top:12px;font-size:16px;display:inline-block;">'.$gB->creator.'</a></center>
';
if($gB->collectable == 'true'){
if($gB->amount == 0)
echo '
<center><span style="color:red">Sold Out</span></center>
';
}else{
echo '
<center><span style="color:red">'.$gB->amount.' Remaining</span></center>
';
}
echo '
<div style="height:25px;"></div>
</div>
</div>
<div style="padding-top:25px;">
<div class="row" style="margin-bottom:0;">
<div class="col s12 m12 l3 center-align">
<div style="font-size:20px;">'.$gB->created.'</div>
<div style="color:#999;font-size:14px;">Time Created</div>
</div>
<div class="col s12 m12 l3 center-align">
<div style="font-size:20px;">'.$gB->created.'</div>
<div style="color:#999;font-size:14px;">Last Updated</div>
</div>
<div class="col s12 m12 l3 center-align">
<div style="font-size:20px;">???</div>
<div style="color:#999;font-size:14px;">Owners</div>
</div>
</div>
</div>
</div>
';
include_once('../private/footer.php');
purchase.php
<?php
include_once('../private/config.php');
if ($user){
$money=$myu->CurrencyCoins;
$id=$_GET['id'];
$item = $handler->query("SELECT * FROM items WHERE id=" . $id);
$gB = $item->fetch(PDO::FETCH_OBJ);
$amount=$gB->amount;
if ($gB->onsale == 1){
if ($money >= $gB->price){
if ($gB->collectable != "true"){
if ($amount != 0){
$new = ($money - $gB->price);
$handler->query("UPDATE `users` SET `CurrencyCoins`='".$new."' WHERE `id`='".$myu->id."'");
$handler->query("INSERT INTO inventory (item,user) VALUES (".$id.",".$myu->id.")");
}
} else {
if ($amount >= 1){
$amount1=($amount - 1);
$new = ($money - $gB->price);
$handler->query("UPDATE `users` SET `CurrencyCoins`='".$new."' WHERE `id`='".$myu->id."'");
$handler->query("UPDATE `items` SET `amount`='".$amount1."' WHERE `id`='".$gB->id."'");
$handler->query("INSERT INTO inventory (item,user) VALUES (".$id.",".$myu->id.")");
} else {
echo '<center><h2>Item is sold out!</h2></center>';
}
}
}
} else {
echo '<center><h2>Item not on sale!</h2></center>';
}
}
echo '<head><meta http-equiv="refresh" content="1; url='.$serverUrl.'/account/character"></head>';
Advertisement
Answer
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^(.*)$ $1.php
These directives should be at the end of your .htaccess file, after the other rewrites. They are also incorrect – although by placing them at the end of the file it will avoid the immediate issue, but could still cause problems with other URLs.
In its current state, when you request example.com/market/item/1 (where it would seem, /market is a physical directory, and /item.php is a file in that directory) then…
In brief… it results in an endless rewrite loop:
/market/item/1.php /market/item/1.php.php /market/item/1.php.php.php /market/item/1.php.php.php.php etc.
Which breaks (after 10 iterations) with a 500 response being sent to the browser.
A very similar process happens when requesting /market/item/1/purchase:
/market/item/1/purchase.php /market/item/1/purchase.php.php /market/item/1/purchase.php.php.php /market/item/1/purchase.php.php.php.php etc.
In detail…
REQUEST_FILENAMEis/market/item(ignoring the directory-prefix) andPATH_INFOis/1(important for later)./market/itemis not a directory (1st condition), but/market/item.phpis a file (2nd condition) – so both conditions are successfully met.The
RewriteRuledirective then rewrites/market/item/1to/market/item/1.php(clearly incorrect and not the intention). Since there is noLflag on this rule, processing continues… for the sake of the remaining rules, thePATH_INFO(from the initial request,/1) is appended to the resulting URL to become/market/item/1.php/1(theDPIflag – discard path info – was created to prevent this specific behaviour)./market/item/1.php/1does not match any further rules in the current pass, so the rewrite engine starts over at the top with/market/item/1.php.REQUEST_FILENAMEis again/market/itemandPATH_INFOis now/1.php./market/itemis not a directory (1st condition), but/market/item.phpis a file (2nd condition) – so both conditions are successfully met a second time.The
RewriteRuledirective then rewrites/market/item/1.phpto/market/item/1.php.php. Since there is noLflag on this rule, processing continues… for the sake of the remaining rules, thePATH_INFO(from the request,/1.phpthis time) is appended to the resulting URL to become/market/item/1.php.php/1.php./market/item/1.php.php/1.phpdoes not match any further rules in the current pass, so the rewrite engine starts over at the top with/market/item/1.php.php.GOTO #4 (with updated URL-path) etc. etc. etc. rewrite loop, 500 error.
And a very similar process happens when requesting /market/item/1/purchase. The REQUEST_FILENAME is the same /market/item (so it again checks that /market/item.php exists, not purchase.php), except that the PATH_INFO is /1/purchase (not /1). And the initial URL-path that the .php extension is appended to is naturaly /market/item/1/purchase (not /market/item/1).
Fix
If you’ve followed that “confusing muddle”, you’ll see that the condition that checks for the existence of the “path/to/file” + “.php” is not necessarily the same as the rule that actually rewrites the request to “URL-path” + “.php”. (“path/to/file” is not the same as the “URL-path”). To fix this, it should be written as:
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]
No real need for the directory check here, since if it was a directory, the file check that follows must fail (unless you have directory names that end in .php). The %{DOCUMENT_ROOT}/$1.php check is now effectively “the same” as $1.php (the file being rewritten to).
The literal dot does not need to be backslash escaped in the RewriteCond TestString – this is an “ordinary” string, not a regex.
Don’t forget the L flag(s). And this rule block should now go at the end of the .htaccess file.
Summary
Options -Indexes
RewriteEngine on
ErrorDocument 500 "500"
ErrorDocument 404 "404"
ErrorDocument 403 "403"
RewriteRule ^users/([^/]*)$ /user/profile.php?username=$1 [L]
RewriteRule ^users/([^/]*)/inventory$ /user/GetUserInventory.php?username=$1 [L]
RewriteRule ^market/item/([^/]*)$ /market/item.php?id=$1 [L]
RewriteRule ^market/item/([^/]*)/purchase$ /market/purchase.php?id=$1 [L]
RewriteRule ^community/([^/]*)$ /communities/view.php?id=$1 [L]
RewriteRule ^community/([^/]*)/join$ /communities/join.php?id=$1 [L]
RewriteRule ^community/([^/]*)/manage$ /communities/manage.php?id=$1 [L]
RewriteRule ^game/([^/]*)$ /games/view.php?id=$1 [L]
# Append .php on remaining requests
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule (.*) $1.php [L]