0

Stack Overflowsのやり方からインスピレーションを得て、ユーザーページのクリーンURLを掘り下げ始めました。ユーザーは、表示したいユーザーのユーザーIDだけを入力できます。これにより、表示名を含む正しいURLにリダイレクトされます。たとえば、IDが1のアカウントを持っている場合、表示名が。であるとすると、visitingusers/1はにリダイレクトされます。ここから、自分で編集するなどの追加のアクションを実行できるため、ユーザー1を編集します。もにリダイレクトされます。上記の例はすべて完璧な世界で機能しますが、簡単に壊れる可能性があります。 ユーザーは、などの他のユーザーに対してアクションを実行できます。明らかに、あなたは自分自身と友達になりたくないので、何もしません。ただし、次のようなURLを入力するusers/1/JosephDuffyJospehDuffyusers/1/JosephDuffy/editusers/1/username/editusers/1/JosephDuffy/edit
users/2/Player2/befriendusers/1/JospehDuffy/befriendusers/1/1/1/1/JosephDuffy/befriendアクションをとしてbefriend、表示名をとしてJosephDuffy、ユーザーIDをとしてトリガーするよう1/1/1/1です。これがmod_rewriteのしくみだと思いますが、カーブボールを投げているようです。
今のところ、私はintval()ユーザーIDを使用しています。これは機能しているように見えますが、理想的とは言えません。同じ情報を提供する複数のURLがまだ残っており、他の「穴」は見つかりませんが、まだいくつかある可能性があります。問題がどこにあるのかわからないので、.htaccessとPHPスクリプトを投稿します。
.htaccess

RewriteEngine On

# Rewrite /users to provide the script with the GET variables it requires to function properly, whilst having clean URLs
# 3 variables were provided
RewriteRule ^users/([^.]+)/([^.]+)/([^.]+)/$ users.php?userid=$1&displayname=$2&action=$3
RewriteRule ^users/([^.]+)/([^.]+)/([^.]+)$ users.php?userid=$1&displayname=$2&action=$3

# 2 variables were provided
RewriteRule ^users/([^.]+)/([^.]+)/$ users.php?userid=$1&displayname=$2
RewriteRule ^users/([^.]+)/([^.]+)$ users.php?userid=$1&displayname=$2

#1 variable was provided
RewriteRule ^users/([^.]+)/$ users.php?userid=$1
RewriteRule ^users/([^.]+)$ users.php?userid=$1

ある段階で、などを使った方がいいと思いますが[R=301,L]、どこにあるのか、なぜそうなのかわかりません。
users.php(一部の部分は、理解しやすくするために、ほとんど擬似コードに簡略化されています)

if (isset($_GET['userid'])) {
    $profileUserid = intval($_GET['userid']);
} else {
    $profileUserid = 0;
}
if (isset($_GET['displayname'])){
    $profileDisplayName = $_GET['displayname'];
} else {
    $profileDisplayName = '';
}
if (isset($_GET['action'])) {
    $action = $_GET['action'];
} else {
    $action = false;
}
$actualDisplayName = GetDisplayNameFromDBWhereid($profileUserid);
if ($actualDisplayName != $profileDisplayName) {
        header('Location: /users/' . $profileUserid . '/' . $actualDisplayName . '/' . $action);
        exit;
    } else if (substr($_SERVER['REQUEST_URI'], -1) != '/') {
        // There is no trailing slash, so add it
        header('Location: ' . $_SERVER['REQUEST_URI'] . '/');
        exit;
    }
    if ($currentUsersid == $profileUserid) {
        // Player is viewing themselves
        if ($action == 'edit') {
            echo 'Editing your profile';
        } else {
            // User viewing self, but not editing
            echo '<a href="edit">Edit your profile</a><br>';
        }
    } else {
        if ($action) {
            // Interact with the user whos profile is being viewed
        } else {
        }
    }

を使用せずintval($_GET['userid'])に入力すると、別のユーザーがいる場合と同じようにusers/1/1/1/1/JosephDuffy/action実行され、「プロファイルの編集」リンクが表示されますが、は「編集」と等しくないため、アクションは無視されます。 うまくいけば、これはばかげたものです(私はそれが私の不十分に書かれたRewriteRulesのせいであると推測しています)が、それでもなお、読んでくれてありがとう。action1/JosephDuffy/action

4

1 に答える 1

1

なぜそのように機能するのですか?

正規表現は貪欲で、正規表現にできるだけ適合しようとするためusers/1/1/1/1/JosephDuffy/befriend、パターンにうまく適合しますusers/([^.]+)/([^.]+)/([^.]+)。TBH なぜ表記[^.]+と同じに見えるのかわからないのです.+が、それが一番気になりますが・・・


直し方

にのみ適合するように修正したい場合は、users/1/JosephDuffy/befriend正規表現パターンを次のように配置する必要があります

^users/([^/]+)/([^/]+)/([^/]+)$ users.php?userid=$1&displayname=$2&action=$3

そして、すべての残りの書き換えをそれぞれ変更します。そこの表記に注意してください。([^/]+)これは、 が見つかるまでのすべての文字を意味します/


そして、私は何をしますか

前述のように、「あらゆる種類の URL」を受け入れることを検討し、PHP エンドで解析を行います ( を使用preg_split)。したがって、URL の書き換えは非常に簡単です。

RewriteEngine On
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^(.*)$ users.php?url=$1 [QSA,L]

次に、コードで私は

$paramsAndValues = preg_split('#/#',$_GET['url']);

それは最も簡単ですが、もちろん、$_GET['url']存在するかどうかなどすべてを確認します。

于 2012-06-04T13:53:33.607 に答える