如何配置.htaccess强制仅通过HTML链接访问,禁用PHP原链接?
It looks like you've already got the rewrite rule set up to map your clean HTML-style URLs to the underlying PHP script, but now you need to lock things down so only those clean URLs are accessible. Here's how to fix this properly:
Step 1: Redirect Direct PHP Requests to HTML URLs
The key challenge here is that your .htaccess can't directly look up the matching post-name for a given vid (since that's stored in your database/content system). The most reliable way to handle this is to add a redirect directly in your watch.php file, then use .htaccess to block direct access to the PHP script except for internal rewrites.
Add Redirect Logic to watch.php
At the very top of your watch.php file, before any output is sent, add this code to check if the request came directly to PHP (not via the rewrite rule) and redirect to the correct HTML URL:
<?php // Check if this is a direct request to watch.php (not from the rewrite) if (!isset($_SERVER['REDIRECT_STATUS'])) { $vid = $_GET['vid'] ?? ''; if (preg_match('/^[a-zA-Z0-9]{9}$/', $vid)) { // Replace this line with code to fetch the actual post-name for this vid from your database $postName = get_post_name_by_vid($vid); // Example function, implement this in your system if ($postName) { // 301 Permanent Redirect (best for SEO) header("HTTP/1.1 301 Moved Permanently"); header("Location: https://www.example.com/{$postName}_{$vid}.html"); exit(); } } // If no valid vid or post-name found, redirect to homepage or 404 header("HTTP/1.1 301 Moved Permanently"); header("Location: https://www.example.com/"); exit(); } // Rest of your watch.php code below... ?>
Update .htaccess to Block Direct PHP Access
Now, add these rules to your .htaccess to ensure that only internal rewrite requests can reach watch.php, and direct requests are handled by the PHP redirect above:
RewriteEngine On # First, handle the redirect for direct watch.php requests (will trigger PHP redirect) RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/watch\.php\?vid=([a-zA-Z0-9]{9})\s [NC] RewriteRule ^ watch.php?vid=%1 [L] # Your existing rewrite rule (maps HTML to PHP) RewriteRule ^([^/]*)_([a-zA-Z0-9]{9})\.html$ watch.php?vid=$2 [L] # Block direct access to watch.php if not coming from internal rewrite RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule ^watch\.php$ - [R=403,L]
Alternative: Pure .htaccess (If Post-Name Doesn't Matter)
If the post-name part of your URL is just for aesthetics and doesn't affect functionality (your current rewrite rule ignores it anyway), you can use a pure .htaccess solution to redirect to a generic post-name:
RewriteEngine On # Redirect direct watch.php requests to generic HTML URL RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/watch\.php\?vid=([a-zA-Z0-9]{9})\s [NC] RewriteRule ^ video_%1.html [R=301,L] # Your existing rewrite rule RewriteRule ^([^/]*)_([a-zA-Z0-9]{9})\.html$ watch.php?vid=$2 [L] # Block direct access to watch.php RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule ^watch\.php$ - [R=403,L]
Key Notes:
- Use
301redirects because they're permanent and help preserve SEO rankings. - The
REDIRECT_STATUScheck ensures that internal rewrite requests (from the HTML to PHP rule) are allowed, while external direct requests are blocked or redirected. - If you use the PHP-based solution, make sure the
get_post_name_by_vid()function correctly fetches the matching post name from your database or content system.
内容的提问来源于stack exchange,提问作者saykoo

