Удобные для пользователя URL - переписывание модов и перенаправление php - PullRequest
6 голосов
/ 02 февраля 2012

Пока я сделал это:

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/

Но если вы введете это в качестве URL-адреса, то при переписывании будет читаться [username]/gallery/ как один раздел, что означает $load = [username]/gallery, что даст мне '404'.

Возможно, есть лучшее решение для получения желаемых результатов, но я не слишком хорош с .htaccess и переписыванием. Я хотел бы добавить, что мне тоже нравится это переписывание, так как у меня есть подкаталоги с именами signup и signin, в которых тоже есть подкаталоги, но если я перейду к URL:

www.mysite.com/signup
www.mysite.com/signin

Он игнорирует переписывание и переходит в каталог, вместо того чтобы запускать его через операторы $load, что мне и нужно.

Кроме того, отметим, что при регистрации учетной записи любое имя пользователя, которое совпадает со строками, например dashboard или about и т. Д., Не позволяет им использовать его, это останавливает имена пользователей и операторы $load if / else и их включает в себя путаницу и т. д.

EDIT

Еще одна вещь, которую я забыл отметить, так как они могут вызывать галерею как угодно, нужно выполнить поиск, чтобы увидеть, существует ли эта галерея, например:

www.mysite.com/username/my+first+album

Сначала нужно проверить, существует ли имя пользователя, затем проверить, существует ли альбом, а затем отобразить его, если он есть, или перенаправить 404 / куда, если это не так. Таким образом, в основном оба параметра / запроса будут динамическими. Кроме того, отдельные фотографии в этом альбоме должны работать одинаково, например:

www.mysite.com/username/my+first+album/my+picture

Надеюсь, это имеет смысл ...

Ответы [ 4 ]

3 голосов
/ 02 февраля 2012

Простое решение: 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;
}

Надеюсь, это поможет

2 голосов
/ 02 февраля 2012

То, что вы хотите, это то, что известно как URL-маршрутизатор, для этого необходимо проанализировать URL-адрес и принять решение на основе содержимого.Большинство систем делают это, заставляя вас предоставить шаблон URL и функцию для вызова, если URL совпадает.Обычно функции передаются любые совпадения в шаблоне url.

Например, Django использует регулярные выражения для своей маршрутизации URL-адреса и передает именованные совпадения в качестве аргументов данной функции (или классу).

Если это слишком сложно для ваших нужд, тогда вы можете просто использовать определенные регулярные выражения для анализа URL, ваш случай галереи будет:

$matches = array();
$re = "/\/([\w\d])+\/([\w\d+%])+\/?/";
preg_match($re, $load, $matches);
$username = $matches[0];
$gallery  = $matches[1];

, тогда вы можете использовать $username и $gallery так, как вы хотите.

Примечание

Вышеприведенное предполагает, что оно будет соответствовать, вам необходимо проверить возвращаемое значение preg_match, чтобы убедиться.Кроме того, я не проверял регулярное выражение, оно может быть неправильным, или использовать функции не в этом синтаксисе.

Ссылка

0 голосов
/ 06 мая 2013

Вот простой пример для начала:

.htaccess

RewriteEngine On
RewriteRule ^includes/.*$ index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

Во-первых, вы должны запретить прямой доступ к файлам .php, вы можете поместить их в отдельную папку, например «/ includes», и перенаправить любой вызов этой папки в index.php. Во-вторых, разрешить прямой доступ к файлам (например, изображения или JavaScript). Последнее правило, перенаправьте все остальное в 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' );

Следующим шагом является проверка полученных параметров.

0 голосов
/ 02 февраля 2012

С помощью Aatch и Sally и нескольких результатов поиска по маршрутизации URL я получил следующий метод для достижения того, чего я добивался, поэтому я решил поделиться им со всеми на тот случай, если кто-нибудь захочет его использовать....

Прежде всего я должен упомянуть, что сайт, над которым я работаю, находится в 2 подкаталогах корневой папки mysite.com/sub/folder/index.php, поэтому для массивов я начинаю с [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.Если ни один из случаев не совпадает, мы могли бы посмотреть на профиль.Сначала проверяется, может ли это быть имя пользователя, если оно существует, то отображается страница профиля просмотра.Затем он проверяет, может ли это быть уникальный идентификационный номер для этого профиля, и выполняет ту же проверку.

Наконец, если ни по одному из них не возвращается никаких результатов, то отображается страница 404, а ненайденная страница.

Если это была страница профиля, то в файле profile.php я могу запустить проверку на $var_two и посмотреть, загрузили ли они фотоальбом под этим именем, например, /sub/folder/joe/holiday/, еслида, затем запустите запрос, чтобы получить все это, если нет, отобразить сообщение / перенаправление или что-то еще.

Затем, если их еще больше, скажем конкретное изображение ($var_three) в этой папке ($var_two), например /sub/folder/joe/holiday/beach/ - затем запустите его через аналогичный запрос, показывающий результаты.

Возможно, это не лучший метод, но он довольно простой и все работает, как мне бы тоже хотелосьЯ не могу пожаловаться.

...