2

CodeIgniter を使用して、ユーザーがアカウントの登録を許可され、選択した URL (URL スラッグ) が割り当てられるアプリを作成しています (例: domain.com/user-name)。CodeIgniter には、正規表現 ( link )を利用できる URL ルーティング機能があります。

ユーザーは、英数字、ダッシュ (-)、アンダースコア (_) を含む URL のみを登録できます。これは、URL スラッグの有効性を検証するために使用している正規表現です。^[A-Za-z0-9][A-Za-z0-9_-]{2,254}$

URL ルーティング機能を使用して、いくつかの URL を自分のサイトの機能 (例: /home -> /pages/index/activity -> /user/activity) にルーティングしているため、これらの特定の URL は明らかにユーザーが登録できません。

私は正規表現の経験がほとんどありませんが、次のいずれかを除いて、英数字/ダッシュ/アンダースコアを含む任意の URL スラッグに一致する式を記述しようとしました:

  1. デフォルトコントローラー
  2. 404_オーバーライド
  3. アクティビティ

その特定の基準で単語を一致させるために使用しているコードは次のとおりです。

$route['(?!default_controller|404_override|home|activity)[A-Za-z0-9][A-Za-z0-9_-]{2,254}'] = 'view/slug/$1';

しかし、正しくルーティングされていません。誰か助けてくれませんか?(補足質問: URL と一致させようとするときに正規表現に^orが必要ですか?)$

4

3 に答える 3

8

よし、これを選別しよう。

CodeIgniter の予約済みルートを無視します。

ルートのdefault_controller404_overrideの部分は不要です。ルートは要求された URI と比較され、一致するかどうかが確認されます。これらの 2 つの項目は、CodeIgniter 用に特別に予約されたルートであるため、URI に含まれる可能性はほとんどありません。だから、それらのことは忘れましょう。

$route['(?!home|activity)[A-Za-z0-9][A-Za-z0-9_-]{2,254}'] = 'view/slug/$1';

すべてをキャプチャ!

正規表現では、括弧を使用してグループが作成されます()。このグループは、後方参照を使用して取得できます。この場合、$1, $2, etc.ルートの 2 番目の部分にあります。除外しようとしていた最初のアイテム セットの周りにグループしかなかったため、ワイルド カード全体を適切にキャプチャできませんでした。あなたはすでにこれを自分で見つけて、アイテム全体にグループを追加しました (良い!)。

$route['((?!home|activity)[A-Za-z0-9][A-Za-z0-9_-]{2,254})'] = 'view/slug/$1';

先のことを考える?!

その件に関して、最初のグループは、最初home|activityに を使用しているため、実際には伝統的なグループではありません?!。これは否定先読みと呼ばれ、複雑な正規表現機能です。そして、それは間違って使用されています:

他の何かが続かないものと一致させたい場合は、否定先読みが不可欠です。

これにはもっと多くのことができますが、基本的にはそもそもそれを本当に望んでいないか、必要としていないので、必要に応じて探索させてください.

生活を楽にするために、ルート内のホーム、アクティビティ、およびその他の既存のコントローラーを分離することをお勧めします。CodeIgniter はルートのリストを上から下に調べ、何かが一致するとチェックを停止します。そのため、ワイルド カードの前に既存のコントローラーを指定すると、それらが一致し、ワイルド カードの正規表現が大幅に簡素化されます。

$route['home'] = 'pages';
$route['activity'] = 'user/activity';
$route['([A-Za-z0-9][A-Za-z0-9_-]{2,254})'] = 'view/slug/$1';

最も具体的なものから順にルートをリストすることを忘れないでください。ワイルド カード マッチは、完全一致 (ホームやアクティビティなど) よりも具体的ではないため、後で指定する必要があります (以下を参照)。

さて、それはすべての複雑なものです。もう少し参考までに。

括弧の間のダッシュ-には特別な意味があることに注意してください。[]リテラルダッシュに一致させたい場合は、それらをエスケープする必要があります。

$route['([A-Za-z0-9][A-Za-z0-9_\-]{2,254})'] = 'view/slug/$1';

文字の繰り返しの最小/最大{2,254}は 2 番目の文字セットにのみ適用されるため、ユーザー名は最小で 3 文字、最大で 255 文字にする必要があることに注意してください。まだ気付いていない場合は参考までに。

この問題に対するあなた自身の答えを見ましたが、それはただ醜いです。ごめん。およびシンボルは^$先読み全体で不適切に使用されています (そもそも存在しないはずです)。テストしているいくつかのユースケースでは「機能する」かもしれませんが、将来的には問題や頭痛の種になるだけです.

これで、正規表現と、ルーティング プロセスで正規表現がどのように照合されるかについて理解が深まったと思います。

いいえ、あなたの質問に答えるには、正規表現の最初と最後に^and$を使用しないでください - CodeIgniter がそれを追加します。


404を使え、ルーク...

この時点で、ルートは改善され、機能するはずです。404_overrideただし、ワイルドカードを処理するために定義されたコントローラー/メソッドを使用することを検討することをお勧めします。これの主な利点は、ワイルドカードを指示したり、ワイルドカードが既存のコントローラーをだましてしまうのを防ぐために、ルートをまったく必要としないことです。あなただけが必要です:

$route['404_override'] = 'view/slug';

次に、View::slug() メソッドは URI をチェックし、それが有効なパターンかどうかを確認し、それがユーザーとして存在するかどうかをチェックします (今のスラッグ メソッドと同じで間違いありません)。もしそうなら、あなたは行ってもいいです。そうでない場合は、404 エラーをスローします。

優雅に見えないかもしれませんが、うまく機能します。それがあなたにとってより良いと思われる場合は、試してみてください。

于 2013-04-02T20:26:57.140 に答える
0

自分の質問に答える

うまくいく別の表現を思いついたようです:

$route['(^(?!default_controller$|404_override$|home$|activity$)[A-Za-z0-9][A-Za-z0-9_-]{2,254}$)'] = 'view/slug/$1';

$1式全体を括弧で囲み (これは CodeIgniterが右側で照合するものだと思います)、行頭識別子:^と一連の行末識別子: を追加しました。$

これが、後でこの問題に遭遇する可能性のある人に役立つことを願っています.

于 2013-04-02T18:49:37.800 に答える
0

特に codeIgniter には詳しくありませんが、ほとんどのフレームワーク ルーティングは優先順位に基づいて動作します。つまり、デフォルトのコントローラー、404 などのルートを最初に定義する必要があります。次に、スラッグのみに一致するように正規表現を単純化できます。

于 2013-04-02T18:39:12.567 に答える