Обрабатывать несколько версий в одном URL - PullRequest
8 голосов
/ 10 августа 2011

я пытаюсь работать с несколькими версиями одного и того же веб-приложения, как это делает Google с некоторыми из своих продуктов, где вы получаете ссылку «Попробуйте новую версию».

Цельэто иметь как «стабильную», так и «бета» версию веб-приложения, позволяющую пользователям опробовать новые функции, не навязывая им (и их ошибкам) ​​их.

Теперь очень простой способДля этого каждая версия должна быть помещена в отдельную подпапку, например www.mywebapp.com/v1 и www.mywebapp.com/v2.

Однако я бы хотел, чтобы это было прозрачно для пользователя иURL веб-приложения остается неизменным (например, www.mywebapp.com/).

Какая версия должна быть загружена, определяется на стороне сервера после входа пользователя в систему (например, активная версия для данного пользователя сохраняется вБД) и может быть позже изменено, когда пользователь нажимает на ссылки «попробуйте новую версию» / «вернуться к старой версии».

На стороне сервера я должен обойтись MySQL, PHP иApache.

У меня естьЯ уже сумел заставить это работать, поместив каждую версию в свою собственную подпапку, затем сохранив информацию о версии в файлах cookie (обновляемых сервером при каждом входе в систему или при обновлении страницы) и используя RewriteRule (s) для «прокси» запросов от базового / не имеющего версии URLправильная подпапка.Если cookie не установлен, папка по умолчанию выбирается резервным RewriteRule.

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

Спасибо!

Ответы [ 7 ]

6 голосов
/ 28 августа 2011

htaccess допускает перезапись на основе содержимого файлов cookie . Поскольку Apache является УДИВИТЕЛЬНЫМ в перенаправлениях, а PHP адекватен, я бы справился с этим таким образом.

В этом примере проверяется, есть ли файл cookie версии. Если есть, он добавляет 'vers =' + все, что было в куки верс, к запросу.

RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_COOKIE} vers=([^;]+) [NC]
RewriteRule ^(.*)$ /$1?vers=%1 [NC,L,QSA]

(этот пример можно найти здесь )

2 голосов
/ 27 августа 2011

Используйте один RewriteRule для перенаправления всех запросов в один route.php файл в корневой папке вашего сайта.

Файл route.php должен выглядеть следующим образом:

$user = authenticateUser();
$version = $user->getPreferredVersion();

$filePath = $_SERVER['DOCUMENT_ROOT'].'v'.$version.$_SERVER['REQUEST_URI'];

if( !file_exists( $filePath ) ) {
    header("Status: 404 Not Found", true, 404 );
    die();
}

$pathDetails = pathinfo( $filePath );

if( $pathDetails['extension'] == 'php' ) {
    require( $filePath );
} else {
    if( $pathDetails['extension'] == 'jpg' ) {
        header( 'Content-Type: image/jpeg' );
    } elseif( $pathDetails['extension'] == 'gif' ) {
        ...
    } elseif (...) {
        ...
    } else {
        // unsupported file type
        header("Status: 404 Not Found", true, 404 );
        die();
    }
    echo file_get_contents( $filePath );
}

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

2 голосов
/ 27 августа 2011

Я думаю, что лучшим способом в PHP было бы просто запросить базу данных, получить нужную версию, а затем include() из подпапки.Таким образом, он прозрачен для пользователя.

Например, если пользователь выбрал новую бета-версию, вы сохраняете его запись в базе данных

UPDATE `versions_table` SET (`version`) VALUES ('1.02b') WHERE `userid` = 5

И затем, когда он получает доступстраница, у вас происходит что-то вроде этого:

//PDO Connection here, skipped for example purposes
$stmt = $pdo->query('SELECT `version` from `versions_table` WHERE `userid` = 5 LIMIT 1'); 
//Of course 5 is only an example, in actual code that would be a variable
//representing the actual user ID.
$row = $stmt->fetch(); //Should be only one row.
include_once($row['version'].'/myApp'.'.php'); //Include 1.02b/myApp.php
0 голосов
/ 03 апреля 2015

Существует облачная платформа, которая делает это автоматически при развертывании. www.cycligent.com
Это просто вопрос установки файла cookie после развертывания двух версий. Гораздо меньше работы, чем некоторые другие показанные ответы.
Полное раскрытие: я работаю на Cycligent.

0 голосов
/ 01 сентября 2011

Это может помочь: сейчас я использую месяц

  1. Сохранить все файлы в базе данных (путь, код, версия = десятичное число (3,1), флаг: стабильный = 3 / lab = 2 / beta = 1 / alpha = 0)

  2. have .htaccess перенаправляет все несуществующие файлы (не перенаправляет изображения, css, js или другие статические файлы без версии) внутренне в loader.pm (для вас loader.ph_ ) не используйте то же расширение, что и другие ваши файлы для разграничения

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^   loader.pm [L,QSA]
    
  3. загрузчик загружает последнюю стабильную версию из базы данных или бета-версию, если стабильной версии не существует.

    SELECT code, version, flag FROM table WHERE path = ? AND flag > 0 ORDER BY flag DESC, version DESC LIMIT 1 Не показывать разрабатываемые альфа-страницы

    вывод 404 ошибка, если нет результатов, и

    когда указана версия как ?v=2.0 файл загрузчика использует другой запрос

    SELECT code, version, flag FROM table WHERE path = ? AND version <= ? ORDER BY flag DESC LIMIT 1

Предположения:

  1. A пользователь хочет получить стабильную или последнюю версию ; так что вам на самом деле не нужно больше 2 файлов на путь; пока, если вы не хотите сохранить старые версии для демонстрации. Если пользователь хочет последний, используйте .. ORDER BY version DESC, flag DESC, ..
  2. Пользователю не важно знать, какая это версия, поэтому вместо того, чтобы устанавливать одну и ту же версию сразу для всего сайта, мы устанавливаем версию каждого файла отдельно ; так что отслеживание разработки легко.

Проблемы:

  • Нет индекса / первичного ключа
    • Вы должны убедиться, что у вас нет повторяющихся записей , это не сломает ваш сайт, но не будет хорошо смотреться;)
    • , если для файла существует такая же бета-версия и стабильная версия, а пользователь выбрал последнюю (бета-версию) ; тогда вы можете случайно доставить ему бета-файл вместо стабильного файла.
  • переменная строки запроса ?v= зарезервирована для выбора версий, но это нормально; Вы можете выбрать ?var=
0 голосов
/ 31 августа 2011

Загрузите свою версию / страницу / страницу в IFRAME, и IFRAME src может быть "webapp.com/v2"..

Так что, какую бы версию пользователь ни выбрал, ваша адресная строка будет читать webapp.com..но вашURL-адрес IFRAME продолжает меняться в зависимости от версии ..

Нет необходимости писать правила перезаписи ..

0 голосов
/ 27 августа 2011

Хотя для создания правил можно использовать механизм маршрутизации и информацию о сеансе, я бы предпочел оставить ваше текущее решение. Все, что вам нужно сделать, внедрив его в PHP, - это передать нагрузку с apache2 (у которого уже есть очень быстрый Rewrite-Engine) в бинарный файл php. Кроме того, вы рискуете помешать вашему приложению работать с версиями из-за несовместимости данных, файлов cookie и других переменных на основе сеанса.

С другой стороны, вы получаете преимущество повторного использования общих объектов, таких как библиотеки, доменные модели, преобразователи данных и т. Д. Но, на мой взгляд, это преимущество не влияет на худшую производительность и риск вмешательства.

Так что в одной фразе я считаю, что ваше текущее решение лучше.

...