[英]User friendly URLs - mod rewrite and php redirections
到目前為止我已經這樣做了:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?load=$1 [QSA,L]
然后在我的索引頁面(在根目錄中)我正在使用PHP來確定要加載的頁面:
// Swap to variables
$load = $_GET['load'];
// Home page
if (!$load || $load == "") { include('home.php'); exit(); }
// Dashboard
if ($load == "dashboard") { include('dashboard.php'); exit(); }
// About
if ($load == "about") { include('about.php'); exit(); }
// Username
$data_array = array(':username' => $load);
$select_account = $connect->prepare("SELECT * FROM `users` WHERE `username` = :username");
$select_account-> execute($data_array);
$account_amount = $select_account->rowCount();
if ($account_amount > 0) { include('profile.php?name=$load'); exit(); }
// Redirect to 404 if there are no results
include('404.php'); exit();
到目前為止一切正常,但用戶可以將照片上傳到圖庫,我希望他們可以像這樣查看:
www.mysite.com/[username]/gallery/
但是如果你打算將其作為網址輸入,則重寫將[username]/gallery/
作為一個部分,這意味着$load = [username]/gallery
這將給我一個'404'。
可能有一個更好的解決方案來獲得理想的結果,但我對.htaccess和重寫並不太好。 我想補充一點,我也喜歡這個重寫,因為我有一個名為signup
和signin
的子目錄,它們都有子目錄,但是如果我轉到URL:
www.mysite.com/signup
www.mysite.com/signin
它忽略了重寫並轉到目錄而不是通過$load
語句運行它,這是我想要的。
另外,要注意,在注冊帳戶時,任何與字符串(如dashboard
或about
等)匹配的用戶名都不允許他們使用它,這會停止用戶名和$load
if / else語句及其包含被混淆等
編輯
我忘記注意的另一件事是,因為他們可以隨意調用圖庫,它需要搜索以查看該圖庫是否存在,例如:
www.mysite.com/username/my+first+album
它首先需要檢查用戶名是否存在,然后檢查相冊是否存在,然后顯示它是否存在,如果不存在則顯示為404 /重定向到哪里。 所以基本上,兩個參數/查詢都是動態的。 不僅如此,那么該專輯中的單張照片需要同樣的工作,例如:
www.mysite.com/username/my+first+album/my+picture
我希望這是有道理的...
一個簡單的解決方案是:EDIT HTACCESS
RewriteBase /
RewriteCond %{REQUEST_URI} !/signup
RewriteCond %{REQUEST_URI} !/signin
RewriteRule ^([^/]*)/([^/]*)$ index.php?load=gallery&username=$1&gallery=$2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?load=$1 [QSA,L]
現在那個PHP部分(對於index.php):
$load = $_GET['load'];
switch ($load){
default:
include('home.php');
exit();
break;
case 'dashboard':
include('dashboard.php');
exit();
break;
case 'about':
include('about.php');
exit();
break;
case 'gallery':
$username = $_GET['username'];
$gallery = $_GET['gallery'];
//check for the username and gallery
header("Location: your-gallery-location-goes-here");
break;
}
希望它會有所幫助:)
您想要的是所謂的URL路由器,這需要您分析URL並根據內容做出決策。 大多數系統通過讓您提供url模板以及在url匹配時調用的函數來完成此操作。 該函數通常傳遞給模板URL中的任何子匹配。
例如,Django使用正則表達式作為其url路由,並將命名匹配作為參數傳遞給給定的函數(或類)。
如果這對您的需求來說過於復雜,那么您可以使用特定的正則表來解析網址,您的圖庫大小寫將是:
$matches = array();
$re = "/\/([\w\d])+\/([\w\d+%])+\/?/";
preg_match($re, $load, $matches);
$username = $matches[0];
$gallery = $matches[1];
然后你可以使用$username
和$gallery
。
注意
以上假設它將匹配,您需要檢查preg_match
的返回值以確保。 此外,我沒有檢查正則表達式,它可能是錯誤的,或使用不在此語法中的功能。
參考
這是一個簡單的例子:
的.htaccess
RewriteEngine On
RewriteRule ^includes/.*$ index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
首先,您必須拒絕直接訪問.php文件,您可以將它們放在單獨的文件夾中,如'/ includes',並將對該文件夾的任何調用重定向到index.php。 其次,允許直接訪問文件(如圖像或javascripts)。 最后一條規則,將其他任何內容重定向到index.php。
PHP
基本上你必須有一組規則來測試URL和一些控制器來處理結果。
define( 'WEB_ROOT', rtrim( dirname($_SERVER["SCRIPT_NAME"]), '/' ) );
define( 'INCLUDES_ROOT', 'includes/' );
// examples of rewrite rules ( $key = action, $value = regular expression )
$rules = array(
'pages' => "/(?'page'dashboard|about|signin|signup)", // e.g. '/about'
'gallery' => "/(?'username'[\w\-]+)/gallery", // e.g. '/some-user/gallery'
'album' => "/(?'username'[\w\-]+)/(?'album'[\w\-]+)", // e.g. '/some-user/some-album'
'picture' => "/(?'username'[\w\-]+)/(?'album'[\w\-]+)/(?'picture'[\w\-]+)", // e.g. '/some-user/some-album/some-picture'
'home' => "/" // e.g. '/'
);
// get uri
$uri = '/' . trim( str_replace( WEB_ROOT, '', $_SERVER['REQUEST_URI'] ), '/' );
// test uri
foreach ( $rules as $action => $rule ) {
$pattern = '/^'.str_replace( '/', '\/', $rule ).'$/';
if ( preg_match( $pattern, $uri, $params ) ) {
/* now you know the action and parameters so you can
* include appropriate template file ( or proceed in some other way )
* NOTE: variable $params vill be visible in template ( use print_r( $params ) to see result )
*/
include( INCLUDES_ROOT . $action . '.php' );
// exit to avoid the 404 message
exit();
}
}
// nothing is found so handle 404 error
include( INCLUDES_ROOT . '404.php' );
下一步是檢查收到的參數。
在Aatch和Sally的幫助以及URL路由的一些搜索結果的幫助下,我有了以下方法來實現我的目標,所以我想我會與所有人分享,以防任何人想要使用它...
首先,我需要提一下我正在處理的網站是在根文件夾mysite.com/sub/folder/index.php
2個子目錄中,因此為什么在數組上我從[3]開始
據說我的.htaccess文件如下:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . sub/folder/index.php [QSA,L]
這個,就我而言,獲取在sub/folder/
之后編寫的任何內容,並將頁面直接重定向回index.php,但是,它會屏蔽地址欄中的URL。
它忽略這一點的唯一一次是子目錄實際存在。 所以例如我有一個文件夾/sub/folder/signup/
如果我要在地址欄中鍵入它,因為目錄存在,那么你不會被重定向到index.php文件,而是發送到請求的目錄,就像正常一樣。
現在在我的index.php文件上(請記住我從$ uri開始[3],因為我在子文件夾中!)
$uri = $_SERVER['REQUEST_URI']; // This brings back /sub/folder/foo/bar/test/
$uri = explode("/", $uri); // Separate each one
$var_one = $uri[3]; // foo
$var_two = $uri[4]; // bar
$var_three = $uri[5]; // test
switch ($var_one) {
case '':
case 'home':
include('home.php');
exit();
break;
case 'signout':
case 'logout':
include('signout.php');
exit();
break;
case 'dashboard':
case 'dash':
include('dashboard.php');
exit();
break;
}
// By Username
$data_array = array(':username' => $var_one);
$select_account = $connect->prepare("SELECT * FROM `users` WHERE `username` = :username");
$select_account -> execute($data_array);
$account_amount = $select_account->rowCount();
if ($account_amount > 0) { include('profile.php'); exit(); }
// By Account ID
$data_array = array(':id' => $var_one);
$select_account = $connect->prepare("SELECT * FROM `users` WHERE `id` = :id");
$select_account -> execute($data_array);
$account_amount = $select_account->rowCount();
if ($account_amount > 0) { include('profile.php'); exit(); }
include('page_not_found.php');
開關案例很簡單,如果url是:/ sub / folder / dashboard /則顯示dashboard.php。 如果沒有一個案例匹配,那么我們可能會查看個人資料。 第一個檢查是否可以是用戶名,如果存在,則顯示視圖配置文件頁面。 然后,它檢查它是否可能是該配置文件的唯一ID號並進行相同的檢查。
最后,如果沒有任何結果從它們中恢復,那么我們將顯示404頁面未找到的頁面。
如果它是個人資料頁面,在profile.php文件中,我可以運行$var_two
檢查並查看他們是否已經以該名稱上傳了相冊,例如/sub/folder/joe/holiday/
if yes,然后運行查詢以獲取所有內容,如果沒有,則顯示消息/重定向或其他內容。
然后,如果還有更多,比如說該文件夾中的特定圖片( $var_three
)( $var_two
),例如/sub/folder/joe/holiday/beach/
- 則通過顯示結果的類似查詢運行它。
它可能不是最好的方法,但它非常直接,一切都按照我的喜好工作,所以我不能抱怨。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.