繁体   English   中英

重写 2 个特定 URL 时出现 500 内部服务器错误

[英]Getting a 500 Internal Server Error when rewriting 2 specific URLs

在尝试重写这些特定的 URL/文件(item.php 和 purchase.php)时,我不断收到 500 内部服务器错误,其余的都有效。

我尝试了很多方法来解决这个问题,但似乎没有任何效果,这很奇怪,因为所有其他 URL 都可以工作,但是这 2 个似乎出于某种原因不想工作。

.htaccess 文件

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

项目.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');

购买.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>';
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}\\.php -f RewriteRule ^(.*)$ $1.php

这些指令应该在你的.htaccess文件的末尾,其他重写之后。 它们也是不正确的 - 尽管将它们放在文件末尾可以避免直接问题,但仍然可能导致其他 URL 出现问题。

在当前状态下,当您请求example.com/market/item/1 (看起来, /market是一个物理目录,而/item.php是该目录中的一个文件)然后...

简而言之......它会导致无限的重写循环:

/market/item/1.php
/market/item/1.php.php
/market/item/1.php.php.php
/market/item/1.php.php.php.php
etc.

这会中断(在 10 次迭代后),并向浏览器发送 500 响应。

请求/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.

详细...

  1. REQUEST_FILENAME/market/item (忽略目录前缀), PATH_INFO/1 (以后很重要)。 /market/item不是目录(第一个条件),但/market/item.php是一个文件(第二个条件) - 所以两个条件都成功满足。

  2. RewriteRule指令然后将/market/item/1重写为/market/item/1.php (显然不正确,而不是意图)。 由于此规则上没有L标志,处理继续......为了其余规则, PATH_INFO (来自初始请求, /1 )被附加到结果 URL 成为/market/item/1.php/1DPI标志 - 丢弃路径信息 - 是为了防止这种特定行为而创建的)。

  3. /market/item/1.php/1不匹配当前传递中的任何其他规则,因此重写引擎从/market/item/1.php的顶部重新开始。

  4. REQUEST_FILENAME/market/itemPATH_INFO现在是/1.php /market/item不是目录(第一个条件),但/market/item.php是一个文件(第二个条件)-因此第二次成功满足这两个条件。

  5. RewriteRule指令然后重写/market/item/1.php/market/item/1.php.php 由于此规则上没有L标志,处理继续......为了其余规则, PATH_INFO (来自请求,这次是/1.php )被附加到结果 URL 中成为/market/item/1.php.php/1.php

  6. /market/item/1.php.php/1.php不匹配当前传递中的任何其他规则,因此重写引擎从顶部重新开始/market/item/1.php.php

  7. GOTO #4(带有更新的 URL 路径)等等等等。重写循环,500 错误。

请求/market/item/1/purchase时会发生非常相似的过程。 REQUEST_FILENAME/market/item相同(因此它再次检查/market/item.php存在,而不是purchase.php ),除了PATH_INFO/1/purchase (不是/1 )。 .php扩展名附加到的初始 URL 路径自然是/market/item/1/purchase (不是/market/item/1 )。

使固定

如果您遵循了“令人困惑的混乱”,您将看到检查“path/to/file”+“.php”是否存在的条件不一定与实际重写请求的规则相同到“网址路径”+“.php”。 (“path/to/file”与“URL-path”不同)。 为了解决这个问题,它应该写成:

RewriteCond %{DOCUMENT_ROOT}/$1.php -f 
RewriteRule (.*) $1.php [L]

这里不需要进行目录检查,因为如果它是一个目录,那么接下来的文件检查一定会失败(除非您的目录名称以.php )。 %{DOCUMENT_ROOT}/$1.php检查现在实际上与$1.php (被重写的文件)“相同”。

文字点不需要在RewriteCond TestString 中转义反斜杠 - 这是一个“普通”字符串,而不是正则表达式。

不要忘记L标志。 这个规则块现在应该放在.htaccess文件的末尾。

概括

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]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM