我要做的是处理同一个网络应用程序的多个版本,有点像谷歌与他们的一些产品,你会得到“尝试新版本”链接。
目标是同时拥有webapp的“稳定”版本和“beta”版本,并让用户试用新功能,而不必强迫它们(以及它们的错误)。
现在,一个非常简单的方法是将每个版本放在自己的子文件夹中,例如www.mywebapp.com/v1和www.mywebapp.com/v2。
但是,我希望这对用户和webapp URL保持透明以保持不变(例如:www.mywebapp.com /)。
必须加载哪个版本在用户登录后确定服务器端(例如:给定用户的活动版本存储在数据库中),并且可能在用户点击“尝试新版本”时更改/“回到旧版本”链接。
在服务器端,我必须使用MySQL,PHP和Apache。
我已经设法让这个工作将每个版本放入其自己的子文件夹中,然后将版本信息存储在cookie中(在每次登录或页面刷新时由服务器更新)并使用RewriteRule来“代理”来自基本/无版本URL到正确的子文件夹。如果未设置cookie,则由后备RewriteRule选择默认文件夹。
这个kludge工作但感觉非常脆弱,它给Apache守护进程带来了额外的负担,所以我在这里询问是否有人知道更好的方法。
谢谢!
答案 0 :(得分:6)
htaccess allows for rewrites based on the contents of cookies。由于Apache在重定向方面非常棒且PHP足够,我会这样处理它。
此示例测试是否存在vers cookie。如果有的话,它会在请求中添加'vers ='+ vers cookie中的任何内容。
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_COOKIE} vers=([^;]+) [NC]
RewriteRule ^(.*)$ /$1?vers=%1 [NC,L,QSA]
(该例子可以找到here)
答案 1 :(得分: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
答案 2 :(得分: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
中做什么的概述,您应该在该文件中处理一些其他安全和技术问题。
答案 3 :(得分:0)
虽然可以使用路由机制和会话信息来制定规则,但我宁愿保留您当前的解决方案。你在PHP中实现它所做的就是将apache2(已经有一个非常快速的Rewrite-Engine)的负载推送到php-binary。此外,由于数据,cookie和其他基于会话的变量不兼容,您的应用程序将面临干扰版本的风险。
另一方面,您可以获得库,域模型,数据映射器等共享对象的可重用性。但在我看来,这种优势并不会降低性能和干扰风险。
所以在一个短语中,我相信你目前的解决方案是最好的。
答案 4 :(得分:0)
在IFRAME中加载版本化页面/ wepages,IFRAME src可能是“webapp.com/v2”..
因此,无论用户选择地址栏的哪个版本都会读取webapp.com ..但您的IFRAME网址会根据版本不断变化..
无需编写重写规则..
答案 5 :(得分:0)
这可能会有所帮助:我现在使用的一个月是
保持数据库中的所有文件(路径,代码,版本=十进制(3,1),标记:stable = 3 / lab = 2 / beta = 1 / alpha = 0 )
将.htaccess 重定向所有非现有文件(不要将图像,css,js或其他静态非版本文件重定向)内部加载到loader.pm(为您加载。 ph_)不要使用与其他文件相同的扩展名进行区分
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ loader.pm [L,QSA]
加载程序会从数据库或测试版加载最新的稳定版。
SELECT code, version, flag FROM table WHERE path = ? AND flag > 0 ORDER BY flag DESC, version DESC LIMIT 1
不要显示正在开发中的Alpha页面
输出404错误,
当指定版本时?v=2.0
加载程序文件使用不同的查询
SELECT code, version, flag FROM table WHERE path = ? AND version <= ? ORDER BY flag DESC LIMIT 1
假设:
.. ORDER BY version DESC, flag DESC, ..
问题:
?v=
保留用于选择版本,但这很好;您可以选择?var=
答案 6 :(得分:0)
有一个云平台可以在部署时自动执行此操作。 www.cycligent.com
只需在部署两个版本后设置cookie即可。比显示的其他一些答案少得多的工作
完全披露:我为Cycligent工作。