2011-08-10 2 views
8

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

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

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

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

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

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

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

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

Спасибо!

+0

Какая часть этого ощущения кажется вам хрупкой? Хранение информации в файле cookie или прокси? –

ответ

2

Я думаю, что лучшим способом в 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

Согласен. Если вы используете структуру MVC или организованы с вашей базой кода, вы можете выполнить эту проверку прямо перед собой и буквально включить() другую базу кода для конкретного пользователя, не знающую, и теперь вам не нужно возиться с вашим .htaccess. – Wrenbjor

2

Используйте один 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 есть некоторые другие вопросы безопасности и технические, которые вы должны заботиться о в этом файле.

+0

Спасибо за ваше предложение, но этот подход создает множество нежелательных побочных эффектов, таких как: 1) относительный включает в файлы PHP, помещенные во вложенные папки, перестает работать, 2) код, который ожидает, что все приложение окажется в корневом винте документа, 3) путем проксирования изображений и других вещей с помощью PHP вы теряете все преимущества производительности и кэширования, которые приходят с Apache (Etags и т. д.). – Sergio

+0

@sergio Это именно некоторые из «других технических проблем», о которых я упомянул, вам следует позаботиться. Ваша третья проблема может быть легко решена путем отправки правильных заголовков кеша, последнего изменения и etag в 'route.php'. Обработайте третью ситуацию, используя 'include (dirname (__ FILE __). '/ ../somefile.php')' метод для включения относительного включает и просто избегает ситуаций в вашей второй проблеме. Причина, по которой я настаиваю на этом методе, заключается в том, что любой другой метод, который полагается только на файлы cookie для ключа версии, является «хрупким», как вы выразились. – nobody

0

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

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

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

6

htaccess allows for rewrites based on the contents of cookies. Поскольку Apache является УДИВИТЕЛЬНЫМ при переадресации, и PHP адекватен, я бы справился с этим именно так.

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

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

(этот пример можно найти here)

+0

Спасибо, но это в основном то, что я делаю уже :) Чтобы быть более точным, я также добавил некоторые операторы, чтобы избежать петли, как: RewriteEngine на RewriteCond% {IS_SUBREQ}^ложь $ RewriteCond% {ENV: REDIRECT_STATUS}^$ RewriteCond% {HTTP_COOKIE} version = ([a-z0-9] +) [NC] RewriteRule^(. *)/V_% 1/$ 1 [NS, L] – Sergio

+0

+1, это хороший подход и не слишком много работы для Apache. – Joshua

0

Загрузите версию-эд страницу/wepages в IFRAME и IFRAME SRC может быть "webapp.com/v2" ..

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

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

0

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

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

  2. имеют .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. Пользователь не заботится о том, какая версия это, следовательно, вместо того, чтобы устанавливать ту же самую версию для всего сайта сразу, мы устанавливаем версию каждого файла отдельно; поэтому отслеживание разработки легко.

Проблемы:

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

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

Смежные вопросы