如何创建未匹配其他规则的.htaccess规则并在PHP中捕获
Hey Marco, let's get this sorted so invalid URLs keep users on your discography page instead of bouncing them elsewhere. Here's what you need to do:
Step 1: Update Your .htaccess Rules
The key here is to put your catch-all rule LAST—Apache processes RewriteRules from top to bottom, so if you put the catch-all first, it'll override your valid rules. We'll add a rule that catches any invalid discography/ paths that don't match your existing patterns, and pass a flag to PHP so you can handle it.
Here's the updated .htaccess code:
ErrorDocument 404 /notfound.php # Valid discography root RewriteRule ^discography/?$ music/music.php [L,QSA] # Valid country filter RewriteRule ^discography/country/(\d+)(?:/[^/]+)?/?$ music/music.php?country=$1 [L,QSA] # Valid format filter RewriteRule ^discography/format/(\d+)(?:/[^/]+)?/?$ music/music.php?format=$1 [L,QSA] # Valid year filter RewriteRule ^discography/year/([0-9]{4})/?$ music/music.php?year=$1 [L,QSA] # Catch-all for invalid discography paths RewriteRule ^discography/.+$ music/music.php?invalid_request=1 [L,QSA]
- The
^discography/.+$pattern matches any URL starting withdiscography/followed by one or more characters (so it doesn't conflict with your root/discographyrule). - We add
invalid_request=1as a query parameter so PHP can easily detect this case.
Step 2: Adjust Your PHP Logic
Now update your PHP script to handle the invalid request case, keeping users on the page and showing your custom message/options. Here's the modified code:
if (isset($_GET['country']) && is_numeric($_GET['country'])) { echo 'country id'; $get_countryid = (int)$_GET['country']; } elseif (isset($_GET['format']) && is_numeric($_GET['format'])) { echo 'format id'; $get_formatid = (int)$_GET['format']; } elseif (isset($_GET['year']) && is_numeric($_GET['year'])) { echo 'year'; $get_year = (int)$_GET['year']; } elseif (isset($_GET['invalid_request'])) { // Handle invalid URL case: keep user on page, show options echo 'Oops, that URL isn’t valid! Please choose a filter from the options below.'; // Add your navigation/filter options here (like country, format, year selectors) } else { // Default discography page echo 'http://www.example.com/discography'; }
Why Your Earlier Attempt Failed
If you put the catch-all rule before your valid ones, Apache would match it first (since .* matches almost everything) and skip your intended rules. By placing it last, we ensure only URLs that don't fit your valid patterns trigger the catch-all.
内容的提问来源于stack exchange,提问作者Marco

